Monday, January 21, 2013

How to set handlers on the JAX-WS client side

In webservice, handlers can be used for logging messages, implmenting security,etc. For a JAX-WS client, there are several ways to set handlers.

Use xml binding

The handlers can be set by binding a handler XML file.
import javax.xml.ws.Service;

@WebServiceClient(name = "MyService", targetNamespace = "...", wsdlLocation = "...")
@HandlerChain(file = "MyService_handler.xml")
public class MyService extends Service{
...
}
MyService_handler.xml:
<?xml version="1.0" encoding="UTF-8"?>
<javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee">
  <javaee:handler-chain>
    <javaee:handler>
      <javaee:handler-class>com.my.SOAPHandler1</javaee:handler-class>
    </javaee:handler>
    <javaee:handler>
      <javaee:handler-class>com.my.SOAPHandler2</javaee:handler-class>
    </javaee:handler>
  
  </javaee:handler-chain>
</javaee:handler-chains>

Set handlers programmatically

The handlers can also be set programmatically. You can use BindingProvider to set the handlers.
import javax.xml.ws.BindingProvider;

 MyService service = new MyService(wsdlLoc, qName);
 port = service.getXXX();
 BindingProvider bp = (BindingProvider) port;
 Binding binding = bp.getBinding();
 List<Handler> handlerList = binding.getHandlerChain();
 MySOAPHandler myHandler = new MySOAPHandler();
 handlerList.add(myHandler );
 bp.getBinding().setHandlerChain(handlerList);

 port.callXYZ(...);
        
You can also use HandlerResolver to set handlers.

    import javax.xml.ws.handler.Handler;
    import javax.xml.ws.handler.HandlerResolver;
    import javax.xml.ws.handler.PortInfo;

        MyService service = new MyService(wsdlLoc, qName);
       
        service.setHandlerResolver(new HandlerResolver() {
        @Override public List getHandlerChain(PortInfo portInfo) { 
         List<Handler> handlerChain = new ArrayList<Handler>(); 
         handlerChain.add(new MySOAPHandler()); 
         return handlerChain; 
       } 
     });
     
      port = service.getXXX();
      port.callXYZ(...);
But be careful that the code "port = service.getXXX()" must be put after service.setHandlerResolver(...). If it is put before the call setHandlerResolver(...), the code won't work.

References

  1. http://www.javaworld.com/javaworld/jw-02-2007/jw-02-handler.html
  2. http://jax-ws.java.net/nonav/2.2.7/docs/index.html

1 comment:

  1. Jesus, I've been searching for this so long. The jax-ws importer allowed me to set a handler only to a webservice itself, not to its port. For the port it generated handler-chain xml file that doesn't even exist. I tried to create and place it here and there, but it didn't help. I tried to set the handler programmatically and it has worked.
    Thank you!

    ReplyDelete