6.1 The Decorator ApproachOne way to enhance the MIDP standard HTTP I/O is to provide a decorator class (CustomConnection) that wraps around the default MIDP HttpConnection implementation but overrides some methods to handle custom headers. Since the decorator class also implements the HttpConnection interface, it is transparent to existing MIDP applications that use HttpConnection. 6.1.1 The CustomConnector Factory ClassIn order to instantiate the CustomConnection decorator, we need to write a new connection factory class CustomConnector (Listing 6.1). The custom request headers are set in the CustomConnector.open() method when a new connection is established. Listing 6.1. The CustomConnector factory class// In CustomConnector class public static HttpConnection open(String url) throws IOException { HttpConnection c = (HttpConnection) Connector.open(url); setRequestHeaders(c); c.setRequestProperty("User-Agent", "Profile/MIDP-1.0, Configuration/CLDC-1.0"); c.setRequestProperty("Content-Language", "en-US"); CustomConnection sc = new CustomConnection(c); return sc; } private static void setRequestHeaders(HttpConnection c) { // Generate custom header for the request and // set the headers to the connection object. } private static void getResponseHeaders(HttpConnection c) { // Retrieve headers from the response stream // and process it. } 6.1.2 The CustomConnection ClassNow, let's have a closer look at class CustomConnection (Listing 6.2). It overrides only two methods, openInputStream() and openDataInputStream(), which process custom headers when the response data is retrieved. Listing 6.2. The CustomConnection classclass CustomConnection implements HttpConnection { private HttpConnection c; public CustomConnection(HttpConnection c) { this.c = c; } public String getURL() { return c.getURL(); } public String getProtocol() { return c.getProtocol(); } public String getHost() { return c.getHost(); } // More HttpConnection methods public InputStream openInputStream() throws IOException { CustomConnector.getResponseHeaders(c); return c.openInputStream(); } public DataInputStream openDataInputStream() throws IOException { CustomConnector.getResponseHeaders(c); return c.openDataInputStream(); } } 6.1.3 Decorator Pros and ConsThe decorator solution is elegant and transparent to existing applications. However, it has several weaknesses. It is not scalable. For each task involving custom HTTP headers, we need to write a pair of decorator and connector factory classes. The decorator solution does not work correctly with HTTP tasks that require automatic header resubmission from the client side. An example of such tasks is the HTTP Digest Authentication (see Section 6.5).
For general-purpose HTTP headers handling, we need a new framework that is more powerful than simple decorators. |