subbu.org

Transport Headers in Java

without comments

Looking at the various J2SE and J2EE APIs, I find quite a number of of inconsistencies across the APIs for representing transport-level headers.

Let me start with J2SE. J2SE uses the term "request property" for transport headers. java.net.HttpURLConnection has the following methods for dealing with headers.

public void addRequestProperty(String name, String value);
public String getRequestProperty(String name);
public void setRequestProperty(String name, String value);

public Map> getHeaderFields();
// Other variants of this method  

If you use this class to send a HTTP POST request and read the response, you would send "request properties" and receive "header fields", where as HTTP calls these "request headers" and "response headers". Anyone experienced with the getHeaderFields() method would also point out that J2SE represents the status line of the response (such as "HTTP/1.x 200 OK") as a header field. This is technically incorrect, since this is not a response header. J2SE parses this line into a header with null value.

Moving on, Java Mail API has its own style for representing headers. This API has a javax.mail.internet.InternetHeaders which represents headers as a collection of javax.mail.Header objects. This looks fine as long as you don’t use send MIME messages over HTTP. To write/read MIME messages to/from HTTP, you have to convert javax.mail.Header objects into request properties, and then again convert "header fields" into MIME headers.

Then there is SAAJ in J2EE, which specifies a totally different style for transport-level headers. Since the purpose of SAAJ is to represent SOAP messages with attachments as MIME messages, one would expect some amount of reuse and consistency. It turns out that this is not the case. SAAJ specifies a javax.xml.soap.MimeHeaders object for MIME headers. This is a collection of javax.xml.soap.MimeHeader objects. Both javax.mail.Header and javax.xml.soap.MimeHeader have the same set of methods, and represent the header as a name/value pair. But the API designers missed the reuse aspect.

I bet the API designers have some valid arguments for these
inconsistencies. But these APIs make application code ugly and inefficient. For instance, consider the case of reading a javax.xml.soap.SOAPMessage from a java.net.HttpURLConnection. Here is one possible way of
implementing this.

Map> headerFields = connection.getHeaderFields();
MimeHeaders mimeHeaders = new MimeHeaders();
for(String name : headerFields.keySet()) {
for(String value : headerFields.get(name)) {
if(name != null && value != null) {
mimeHeaders.addHeader(name, value);
}
}
}
InputStream is = connection.getInputStream();
SOAPMessage soapMessage = MessageFactory.newInstance().createMessage(mimeHeaders, is);

Due to the inconsistencies, you are forced to copy the headers from the connection to the message. It would have been much simpler if SAAJ and other APIs used the same style as J2SE.

  • Digg
  • del.icio.us
  • Google

April 21st, 2005 at 12:34 pm

Tagged with

RSS feed

Comments »

No comments yet.

Name (required)
E-mail (required - never shown publicly)
URI
Your Comment (smaller size | larger size)
You may use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> in your comment.

Trackback responses to this post