41.10. Configuring Endpoints to Use Handlers

41.10.1. Programmatic Configuration

41.10.1.1. Adding a Handler Chain to a Consumer

Overview
Adding a handler chain to a consumer involves explicitly building the chain of handlers. Then you set the handler chain directly on the service proxy's Binding object.
Important
Any handler chains configured using the Spring configuration override the handler chains configured programmaticaly.
Procedure
To add a handler chain to a consumer you do the following:
  1. Create a List<Handler> object to hold the handler chain.
  2. Create an instance of each handler that will be added to the chain.
  3. Add each of the instantiated handler objects to the list in the order they are to be invoked by the runtime.
  4. Get the Binding object from the service proxy.
    Tip
    Apache CXF provides an implementation of the Binding interface called org.apache.cxf.jaxws.binding.DefaultBindingImpl.
  5. Set the handler chain on the proxy using the Binding object's setHandlerChain() method.
Example
Example 41.14, “Adding a Handler Chain to a Consumer” shows code for adding a handler chain to a consumer.

Example 41.14. Adding a Handler Chain to a Consumer

import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.Handler;
import java.util.ArrayList;
import java.util.List;

import org.apache.cxf.jaxws.binding.DefaultBindingImpl;
...
SmallNumberHandler sh = new SmallNumberHandler(); 1
List<Handler> handlerChain = new ArrayList<Handler>(); 2
handlerChain.add(sh); 3

DefaultBindingImpl binding = ((BindingProvider)proxy).getBinding(); 4
binding.getBinding().setHandlerChain(handlerChain); 5
1
Instantiates a handler.
2
Creates a List object to hold the chain.
3
Adds the handler to the chain.
4
Gets the Binding object from the proxy as a DefaultBindingImpl object.
5
Assigns the handler chain to the proxy's binding.

41.10.1.2. Adding a Handler Chain to a Service Provider

Overview
You add a handler chain to a service provider by decorating either the SEI or the implementation class with the @HandlerChain annotation. The annotation points to a meta-data file defining the handler chain used by the service provider.
Procedure
To add handler chain to a service provider you do the following:
  1. Decorate the provider's implementation class with the @HandlerChain annotation.
  2. Create a handler configuration file that defines the handler chain.
The @HandlerChain annotation
The javax.jws.HandlerChain annotation decorates service provider's implementation class. It instructs the runtime to load the handler chain configuration file specified by its file property.
The annotation's file property supports two methods for identifying the handler configuration file to load:
  • a URL
  • a relative path name
Example 41.15, “Service Implementation that Loads a Handler Chain” shows a service provider implementation that will use the handler chain defined in a file called handlers.xml. handlers.xml must be located in the directory from which the service provider is run.

Example 41.15. Service Implementation that Loads a Handler Chain

import javax.jws.HandlerChain;
import javax.jws.WebService;
...

@WebService(name = "AddNumbers",
            targetNamespace = "http://apache.org/handlers",
            portName = "AddNumbersPort",
            endpointInterface = "org.apache.handlers.AddNumbers",
            serviceName = "AddNumbersService")
@HandlerChain(file = "handlers.xml")
public class AddNumbersImpl implements AddNumbers
{
...
}
Handler configuration file
The handler configuration file defines a handler chain using the XML grammar that accompanies JSR 109 (Web Services for Java EE, Version 1.2). This grammar is defined in the http://java.sun.com/xml/ns/javaee.
The root element of the handler configuration file is the handler-chains element. The handler-chains element has one or more handler-chain elements.
The handler-chain element define a handler chain. Table 41.1, “Elements Used to Define a Server-Side Handler Chain” describes the handler-chain element's children.

Table 41.1. Elements Used to Define a Server-Side Handler Chain

ElementDescription
handler Contains the elements that describe a handler.
service-name-pattern Specifies the QName of the WSDL service element defining the service to which the handler chain is bound. You can use * as a wildcard when defining the QName.
port-name-pattern Specifies the QName of the WSDL port element defining the endpoint to which the handler chain is bound. You can use * as a wildcard when defining the QName.
protocol-binding
Specifies the message binding for which the handler chain is used. The binding is specified as a URI or using one of the following aliases: ##SOAP11_HTTP, ##SOAP11_HTTP_MTOM, ##SOAP12_HTTP, ##SOAP12_HTTP_MTOM, or ##XML_HTTP.
For more information about message binding URIs see Appendix C, Apache CXF Binding IDs.
The handler-chain element is only required to have a single handler element as a child. It can, however, support as many handler elements as needed to define the complete handler chain. The handlers in the chain are executed in the order they specified in the handler chain definition.
Important
The final order of execution will be determined by sorting the specified handlers into logical handlers and protocol handlers. Within the groupings, the order specified in the configuration will be used.
The other children, such as protocol-binding, are used to limit the scope of the defined handler chain. For example, if you use the service-name-pattern element, the handler chain will only be attached to service providers whose WSDL port element is a child of the specified WSDL service element. You can only use one of these limiting children in a handler element.
The handler element defines an individual handler in a handler chain. Its handler-class child element specifies the fully qualified name of the class implementing the handler. The handler element can also have an optional handler-name element that specifies a unique name for the handler.
Example 41.16, “Handler Configuration File” shows a handler configuration file that defines a single handler chain. The chain is made up of two handlers.

Example 41.16. Handler Configuration File

<handler-chains xmlns="http://java.sun.com/xml/ns/javaee" 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xsi:schemaLocation="http://java.sun.com/xml/ns/javaee">
  <handler-chain>
    <handler>
      <handler-name>LoggingHandler</handler-name>
      <handler-class>demo.handlers.common.LoggingHandler</handler-class>
    </handler>
    <handler>
      <handler-name>AddHeaderHandler</handler-name>
      <handler-class>demo.handlers.common.AddHeaderHandler</handler-class>
    </handler>
  </handler-chain>
</handler-chains>

41.10.2. Spring Configuration

Overview

The easiest way to configure an endpoint to use a handler chain is to define the chain in the endpoint's configuration. This is done by adding a jaxwxs:handlers child to the element configuring the endpoint.
Important
A handler chain added through the configuration file takes precedence over a handler chain configured programatically.

Procedure

To configure an endpoint to load a handler chain you do the following:
  1. If the endpoint does not already have a configuration element, add one.
    For more information on configuring Apache CXF endpoints see Chapter 15, Configuring JAX-WS Endpoints.
  2. Add a jaxws:handlers child element to the endpoint's configuration element.
  3. For each handler in the chain, add a bean element specifying the class that implements the handler.
    Tip
    If your handler implementation is used in more than one place you can reference a bean element using the ref element.

The handlers element

The jaxws:handlers element defines a handler chain in an endpoint's configuration. It can appear as a child to all of the JAX-WS endpoint configuration elements. These are:
  • jaxws:endpoint configures a service provider.
  • jaxws:server also configures a service provider.
  • jaxws:client configures a service consumer.
You add handlers to the handler chain in one of two ways:
  • add a bean element defining the implementation class
  • use a ref element to refer to a named bean element from elsewhere in the configuration file
The order in which the handlers are defined in the configuration is the order in which they will be executed. The order may be modified if you mix logical handlers and protocol handlers. The run time will sort them into the proper order while maintaining the basic order specified in the configuration.

Example

Example 41.17, “Configuring an Endpoint to Use a Handler Chain In Spring” shows the configuration for a service provider that loads a handler chain.

Example 41.17. Configuring an Endpoint to Use a Handler Chain In Spring

<beans ...
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  ...
  schemaLocation="...
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    ...">
  <jaxws:endpoint id="HandlerExample"
                  implementor="org.apache.cxf.example.DemoImpl"
                  address="http://localhost:8080/demo">
    <jaxws:handlers>
       <bean class="demo.handlers.common.LoggingHandler" />
       <bean class="demo.handlers.common.AddHeaderHandler" />
    </jaxws:handlers>
  </jaws:endpoint>
</beans>