Web services Handler Chains tutorial

Handler Chains play a crucial role in intercepting and processing incoming and outgoing messages. They offer a flexible way to customize and extend the functionality of web services without modifying the core application logic. In this article, we’ll explore what Handler Chains are, how they work, and demonstrate their implementation with a practical example.

Understanding Web Services Handler Chains

Web Services and their clients may need to access the SOAP message for additional processing of the message request or response. You can create SOAP message handlers to enable Web Services and clients to perform this additional processing on the SOAP message. A SOAP message handler provides a mechanism for intercepting the SOAP message in both the request and response of the Web Service.

In order to use Handler chains in your Web service you have to add the @jakarta.jws.HandlerChain annotation at class level:

package com.sample.ws;

import jakarta.jws.HandlerChain;
import jakarta.jws.WebService;

@WebService(endpointInterface = "com.sample.ws.SampleWS", serviceName = "SampleWS")
public class SampleWSImpl implements SampleWS {
 public SampleWSImpl() {}
 public String hello(String s) {
 return "Hello "+s;

Ok, now your Web service will be proxied by one or more Handler defined in the handler-chain.xml configuration file.

In earlier releases of JBoss you had to place this file beneath the META-INF folder of your Web application. When using JBoss 7 just place it in the package folder which is included in the file property (In our example com/sample/ws).

Here is the handler-chain.xml which defines a Logging Handler:

<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">

And this is the Handler Class:

package com.sample.handler;

import java.util.Set;

import jakarta.xml.namespace.QName;
import jakarta.xml.soap.SOAPMessage;
import jakarta.xml.ws.handler.MessageContext;
import jakarta.xml.ws.handler.soap.SOAPHandler;
import jakarta.xml.ws.handler.soap.SOAPMessageContext;

import org.apache.commons.io.output.ByteArrayOutputStream;

public class LoggingHandler implements SOAPHandler<SOAPMessageContext> {

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

 public void close(MessageContext context) {

 public boolean handleFault(SOAPMessageContext context) {
  return true;

 public boolean handleMessage(SOAPMessageContext context) {
  return true;

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

  try {
   if (!outboundProperty.booleanValue()) {
   SOAPMessage message = smc.getMessage();
  System.out.println("Incoming message:");
  ByteArrayOutputStream stream = new ByteArrayOutputStream();
  catch (Exception e) {
  System.out.println("Exception in handler: " + e);

The above Handler will just print out all the SOAP incoming messages which are gathered as InputStream and finally converted to String using the ByteArrayOutputStream utility class from Apache Commons IO.

You can use SOAP message Handlers as well to improve the performance of your Web Service. After your Web Service has been deployed, you might discover that many consumers invoke it with the same parameters. You could improve the performance of your Web Service by caching the results of popular invokes of the Web Service (assuming the results are static) and immediately returning these results when appropriate, without ever invoking the back-end components that implement the Web Service. You implement this performance improvement by using handlers to check the request SOAP message to see if it contains the popular parameters.

Similarities between Handlers and CXF Interceptors

JAX-WS handlers are internally implemented in CXF by use of interceptors, so by definition anything that can be done with the former can be done with the latter. Handlers and interceptors are quite similar, in fact both have a handleMessage()  which is defined by the top level interfaces. Both provide mechanisms for SOAP messages as well as more generic XML over HTTP routing. The routing direction is also similar in that handleFault(), when errors occur, causes the interceptors to run in reverse order.

Differences between Handlers and CXF Interceptors

The most important difference is that CXF Interceptors are split into two main categories: inbound and outgoing interceptors which are used to collect the server incoming message and the outgoing response. On the other hand  when using JAX-WS handlers, the same handlers are activated both on request and reply. When using Handlers you can discriminate if it’s an inbound/outbound message by checking the MessageContext.MESSAGE_OUTBOUND_PROPERTY.

public boolean handleMessage(SOAPMessageContext messageContext)
 Boolean outboundProperty = (Boolean)
 messageContext.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY);

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

 System.out.println("** Response: "+messageContext.getMessage().toString());
 return true;

Another difference is that an additional close() method,used for object cleanup, is available with handlers but not interceptors.

public void close(MessageContext messageContext)

Another difference is how Fault exception are treated. When using Interceptors you can retrieve the Fault from the MessageContent:

public void handleMessage(SoapMessage message) throws Fault {
 Fault fault = (Fault) message.getContent(Exception.class);

…provided that you registered your Fault Interceptor:

@org.apache.cxf.interceptor.OutFaultInterceptors (interceptors = {"com.sample.CustomFaultInterceptor" })
public class SayHiImpl  implements SayHi {
public long sayHi(long arg) {
return arg;



Handler Chains provide a powerful mechanism for intercepting and processing messages in web services. By understanding the components of a handler chain and following a structured approach, developers can implement custom logic to address various cross-cutting concerns efficiently. In this article, we’ve covered the basics of Handler Chains and demonstrated their implementation with a practical logging example. Whether it’s logging, security, or transformation, Handler Chains offer a flexible solution to extend the functionality of web services seamlessly.