Wednesday 6 April 2011

J2ME Network programming


ntroducing CLDC and MIDP
The Connected Limited Device Configuration (CLDC) is a standard, portable, minimum-footprint configuration for small, resource-constrained mobile devices, and is the foundation for the MID profile. A configuration defines the minimum set of class libraries available for a range of devices, and a profile defines the set of APIs available for a particular family of devices. The MID profile provides a standard platform for small, resource-constrained, wireless-connected mobile information devices. So, you can think of the CLDC as a horizontal set of classes, and the MID Profile (MIDP), which is built on top of CLDC, as a vertical set of classes. This means that MIDP has access to all the classes provided by the CLDC.
The javax.microedition.io CLDC package contains classes for input/output (I/O), including networking I/O. To these CLDC classes, the MIDP adds the HttpConnection interface for HTTP protocol access. This interface defines the necessary methods and constants for an HTTP connection.
The CLDC Connection Framework
The java.io.* and java.net.* packages of the J2SE are not suitable for handheld devices with a small memory footprint.
  • Device manufacturers who work with circuit-switched networks require stream-based connections such as the Transport Control Protocol (TCP), which is a connection-oriented protocol.
  • Device manufacturers working with packet-switched networks require datagram-based connections such as the User Datagram Protocol (UDP), which is connectionless protocol.
  • Other hand-held devices have specific mechanisms for communications.
All this variation makes the design of networking facilities for CLDC quite a challenge.
This challenge has led to the design of a set of related abstractions that can be used at the programming level instead of using different abstractions for different forms of communications. For example, the J2SE java.net package provides a set of related abstractions in the form of over 20 networking classes including SocketServerSocket, and DatagramSocket.
Generic Connections
In the CLDC Generic Connection framework, all connections are created using the open static method from the Connector class. If successful, this method returns an object that implements one of the generic connection interfaces. Figure 1 shows how these interfaces form an is-ahierarchy. The Connection interface is the base interface such that StreamConnectionNotifier is a Connection and InputConnection is aConnection too.
  • The Connection interface is the most basic connection type. It can only be opened and closed.
  • The InputConnection interface represents a device from which data can be read. Its openInputStream method returns an input stream for the connection.
  • The OuputConnection interface represents a device to which data can be written. Its openOutputStream method returns an output stream for the connection.
  • The StreamConnection interface combines the input and output connections.
  • The ContentConnection is a subinterface of StreamConnection. It provides access to some of the basic meta data information provided by HTTP connections.
  • The StreamConnectionNotified waits for a connection to be established. It returns a StreamConnection on which a communication link has ben established.
  • The DatagramConnection represents a datagram endpoint.
The open method of the Connector class has the following syntax, where the String parameter has the format"protocol:address;parameters".
Connector.open(String);
For a full list of methods, see the CLDC/MIDP specifications.
Here are a few examples:
HTTP Connection
Connector.open("http://java.sun.com/developer");
Datagram Connection
Connector.open("datagram://address:port#");
Communicate with a Port
Connector.open("comm:0;baudrate=9600');
Open Files
Connector.open("file:/myFile.txt");
Benefit
The goal of the above syntax is to isolate the differences between the setup of one protocol and another into a simple string that characterizes the type of connection. Most of the application's code remains the same regardless of the protocol you use. You see this benefit in action in the examples for this article.
.
...
.Important Note: The connection examples above are for illustration only. CLDC itself does not provide any protocol implementations, because no implementations should be provided at the configurations level (CLDC is a configuration). Also, a J2ME profile such as MIDP does not have to provide implementations for all of these protocols. For example, MIDP provides an implementation for the HTTP protocol, but it does not provide implementations for socket or datagram connections..
.
.

MIDP Connectivity
HTTP can either be implemented using IP protocols (such as TCP/IP) or non-IP protocols (such as WAP and i-mode), because the MIDP extends CLDC connectivity to provide support for a subset of the HTTP protocol.
.
...
.Important Note: All MIDP implementations must provide support for the HTTP protocol. It is up to the implementors to support datagram connections. It is recommended, however, to use only protocols supported by MIDP (e.g. HTTP) because this will allow the application to be portable across all mobile information devices..
.
.

The idea of having MIDP support the HTTP protocol is very clever. For network programming, you can revert to the HTTP programming model, and your applications will run on any MIDP device, whether it is a GSM phone with a WAP stack, a phone with i-mode, a Palm VII wireless, or a hand-held device with Bluetooth.
The HttpConnection Interface
The HttpConnection interface is part of the package javax.microedition.io. This interface defines the necessary methods and constants for an HTTP connection. It has the following signature:
public interface HttpConnection
extends javax.microedition.io.ContentConnection
The HTTP protocol is a request-response application protocol in which the parameters of the request must be set before the request is sent. The connection could be in one of the three following states:
  • Setup: No connection yet
  • Connected: Connection has been made, the request has been sent, and some response is expected
  • Closed: Connection is closed
In the setup state the following methods can be invoked:
  • setRequestMethod
  • setRequestProperty
For example, suppose you have this connection:
HttpConnection c = (HttpConnection)
Connector.open("http://java.sun.com/developer");
Then, you can set the request method to be of type POST as follows:
c.setRequestMethod(HttpConnection.POST);
And likewise, you can set some of the HTTP properties. For example, you can set the User-Agent as follows:
c.setRequestProperty("User-Agent",
"Profile/MIDP-1.0 Configuration/CLDC-1.0");
If there is a method that requires data to be sent or received from the server, there is a state transition from Setup to Connected. Examples of methods that cause the transition include:
openInputStream
openOutputStream   i
openDataInputStream
openDataOutputStream
getLength
getType
getDate
getExpiration
And while the connection is open, some of these methods that may be invoked:
getURL
getProtocol
getHost
getPort
Examples using HttpConnection
These examples demonstrate how to write network applications to retrieve information across the network using the HTTP protocol.
Example1: Fetch a page using a StreamConnection
In this example, you read the contents of a file referenced by a URL using StreamConnection. Here, there is no HTTP-specific behavior needed. As you can see from Listing 1, the Connector.open opens a connection to the URL and returns a StreamConnection object. Then anInputStream is opened through which to read the contents of the file, character by character, until the end of the file (-1). In the event an exception is thrown, both the stream and connection are closed.
Listing 1: FirstExample.java
import java.io.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

/**
 * An example MIDlet to fetch a page 
 * using a StreamConnection.
 */
public class FirstExample extends MIDlet {
  private Display display;
  String url = "http://www.javacourses.com/hello.txt";
  public FirstExample() {
    display = Display.getDisplay(this);
  }
  /**
   * This method is invoked when the MIDlet is activated
   */
  public void startApp() {
    try {
      getViaStreamConnection(url);
    } catch (IOException e) {
      //Handle Exceptions any other way you like.
      System.out.println("IOException " + e);
      e.printStackTrace();
    }
  }
  /**
   * Pause, discontinue....
   */
  public void pauseApp() { }
    /**
     * Destroy cleans up everything.  
     */
  public void destroyApp(boolean unconditional) { }
    /**
     * read url via stream connection
     */
  void getViaStreamConnection(String url) 
  throws IOException {
    StreamConnection c = null;
    InputStream s = null;
    StringBuffer b = new StringBuffer();
    TextBox t = null;
    try {
      c = (StreamConnection)Connector.open(url);
      s = c.openInputStream();
      int ch;
      while((ch = s.read()) != -1) {
        b.append((char) ch);
      }
      System.out.println(b.toString());
      t = new TextBox("hello....", 
        b.toString(), 1024, 0);
    } finally {
      if(s != null) {
        s.close();
      }
      if(c != null) {
        c.close();
      }
    }
    // display the contents of the file in a text box.
    display.setCurrent(t);
  }
}










Example 2: Fetch a Page Using an HttpConnection
Similar to the last example, this example fetches a page, but instead uses an HttpConnection. The Connector.open method opens a URL and returns an HttpConnection object. When you open the input stream, the connection is opened and the HTTP headers read. Thec.getLength gets the content length, and if you want to get the content type, use the c.getType method. The source code is in Listing 2.
Listing 2: SecondExample.java
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;

/**
 * An example MIDlet to fetch a page 
   using an HttpConnection.
*/

public class SecondExample extends MIDlet {
  private Display display;
  private String url = 
 "http://www.javacourses.com/hello.txt";
    public SecondExample() {
      display = Display.getDisplay(this);
    }
  /**
   * startApp is invoked when 
   * the MIDlet is activated.
  */
  public void startApp() {
    //The specified URL is overridden 
    //in the descriptor
    try {
      downloadPage(url);
    } catch(IOException e) {
      // handle the exception
    }
  }
  private void downloadPage(String url) 
 throws IOException {
    StringBuffer b = new StringBuffer();
    InputStream is = null;
    HttpConnection c = null;
    TextBox t = null;
    try {
      long len = 0 ;
      int ch = 0;
      c = (HttpConnection)Connector.open(url);
      is = c.openInputStream();
      len =c.getLength();
      if( len != -1) {
 // Read exactly Content-Length bytes
    for(int i =0 ; i < len ; i++ )
   if((ch = is.read()) != -1) {
     b.append((char) ch);
          }
        }
      } else {
        //Read until the connection is closed.
 while ((ch = is.read()) != -1) {
          len = is.available() ;
   b.append((char)ch);
        }
      }
      t = new TextBox("hello again....", 
        b.toString(), 1024, 0);
    } finally {
      is.close();
      c.close();
    }
    display.setCurrent(t);
  }
  /**
   * Pause, discontinue....
  */
  public void pauseApp() { }
  /**
   * Destroy must cleanup everything.
  */
  public void destroyApp(boolean unconditional) { }
}


A CGI script is invoked from the HTTP server side, and the results are captured and displayed on the hand-held device screen.
Example 3: Invoking a CGI Script
This example uses an HttpConnection object returned by the call to the Connector.open method. The call to setRequestMethod is set to GETand some request headers are also set. In this example, a script is invoked that accepts a Student ID# from a form. The script searches a file and returns the final grade for the student corresponding to the ID#.
.
...
.Note: In this example, the URL has the form http://www.javacourses.com/cgi-bin/getgrade.cgi?idnum=182016. Alternatively, you can do this with the commented-out code shown below in bold. The bolded code segment can also be used if you want to POST something to the server..
.
.

This example's source code is shown in Listing 3.
Listing 3: ThirdExample.java
import java.io.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

/**
 * An example MIDlet to invoke a CGI script.
*/

public class ThirdExample extends MIDlet {
  private Display display;
  String url = 
    "http://www.javacourses.com/cgi-bin/getgrade.cgi?idnum=182016";

  public ThirdExample() {
    display = Display.getDisplay(this);
  }
  /**
   * Initialization. Invoked the MIDlet is activated.
   */
  public void startApp() {
    try {
      getGrade(url);
    } catch (IOException e) {
      System.out.println("IOException " + e);
      e.printStackTrace();
    }
  }
  /**
   * Pause, discontinue ....
  */
  public void pauseApp() { }
  /**
   * Destroy must cleanup everything.
  */
  public void destroyApp(boolean unconditional) { }
  /**
   * Retrieve a grade....
  */
  void getGrade(String url) throws IOException {
    HttpConnection c = null;
    InputStream is = null;
    OutputStream os = null;
    StringBuffer b = new StringBuffer();
    TextBox t = null;
    
    try {
      c = (HttpConnection)Connector.open(url);
      c.setRequestMethod(HttpConnection.GET);
      c.setRequestProperty("IF-Modified-Since", 
  "10 Nov 2000 17:29:12 GMT");
      c.setRequestProperty("User-Agent",
  "Profile/MIDP-1.0 Confirguration/CLDC-1.0");
      c.setRequestProperty("Content-Language", 
  "en-CA");
      os = c.openOutputStream();
      
      /**
        String str = "?idnum=182016";
        byte postmsg[] = str.getBytes();
        for(int i=0;i<postmsg.length;i++) {
          os.writeByte(postmsg[i]);
        }
        os.flush();
      */
      
      is = c.openDataInputStream();
      int ch;
      while ((ch = is.read()) != -1) {
            b.append((char) ch);
            System.out.println((char)ch);
      }
      t = new TextBox("Final Grades", 
  b.toString(), 1024, 0);
    } finally {
      if(is!= null) {
        is.close();
      }
      if(os != null) {
        os.close();
      }
      if(c != null) {
        c.close();
      }
   }
   display.setCurrent(t);
  } 
}

No comments:

Post a Comment