May 15, 2009, 6:26 a.m.
posted by barateon
15.3 The HttpConnection InterfaceThe interface javax.microedition.io.HttpConnection defines the MIDP HTTP API. This interface is unchanged from MIDP 1.0. The interface extends the interface javax.microedition.io.ContentConnection to provide additional fields and methods that parse URLs, set request headers, and parse response headers. (Refer to the documentation of interface ContentConnection on page 69.) 1 States of an HTTP ConnectionAn HTTP connection exists in one of three states: setup, connected, or closed. A connection is in the setup state after it is opened and before the request has been made to the server. The application sets information needed to connect to the server, such as the request parameters and headers. (They must be set before the request is sent.) The methods setRequestMethod and setRequestProperty set the values; the getRequestMethod and the getRequestProperty methods retrieve them. A connection enters the connected state when the request is sent. This occurs when the application calls a method that requires a response value or closes the output stream, if any. These methods indicate the end of the request. A connection enters the closed state when the connection is closed. Although none of the methods of the HttpConnection object can be used when the connection is closed, its InputStream or OutputStream might still contain data. The streams may be used until they are closed. The following code fragment shows an input stream being used after its connection has been closed:
// Open the connection and input stream
HttpConnection c = (HttpConnection)Connector.open(...);
InputStream is = c.openInputStream();
...
// Close the connection. Can't call HttpConnection methods
// after this, but InputStream methods are still available.
c.close();
while ((int ch = is.read()) != -1) {
...
}
// Close the input stream. Can't call InputStream methods after this
is.close();
2 Security of HTTPAccess to the HTTP connection may be restricted by device policy. Trusted MIDlet suites request access with the javax.microedition.io.Connector.http permission, as described in Section 18.3, "Trusted MIDlet Suite Security Model." The device may try to authorize the MIDlet when the MIDlet calls the Connector.open method with a valid URL. If the authorization fails and the MIDlet is not allowed to use the HTTP API, the Connector.open method throws a java.lang.SecurityException. 15.3.3 Establishing a ConnectionApplications open HTTP connections with the CLDC method javax.microedition.io.Connector.open. (Refer to Section 5.3.2, "The Generic Connection Framework.") The method takes a single String URL parameter in the URI (Uniform Resource Identifier) form as defined by the IETF standard RFC2396 Uniform Resource Identifiers [reference 5]. Opening the connection might block the application thread until the server responds. The application should make sure this code runs in a thread separate from the user interfaces callbacks. The following code fragment opens a connection to the home page of the Java™ Programming Language.
HttpConnection c =
(HttpConnection)Connector.open("http://java.sun.com/");
The resulting connection supports the HTTP 1.1 protocol as defined by RFC2616 [reference 9]. The connection is in the setup state. 15.3.4 Parsing URLsWhile an HTTP connection is open, a MIDlet can parse the components of its URL. The URL-parsing methods are:
The following example uses these accessor methods:
// Open the Connection
String HTTP_URL =
"http://localhost:8080/myApp?first=joe?last=cool";
HttpConnection c = (HttpConnection)Connector.open(HTTP_URL);
// Can now use the URL parsing methods
System.out.println("Protocol: " + c.getProtocol());
System.out.println("Host: " + c.getHost());
System.out.println("Port: " + c.getPort());
System.out.println("File: " + c.getFile());
System.out.println("Query: " + c.getQuery());
System.out.println("Reference: " + c.getRef());
When run, the code prints the following lines: Protocol: http Host: localhost Port: 8080 File: /myApp Query: first=joe?last=cool Reference: null 15.3.5 HTTP Request HeadersThe HTTP protocol provides a rich set of request headers that allow a MIDlet to negotiate the form, format, language, session, and other attributes of the content posted or retrieved. The protocol also provides response headers. It is the responsibility of a MIDlet to choose the request headers to use and to process response headers. When a MIDlet communicates with a known service, it needs to handle only a subset of headers. It can omit and ignore the others. The following methods set the request method and headers. A MIDlet can use them when its connection is in the setup state.
Of the request properties that can be set, the User-Agent, Accept-Language, and Authorization properties merit special discussion. The User-Agent HeaderIn the HTTP specification, a request header called User-Agent identifies the current client to the server. As specified by RFC2616 [reference 9], the field contains features separated by blanks. A feature consists of a name and optional version number. The MIDP Specification version 2.0 does not require that a MIDlet set the User-Agent field. A MIDlet can use it, though, to identify its device to the server. The following code fragment sets the User-Agent field to the version numbers of the CLDC and MIDP implementations running on the device:
StringBuffer sb = new StringBuffer(60);
// Add the Configuration to the string that is the User-Agent value
sb.append("Configuration/");
sb.append(System.getProperty("microedition.configuration"));
// For each profile, append it to the User-Agent string
String prof = System.getProperty("microedition.profiles")
int i = 0, j = 0;
while ((j = prof.indexOf(' ', i)) != -1) {
sb.append(" Profile/");
sb.append(prof.substring(i, j));
i = j + 1;
}
sb.append(" Profile/");
sb.append(prof.substring(i));
// Set the User-Agent field
c.setRequestProperty("User-Agent", sb.toString());
The Accept-Language HeaderThe Accept-Language header requests a document in a particular language. The header can be set with the value of the system property microedition.locale, which identifies the current locale of the device. (See Section 20.2, "System Properties" for more information.) The following code fragment shows the Accept-Language header being set with the microedition.locale value.
String locale = System.getProperty("microedition.locale");
if (locale != null) {
c.setRequestProperty("Accept-Language", locale);
}
The Authorization HeaderThe HTTP protocol provides several mechanisms that a client and server can use to to implement a challenge-response authentication scheme [reference 10]. One scheme, the basic authentication scheme, has the client send a userId-password pair to the server in the Authorization header. The server uses the authentication data to give the client access to a protected resource, or realm. The server only handles a request to access a realm if it can validate the user identifier and password the client supplied. To use a basic authentication scheme, the Authorization header must contain the string Basic, a space, and then the base64 [reference 3] encoding of a string composed of the user-ID, a colon, and password. For example, if a client needed to access a protected resource that requires a user-ID of book and a password of bkpasswd, the MIDlet would send the following header field: Authorization: Basic Ym9vazpia3Bhc3N3ZA== where the 'Ym9vazpia3Bhc3N3ZA==' string is the base64 encoding of book:bkpasswd. The Authorization header can also be used for other authentication schemes. See RFC2617 [reference 10] for more information. 15.3.6 Using an HTTP ConnectionAfter a MIDlet sets the appropriate headers it can use the connection. The connection's action depends on the value (GET, POST, or HEAD) set with the setRequestMethod method. Using the GET Request MethodThe GET method retrieves information. The following code fragment shows the common situation in which an application opens an HttpConnection, checks the connection's status (which sends the request), and then reads data from the connection using the InputStream of the connection.
HttpConnection c;
InputStream is;
try {
// Open the connection
c = (HttpConnection)Connector.open("http://java.sun.com/");
// Get the HTTP response code, which sends the request
// Only HTTP_OK (200) means that the content is returned
int status = c.getResponseCode();
if (status != HttpConnection.HTTP_OK) {
throw new IOException("Response code not OK");
} else {
// Handle other recoverable responses like redirects
}
// Open the InputStream and read until end of file
// (-1) is returned
is = c.openInputStream();
int ch;
while ((ch = is.read()) != -1) {
// Process the byte from the stream;
}
} finally {
// Close the connection and the InputStream
if (is != null) {
is.close();
}
if (c != null) {
c.close();
}
}
Using the POST Request MethodPOST requests can send more data and parameters to a server than GET requests. When using a POST request, a MIDlet can provide parameters as part of the URL (as with a GET request). In addition, the MIDlet can write a stream of bytes over the network in order to supply the server with additional data. The example below shows a POST request. The example opens the connection and sets up the request headers. It then opens an OutputStream and writes additional data or commands into the stream before sending the request to the server.
HttpConnection c;
InputStream is;
OutputStream os;
try {
// Open the connection
c = (HttpConnection)Connector.open(url);
// Make this a POST request
c.setRequestMethod(HttpConnection.POST);
// Get the output stream and write a command
os = c.openOutputStream();
os.write("LIST games\n".getBytes());
os.flush();
// Get the status code, causing the request to be sent
// Only HTTP_OK (200) means the request was accepted
status = c.getResponseCode();
if (status != HttpConnection.HTTP_OK)
throw new IOException("Response status not OK");
}
Using the HEAD Request MethodThe HEAD request method is like the GET request method except the server does not return a message body in the response. All of the information in the HTTP headers is identical. An application usually uses a HEAD request to test whether a URL is valid or modified. 15.3.7 HTTP Response HeadersAn HTTP server responds to a request by sending one or more headers that describe the content of the response, such as the type, encoding, length, and so on. The requested content is sent next. The HttpConnection object parses and stores the response headers until the connection is closed. The MIDlet must get any headers it needs from the connection before closing it. It uses the information to interpret the returned content. The methods that fetch and convert the commonly used fields to the appropriate primitive type are:
Additional response headers are also available. Methods provide access to the fields by index or name as a String, an integer, or a time in milliseconds. If a header may appear more than once (as Set-Cookie can) a MIDlet must iterate through the response headers using getHeaderFieldKey to identify which headers have multiples. The methods to iterate through and get the values of the fields are:
All of the header-related methods catch any exceptions that occur in making the connection and return default values. To avoid missing a network error or incorrectly acting upon it, a MIDlet should call getResponseCode, check the return value, and be prepared to handle any exceptions before getting the response headers. 8 Closing an HTTP ConnectionAn application closes an HTTP connection with the javax.microedition.io.Connector.close method. The following example shows a connection being closed.
try {
c.close();
} catch (IOException e) {
...
}
|
- Comment