Thursday, March 20, 2014

Writing JAX-WS SoapHandler

SoapHandler(SMH) is a interceptor for JAXWS webservies. It will intercept in bound and out bound messages. It is a couterpart of GenericHandler for the JAXRPC webservices. There are two types of handlers for JAXWS webservices. One is LogicalHandler and other is SoapHandler. LogicalHandler is used to write some logic on in bound or out bound messages. Lets focus now on writing SoapHandler. Lets try to do it in simple steps. 1. Write a handler by implementing interface SoapHandler. SoapHandler is a Generic interface, which takes in any class which "IS A" SOAPMessageContext. If you want your custom features in SOAPMessageContext, then implement you own. Else, use SOAPMessageContext.
 
public class MySoapHandler implements SOAPHandler{

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
 // TODO Auto-generated method stub
 return false;
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
 // TODO Auto-generated method stub
 return false;
    }

    @Override
    public void close(MessageContext context) {
 // TODO Auto-generated method stub
 
    }

    @Override
    public Set getHeaders() {
 // TODO Auto-generated method stub
 return null;
    }

}

2. Once you implement the class, you will have to implement a number of methods. Prominent method being 2.1 handleMessage(SOAPMessageContext context) - This is the method used to get the in bound or out bound messages and process it. 2.2 handleFault(SOAPMessageContext context) - Whenever there is a Fault, this message is called and you can write logic to handle the fault. 3. I will log the inbound and out bound messages in handleMessgae and let the flow continue.
 
 
     @Override
    public boolean handleMessage(SOAPMessageContext context) {
 Boolean isOutbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
 if (!isOutbound) {
     System.out.println("In Bound Message ... ");
 }
 else {
     System.out.println("Out Bound Message ... ");
 }

 try {
     context.getMessage().writeTo(System.out);
 }
 catch (SOAPException e) {
     e.printStackTrace();
 }
 catch (IOException e) {
     e.printStackTrace();
 }
 return true;
    }

4. Write a handlerConfig.xml file which will contain the fully qualified class name of the handler we just created. As the name of the file indicates, it is a chain of handlers.
    <handler-chains xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/javaee_web_services_metadata_handler_2_0.xsd">  
      <handler-chain>  
           <handler>  
                <handler-name>SoapRequestValidator</handler-name>  
                <handler-class>com.example.jws.handler.MySoapHandler</handler-class>  
           </handler>  
 <!-- Can have multiple chains ... -->  
      </handler-chain>  
 </handler-chains>  
5. In the JAXWs webservice, include the handlerChain using the annotation:
@HandlerChain(file = "handlerConfig.xml")
Place the handlerConfig.xml in the same package as the webservice endpoint implementation file.
6. Finally, very important point is to include the handlerConfig.xml in the war which you build. If you don't include the handlerConfig file, then you don't get any error. But the handler will never be called. So, do remember to include the handlerConfig.xml in the war file.
Expect an example project on this shortly in my github account. Simple isn't it :)

No comments:

Post a Comment