JAXWS Handler Chain Intercept incoming outgoing messages

In this tutorial we create a basic JAX-WS web service with a handler chain. SOAP Handlers are similar to Servlet Filters or EJB/CDI Interceptor. They can intercept and alter incomming and outgoing SOAP messages. JAX-WS defines a Handler interface with subinterfaces LogicalHandler and SOAPHandler. The SOAPHandler has access to the full SOAP Message, including the headers. The LogicalHandler only has access to the Payload of the message.

Project Structure

src
|--main
|    +--java
|        +--com
|            +--memorynotfound
|                +--handlers
|                    |--LoggingHandler.java
|                +--ws
|                    |--GreetingService.java
|                    |--GreetingServiceImpl.java
|    +--resources
|        +--com
|            +--memorynotfound
|                +--ws
|                    |--handlers.xml
|    +--webapp
|        +--WEB-INF
|            |--sun-jaxw.xml
|            |--web.xml
pom.xml

SOAP Handler

To create a Handler we need to implement the javax.xml.ws.handler.Handler interface or any of its subinterfaces.

  • SOAPHandler: SOAP handlers can access the entire SOAP message, including the message headers and body.
  • LogicalHandler: Logical handlers can access the payload of the message only, and cannot change any protocol-specific information (like headers) in a message.
package com.memorynotfound.handlers;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.util.HashSet;
import java.util.Set;

public class LoggingHandler implements SOAPHandler<SOAPMessageContext> {

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

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        Boolean isOutBound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        try {
            if (isOutBound){
                System.out.println("Intercepting outbound message:");
            } else {
                System.out.println("Intercepting inbound message:");
            }
            context.getMessage().writeTo(System.out);
            System.out.println();
        } catch (SOAPException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }

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

    @Override
    public void close(MessageContext context) {
        System.out.println("Do some cleanup handling .. ");
    }
}

SOAP Handler chain xml file

Warning: In order for the handler chain to register for your web service the handlers.xml file needs to be in the same package as your web service on the classpath. This means for every service you need to add a handler chain this file must exist.
<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
    <handler-chain>
        <handler>
            <handler-name>LoggingHandler</handler-name>
            <handler-class>com.memorynotfound.handlers.LoggingHandler</handler-class>
        </handler>
    </handler-chain>
</handler-chains>

Attaching the Handler to our Web Service

To register a SOAP Handler with our Web Service we need to specify a @HandlerChain() annotation in our class. As said before, the handlers.xml file must be in the same package on your classpath as the web service. For our example this means that the file must exist in com.memorynotfound.ws in the resources folder.

package com.memorynotfound.ws;

import javax.jws.HandlerChain;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService
@HandlerChain(file = "handlers.xml")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class GreetingServiceImpl implements GreetingService {

    public String printMessage() {
        return "Hello, World!";
    }
}

References

Download

You may also like...