Thursday, September 25, 2008

Using JAX-WS Handlers

The JAX-WS provides a good facility to do pre/post processing on SOAP messages using SOAPHandler. The handlers are useful for auditing, logging and potentialy some more functionality. In this entry I will try to explain a typical usage of handlers for logging the SOAP messages. Every handler class needs to implement javax.xml.ws.handler.soap.SOAPHandler interface as shown below-
public class LoggingHandler implements SOAPHandler<SOAPMessageContext> {

    @Override
    public Set<QName> getHeaders() {
        return null;
    }

    @Override
    public void close(MessageContext context) {
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        logToSystemOut(context);
        return true;
    }

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        logToSystemOut(context);
        return true;
    }

    private void logToSystemOut(SOAPMessageContext smc) {
        Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        if (outboundProperty.booleanValue()) {
            System.out.println("\nOutgoing message:");
        } else {
            System.out.println("\nIncoming message:");
        }

        SOAPMessage message = smc.getMessage();
        try {
            message.writeTo(System.out);
        } catch (Exception e) {
            System.out.println("Exception in handler: " + e);
        }
    }

}
Now create a handler confiuration file say 'handlers.xml' as shown below and put it in 'WEB-INF' directory of your application.

<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
   <handler-chain>
      <handler>
         <handler-class>my.server.pkg.LoggingHandler</handler-class>
      </handler>
   </handler-chain>
</handler-chains>
Using @HandlerChain annotation we can instruct the JAX-WS runtime to apply the handlers configured in the above-mentioned configuration on a web service endpoint-
@WebService(endpointInterface = "my.server.pkg.IMyService")
@HandlerChain(file = "handlers.xml")
public class MyServiceImpl implements IMyService {
Now all incoming and outgoing SOAP messages will be logged to standard output stream. Source code for this example is available here.
For developing and deploying web services see my earlier posts-
http://blog.vinodsingh.com/2008/09/building-jax-ws-web-service.html
http://blog.vinodsingh.com/2008/09/jax-ws-web-service-and-jboss.html

19 Comments: