Ealier in my blog "Understanding Handlers in JAX-WS", I talked about Handler Framework in JAX-WS and showed some exampl ]]> of using handlers to intercept the messages for additional processing on the server and client. Overall, JAX-WS handlers provide good API to abstract your application logic as a handler and plug it in easily with any service. But the standard handlers have some limitations. LogicalHandler provides access to payload only and does n't provide access to SOAP headers and binary data carried as attachments in the SOAP Message and is more suited for XML/HTTP binding. Though SOAPHandlers provide access to whole SOAP Message, it has performance implications as SOAPMessage is based on DOM and tries to load the whole message in memory. JAX-WS RI reads the message in Streaming fashion and tries to read the information lazily to provide better performance. But each time a SOAPHandler acceses the message, it is converted to DOM based SOAP Message. This can hurt your application performance. Though the SOAPHandlers have the performance limitation due to the above mentioned reasons, The JAX-WS Specification defined a pretty extensible framework, so that other types of protocol handlers can be plugged-in easily.

JAX-WS RI has been fine tuned to perform better and better. JAX-WS RI defines Message abstraction thats hides the actual data representation either the message be constructed from a JAXB object or InputStream of a HttpConnection. The
Message API provides various ways to access the payload and implementations can implement those methods in the best possible way. JAX-WS Runtime chooses the right Message representation when it is constructing a new message. It also provides some commonly used implementations of Message (like JAXBMessage, DOMMessage, SAAJ Message, ProtocolSourceMessage etc). Each kind of Message has particular characteristic and is more useful or suited depending on the situation. Along with it, RI also provides some static factory methods to easily create messages with the Messages API. Using these one can easily access/create messages irrespective of the actual data representation. More about the API can be found in the JAX-WS architecture document.

MessageHandler:
Utilizing the extensible Handler framework provided by JAX-WS Specification and the better Message abstraction in RI, We introduced a new handler called
MessageHandler to extend your Web Service applications. MessageHandler is similar to SOAPHandler, except that implementations of it gets access to MessageHandlerContext (an extension of MessageContext).  Through MessageHandlerContext one can access the Message and process it using the Message API. As I put in the title of the blog, this handler lets you work on Message, which provides efficient ways to access/process the message not just a DOM based message. The programming model of the handlers is same and the Message handlers can be mixed with standard Logical and SOAP handlers. I have added a sample in JAX-WS RI 2.1.3 showing the use of MessageHandler to log messages and here is a snippet from the sample.

 public class LoggingHandler implements MessageHandler<MessageHandlerContext> { public boolean handleMessage(MessageHandlerContext mhc) { Message m = mhc.getMessage().copy(); XMLStreamWriter writer = XMLStreamWriterFactory.create(System.out); try { m.writeTo(writer); } catch (XMLStreamException e) { e.printStackTrace(); return false; } return true; } public boolean handleFault(MessageHandlerContext mhc) { ..... return true; } public void close(MessageContext messageContext) { } public Set getHeaders() { return null; } } 


MessageHandler as light weight Tube:
JAX-WS RI also provides pugglable framework for JAX-WS extensions to process the messages represented as
Packets through Tubes. Packets are just a containers for Message and hold additional Metadata properties relating to the message. Tubes are like filters that work on the packet. Most of the WS-* spec imlementations are done as Tube/Pipe implementation in WSIT. Tubes are very convenient and targeted for developers where in the extensions providing Tube implementation adhere to the Tube API to dotheir part of processing in a bigger chain. But for your Tube to be recognized by the JAX-WS Runtime, you need to plugin your Tube in a TubelineAssembler and make it available to the RI runtime. I talked more about extending JAX-WS through annotations and Tubes here.

Most of the work that can be done in Tubes can be done in a MessageHandler, there by providing light-weight framework for the users to take advantage of the Message abstraction and easy pluggability without change to the already familiar in programming model. You don't have to implement your TubelineAssembler to plug in your logic. Along with the standard properties exposed by the Messagecontext, MessageHandlerContext provides access to SEI Model, WSDL Model and other information to the handler, so that the handler can almost do what a tube can do. Infact you can implement the functionalioty of  MUHeaderTube ( a Tube that does SOAP MustUnderstand Header processing) in a handler efficiently. One downside of implementing it as a handler is that if you implement it as a Tube and extend
TublineAssembler, you can make it available to all applications  and even to the existing applications with out touching the code. But with handlers approach, you need to modify the application a bit to configure handlers.

I see advantanges to both ways of extensions to JAX-WS. Extending JAX-WS as a Tube is mostly for developers enhancing the JAX-WS Runtime to provide some extra functionality. MessageHandlers are easier to develop handlers by the end users and are natural choice if your applications are already using JAX-WS handler framework.

Get the latest Metro 1.1 bits and give it a try.

Technorati:
JAX-WS   Metro   GlassFish