MIDP ProgrammingMIDP Programming
NetworkingNetworking
Chapter ObjectivesChapter Objectives
The CLDC Streams ModelThe CLDC Streams Model
Generic Connection Framework (GCF)Generic Connection Framework (GCF)
Supported ProtocolsSupported Protocols
Creating a ConnectionCreating a Connection
Review of HTTPReview of HTTP
Making an HTTP RequestMaking an HTTP Request
Building a CGI StringBuilding a CGI String
Design TipsDesign Tips
Differences between J2ME and J2SE NetworkingDifferences between J2ME and J2SE Networking
The CLDC Streams ModelThe CLDC Streams Model
In MIDP, as in J2SE, IO streams are the primary mechanism In MIDP, as in J2SE, IO streams are the primary mechanism available to applications to read and write streams of data.available to applications to read and write streams of data.In addition to java.io, the MIDP defines the In addition to java.io, the MIDP defines the javax.microedition.io package in contrast to java.net, which javax.microedition.io package in contrast to java.net, which supports networking and communications for MIDP supports networking and communications for MIDP applications. applications. MIDP applications use the javax.microedition.io types to MIDP applications use the javax.microedition.io types to create and manipulate various kinds of network connections. create and manipulate various kinds of network connections. They then read from these connections and write to them using They then read from these connections and write to them using the types in the MIDP java.io package, which contains a subset the types in the MIDP java.io package, which contains a subset of the classes and interfaces in the J2SE java.io package.of the classes and interfaces in the J2SE java.io package.
Generic Connection FrameworkGeneric Connection Framework
CLDC specifies a CLDC specifies a generic connection generic connection mechanismmechanism
Leaves considerable Leaves considerable flexibility to flexibility to implementationsimplementationsCapable of supporting Capable of supporting many different kinds of many different kinds of connections, from serial connections, from serial ports through wireless ports through wireless networkingnetworking
The fundamental idea:The fundamental idea:Give an URL-like string Give an URL-like string to the frameworkto the frameworkGet back something that Get back something that has input and output has input and output streamsstreams
Connection and its FamilyConnection and its Family
Connection represents some kind of I/O connectionConnection represents some kind of I/O connection
It has subinterfaces that define more specific connection typesIt has subinterfaces that define more specific connection types
Making a ConnectionMaking a Connection
Connector is a Connection factoryConnector is a Connection factory
Pass a URL-style string to open(), get back some Pass a URL-style string to open(), get back some Connection implementationConnection implementation
MIDP says that HTTP must be supportedMIDP says that HTTP must be supportedOther connection types are optionalOther connection types are optional
Note that HTTP does not have to run over TCP/IPNote that HTTP does not have to run over TCP/IP
Connection protocol supportConnection protocol support
Connector.Open("socket://www.corej2me.com.com:55");Connector.Open("socket://www.corej2me.com.com:55");
Connector.Open("http://www.corej2me.com");Connector.Open("http://www.corej2me.com");
Connector.Open("datagram://www.corej2me.com:1000");Connector.Open("datagram://www.corej2me.com:1000");
Connector.Open("file://makefile.txt"); Connector.Open("file://makefile.txt");
Opening a connectionOpening a connection
public static Connection open(String name)public static Connection open(String name)
public static Connection open(String name, int mode)public static Connection open(String name, int mode)
public static Connection open(String name, int mode, public static Connection open(String name, int mode, boolean timeouts) boolean timeouts)
Opening a connectionOpening a connection
public static DataInputStream public static DataInputStream openDataInputStream(String name) openDataInputStream(String name)
public static DataOutputStream public static DataOutputStream openDataOutputStream(String name) openDataOutputStream(String name)
public static InputStream public static InputStream openInputStream(String name) openInputStream(String name)
public static OutputStream public static OutputStream openOutputStream(String name)openOutputStream(String name)
Opening a connectionOpening a connection
//Create connection//Create connectionContentConnection connection = (ContentConnection) ContentConnection connection = (ContentConnection) Connector.open("http://www.corej2me.com" ); Connector.open("http://www.corej2me.com" );
// With the connection, open a stream // With the connection, open a stream InputStream iStrm = connection.openInputStream(); InputStream iStrm = connection.openInputStream();
// ContentConnection includes a length method // ContentConnection includes a length method int length = (int) connection.getLength(); int length = (int) connection.getLength(); if (length != -1) { if (length != -1) {
byte imageData[] = new byte[length]; byte imageData[] = new byte[length]; // Read the data into an array // Read the data into an array iStrm.read(imageData); iStrm.read(imageData);
} }
Opening a connectionOpening a connection
InputStream iStrm = (InputStream) InputStream iStrm = (InputStream) Connector.openInputStream(url); Connector.openInputStream(url); Image img = null; Image img = null;
ByteArrayOutputStream bStrm = new ByteArrayOutputStream bStrm = new ByteArrayOutputStream(); ByteArrayOutputStream(); int ch; int ch; while ((ch = iStrm.read()) != -1) {while ((ch = iStrm.read()) != -1) {
bStrm.write(ch); bStrm.write(ch);
// Place into image array // Place into image array
byte imageData[] = bStrm.toByteArray(); byte imageData[] = bStrm.toByteArray();
// Create the image from the byte array // Create the image from the byte array
img = Image.createImage(imageData, 0, imageData.length); img = Image.createImage(imageData, 0, imageData.length); }}
HTTP support in MIDPHTTP support in MIDP
HTTP support in MIDPHTTP support in MIDP
The original MIDP 1.0 specification only The original MIDP 1.0 specification only required that devices support the HTTP required that devices support the HTTP connection protocolconnection protocol
MIDP 2.0 spec requires support for both HTTP MIDP 2.0 spec requires support for both HTTP and HTTPS. and HTTPS.
The APIs to work with these protocols are The APIs to work with these protocols are HttpConnection and HttpConnections, HttpConnection and HttpConnections, respectively respectively
Request and response protocolsRequest and response protocols
Both HTTP and HTTPS are request/response Both HTTP and HTTPS are request/response protocols. protocols.
A client sends a request and a server sends a A client sends a request and a server sends a response response
Request and response protocolsRequest and response protocols
The client request, sometimes called the The client request, sometimes called the request entity, consists of the following three request entity, consists of the following three sections:sections:
Request method Request method
Header Header
Body Body
Request and response protocolsRequest and response protocols
The request method determines how data will The request method determines how data will be sent to a remote resource. The three be sent to a remote resource. The three methods available are:methods available are:
GET: data is sent as part of the URL. GET: data is sent as part of the URL.
POST: any client data is sent in a separate POST: any client data is sent in a separate stream, distinct from the request to establish a stream, distinct from the request to establish a connection. connection.
HEADER: requests do not send any data to a HEADER: requests do not send any data to a server. Instead, HEADER requests only meta server. Instead, HEADER requests only meta information about the remote resource information about the remote resource
Request and response protocols
Request and response protocols
String url = "http://www.corej2me.com?size=large"; String url = "http://www.corej2me.com?size=large";
HttpConnection http = (HttpConnection) HttpConnection http = (HttpConnection) Connector.open(url);Connector.open(url);
http.setRequestMethod(HttpConnection.GET);http.setRequestMethod(HttpConnection.GET);
Request and response protocolsRequest and response protocols
Header fields let us pass parameters, if you Header fields let us pass parameters, if you will, from the client to the server.will, from the client to the server.
Common fields are If-Modified-Since, Accept, Common fields are If-Modified-Since, Accept, and User Agent. and User Agent.
You set header fields as key-value pairs, using You set header fields as key-value pairs, using the setRequestProperty() method the setRequestProperty() method
Request and response protocols
Request and response protocols
String url = "http://www.corej2me.com\somefile.txt"; String url = "http://www.corej2me.com\somefile.txt"; HttpConnection http = (HttpConnection) HttpConnection http = (HttpConnection) Connector.open(url);Connector.open(url);
http.setRequestMethod(HttpConnection.GET); http.setRequestMethod(HttpConnection.GET);
// Set header field as key-value pair // Set header field as key-value pair http.setRequestProperty("If-Modified-Since", "Mon, 12 http.setRequestProperty("If-Modified-Since", "Mon, 12 Jan 2004 12:00:00 GMT"); Jan 2004 12:00:00 GMT");
Request and response protocols
Request and response protocols
String url = “http://www.corej2me.com”; String url = “http://www.corej2me.com”; String tmp = "test data here"; String tmp = "test data here"; OutputStream ostrm = null; HttpConnection http = OutputStream ostrm = null; HttpConnection http = null; null;
http = (HttpConnection) Connector.open(url);http = (HttpConnection) Connector.open(url);http.setRequestMethod(HttpConnection.POST); http.setRequestMethod(HttpConnection.POST);
//Send client body //Send client body ostrm = http.openOutputStream(); ostrm = http.openOutputStream(); byte bytes[] = tmp.getBytes(); byte bytes[] = tmp.getBytes(); for(int i = 0; i < bytes.length; i++) { for(int i = 0; i < bytes.length; i++) {
os.write(bytes[i]); os.write(bytes[i]); } } os.flush(); os.flush();
Request and response protocolsRequest and response protocols
After the server has received and processed the After the server has received and processed the client request, it must package and send a client request, it must package and send a response. response.
As with the client request, three sections are As with the client request, three sections are associated with the server response: associated with the server response:
Status line Status line
Header Header
Body Body
Request and response protocolsRequest and response protocols
Status line: the server status line informs the Status line: the server status line informs the client of the outcome of its request.client of the outcome of its request.
HTTP classifies the status line codes into the HTTP classifies the status line codes into the following broad categories:following broad categories:
1xx is informational 1xx is informational
2xx is success 2xx is success
3xx is redirection 3xx is redirection
4xx is client error 4xx is client error
5xx is server error 5xx is server error
Request and response protocolsRequest and response protocols
"HTTP/1.1 200 OK" "HTTP/1.1 200 OK"
"HTTP/1.1 400 Bad Request" "HTTP/1.1 400 Bad Request"
"HTTP/1.1 500 Internal Server Error" "HTTP/1.1 500 Internal Server Error"
Request and response protocolsRequest and response protocols
The server can send information through The server can send information through header fields. header fields.
Three of the most common methods for Three of the most common methods for retrieving header information sent from a retrieving header information sent from a server server
String getHeaderField(int n) String getHeaderField(int n)
String getHeaderField(String name) String getHeaderField(String name)
String getHeaderFieldKey(int n) String getHeaderFieldKey(int n)
Request and response protocols
Request and response protocols
•the response in a server header contained the response in a server header contained the content "content-type=text/plain" the content "content-type=text/plain"
Method Method Return value Return value
http.getHeaderField(0) http.getHeaderField(0) "text-plain" "text-plain"
http.getHeaderField("content-type") http.getHeaderField("content-type") "text-plain" "text-plain"
http.getHeaderFieldKey(0) http.getHeaderFieldKey(0) "content-type" "content-type"
The HttpConnection API The HttpConnection API
MethodMethod DescriptionDescription
long getDate() long getDate() Get header field date Get header field date
long getExpiration() long getExpiration() Gets header field expiration Gets header field expiration
String getFile()String getFile() Gets filename from the URL Gets filename from the URL
int getHeaderField(int n) int getHeaderField(int n) Gets header field value looking Gets header field value looking up by index up by index
String getHeaderField(String getHeaderField(
String name) String name)
Gets header field value looking Gets header field value looking up by name up by name
Request and response protocols
Request and response protocols
MethodMethod DescriptionDescription
int getHeaderFieldInt(String int getHeaderFieldInt(String name, int def) name, int def)
Gets named field as an integer Gets named field as an integer
String getHeaderFieldKey(int n) String getHeaderFieldKey(int n) Gets header field key using index Gets header field key using index
String getHost() String getHost() Gets host from the URL Gets host from the URL
String getPort() String getPort() Gets port from the URL Gets port from the URL
void setRequestMethod(void setRequestMethod(
String method) String method)
Sets the request method (GET, Sets the request method (GET, POST or HEAD) POST or HEAD)
String getProtocol() String getProtocol() Gets protocol from the URL Gets protocol from the URL
Request and response protocols
Request and response protocols
MethodMethod DescriptionDescription
String getQuery() String getQuery() Gets the query string Gets the query string
String getRequestMethod() String getRequestMethod() Gets the current setting of the Gets the current setting of the request method request method
int getResponseCode() int getResponseCode() Gets the response code Gets the response code
String getURL() String getURL() Gets the entire URL Gets the entire URL
String getResponseMessage() String getResponseMessage() Gets the response messageGets the response message
Accessing a Java servlet Accessing a Java servlet
private void callServlet() throws IOException { private void callServlet() throws IOException { HttpConnection http = null; HttpConnection http = null; InputStream iStrm = null; InputStream iStrm = null; boolean ret = false; boolean ret = false; // Examples - Data is passed at the end of url for GET // Examples - Data is passed at the end of url for GET String url = "http://www.mycgiserver.com/servlet/corej2me.DateFormatServlet? String url = "http://www.mycgiserver.com/servlet/corej2me.DateFormatServlet? format=MMMM.dd.yyyy+'-'+hh:mm+aa"; format=MMMM.dd.yyyy+'-'+hh:mm+aa"; http = (HttpConnection) Connector.open(url); http = (HttpConnection) Connector.open(url);
// 1) Send request method // 1) Send request method http.setRequestMethod(HttpConnection.GET); http.setRequestMethod(HttpConnection.GET);
// 2) Send header information - none // 2) Send header information - none // 3) Send body/data - data is at the end of URL // 3) Send body/data - data is at the end of URL
iStrm = http.openInputStream(); iStrm = http.openInputStream(); // Three steps are processed in this method call // Three steps are processed in this method call ret = processServerResponse(http, iStrm); ret = processServerResponse(http, iStrm);
} }
Accessing a Java servlet Accessing a Java servlet
private boolean processServerResponse(HttpConnection http, InputStream private boolean processServerResponse(HttpConnection http, InputStream iStrm) { iStrm) {
// 1) Get status Line // 1) Get status Line if (http.getResponseCode() == HttpConnection.HTTP_OK) { if (http.getResponseCode() == HttpConnection.HTTP_OK) {
// 2) Get header information - none // 2) Get header information - none // 3) Get body (data) // 3) Get body (data) int length = (int) http.getLength(); int length = (int) http.getLength(); String str; String str; if (length != -1) { if (length != -1) {
byte servletData[] = new byte[length]; byte servletData[] = new byte[length]; iStrm.read(servletData); iStrm.read(servletData); str = new String(servletData); str = new String(servletData);
} else { // Length not available... } else { // Length not available... ByteArrayOutputStream bStrm = new ByteArrayOutputStream(); ByteArrayOutputStream bStrm = new ByteArrayOutputStream(); int ch; int ch; while ((ch = iStrm.read()) != -1) while ((ch = iStrm.read()) != -1)
bStrm.write(ch); bStrm.write(ch); str = new String(bStrm.toByteArray()); str = new String(bStrm.toByteArray());
}}serverMsg = str; // Save the server message serverMsg = str; // Save the server message return true; return true;
} return false; } return false; } }
Accessing a Java servlet Accessing a Java servlet
public class DateFormatServlet extends HttpServlet { public class DateFormatServlet extends HttpServlet { public void init(ServletConfig config) throws ServletException { public void init(ServletConfig config) throws ServletException { super.init(config); super.init(config); } } public void doGet(HttpServletRequest request, HttpServletResponse response) throws public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletException, IOException {
doPost(request, response); doPost(request, response); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletException, IOException {
String format = request.getParameter("format"); String format = request.getParameter("format"); SimpleDateFormat simpleDate = new SimpleDateFormat(format); Date dt = new Date(); SimpleDateFormat simpleDate = new SimpleDateFormat(format); Date dt = new Date(); PrintWriter out = response.getWriter(); PrintWriter out = response.getWriter(); response.setContentType("text/html"); response.setContentType("text/html"); out.println(simpleDate.format(dt)); out.println(simpleDate.format(dt)); out.close(); out.close();
}}public String getServletInfo() { public String getServletInfo() {
return "DateFormatServlet"; return "DateFormatServlet"; } }
} }
Review of HTTPReview of HTTP
General data transfer protocolGeneral data transfer protocol
Client sends requestClient sends request
Server sends responseServer sends response
Requests and responses have two parts:Requests and responses have two parts:Headers (metadata)Headers (metadata)
ContentContent
Requests often have no contentRequests often have no content
Requests can contain parametersRequests can contain parametersThink of the values from an HTML formThink of the values from an HTML form
HTTP Connections HTTP Connections
The MIDP profile supports The MIDP profile supports HTTP version 1.1 HTTP version 1.1 connections via the connections via the HttpConnection interface. HttpConnection interface. The GET, POST, and HEAD The GET, POST, and HEAD schemes of HTTP are schemes of HTTP are supported.supported.
ParametersParameters
For GET, parameters are encoded and tacked For GET, parameters are encoded and tacked on to the end of the URLon to the end of the URL
http://www.jonathanknudsen.com/simple?http://www.jonathanknudsen.com/simple?user=jonathan&zip=08540user=jonathan&zip=08540
With POST, parameters are sent as the content With POST, parameters are sent as the content part of the request part of the request
The same encoding is usedThe same encoding is used
Performing a GETPerforming a GET
It’s amazingly simple:It’s amazingly simple:String url = "http://www.jonathanknudsen.com/simple";String url = "http://www.jonathanknudsen.com/simple";
InputConnection ic = (InputConnection)Connector.open(url);InputConnection ic = (InputConnection)Connector.open(url);
InputStream in = ic.openInputStream();InputStream in = ic.openInputStream();
// Now read stuff from the InputStream.// Now read stuff from the InputStream.
// Remember to clean up.// Remember to clean up.
ic.close();ic.close();
Remember to catch IOExceptionsRemember to catch IOExceptions
GET ExampleGET Example
POSTing a FormPOSTing a Form
It’s a little more complicated than GETIt’s a little more complicated than GETYou need HttpConnection methodsYou need HttpConnection methodsChange the request method with setRequestMethod()Change the request method with setRequestMethod()Tell the server the length of your parameters Tell the server the length of your parameters (“Content-Length”) with setRequestProperty()(“Content-Length”) with setRequestProperty()Send the parameters in the output stream of the Send the parameters in the output stream of the connection of the connectionconnection of the connectionSee See Jargoneer.javaJargoneer.java
POST ExamplePOST Example
Invoking a CGI ScriptInvoking a CGI Script
Both the GET and POST methods can be used to Both the GET and POST methods can be used to invoke a CGI (Common Gateway Interface) scripts invoke a CGI (Common Gateway Interface) scripts and supply input data and supply input data
Design TipsDesign Tips
Use GET instead of POSTUse GET instead of POST
Don’t hard-code URLsDon’t hard-code URLs
Network access should go in its own threadNetwork access should go in its own thread
Handle exceptions gracefully Handle exceptions gracefully
Clean upClean up
Differences between J2ME and J2SE NetworkingDifferences between J2ME and J2SE Networking
There's no MIDP java.net package as there is in J2SE.There's no MIDP java.net package as there is in J2SE.MIDP java.io package only supports a subset of the familiar MIDP java.io package only supports a subset of the familiar J2SE byte- and character-oriented input and output stream J2SE byte- and character-oriented input and output stream classes.classes.The following application-level facilities are missing from the The following application-level facilities are missing from the MIDP:MIDP:
RMI RMI requires too much processing for mobile devices to support at this requires too much processing for mobile devices to support at this time.time.Jini Jini requires RMI; therefore, it's not present.requires RMI; therefore, it's not present.JavaSpaces JavaSpaces doesn't exist in J2ME.doesn't exist in J2ME.CORBA CORBA middleware doesn't exist in J2ME.middleware doesn't exist in J2ME.