JAX-RPC 2.0 Early Access
Handler Framework


Last Modified: 04/04/05

Handler Types

JAX-RPC 2.0 defines two new handler interfaces, LogicalHandler and SOAPHandler. Both interfaces extend AbstractHandler, which replaces handleRequest and handleResponse with a common handleMessage(C context) method, where C extends MessageContext. A property in the MessageContext object is used to determine what type of message is being processed. For backwards compatibilty, JAX-RPC 1.1 Handler objects are still supported. Together with SOAPHandler, these are known as protocol handlers, and they have access to the full soap message including headers. Logical handlers are independent of protocol and have access to the payload of the message.

The new handler types can now be written without casting the message context object that is passed to them. For instance:

public class MyLogicalHandler implements LogicalHandler<LogicalMessageContext> {
    public boolean handleMessage(LogicalMessageContext messageContext) {
        LogicalMessage msg = messageContext.getLogicalMessage();
        return true;
    }
    // other methods
}

public class MySOAPHandler implements SOAPHandler<SOAPMessageContext> {

    public boolean handleMessage(SOAPMessageContext messageContext) {
        SOAPMessage msg = messageContext.getSOAPMessage();
        return true;
    }
    // other methods
}

Similarly, the new handlers define a handleFault(C context) method that is used for fault-specific handling. Besides the standard lifecycle methods and new handle methods, a close(C context) method has been added that is called on the handlers at the conclusion of a message exchange pattern. This allows handlers to clean up any resources that were used for the processing of a request-only or request/response exchange.

MessageContext

In the examples above, the LogicalMessage object allows a handler to get and set the message payload either as a JAXB object or as a javax.xml.transform.Source. The SOAPMessage object is the same as in JAX-RPC 1.1, and allows access to headers and the SOAP body of the message.

Both context objects extend MessageContext, which holds properties that the handlers can use to communicate with each other. A standard property MessageContext.MESSAGE_OUTBOUND_PROPERTY holds a Boolean that is used to determine the direction of a message. For example, during a request, the property would be Boolean.TRUE when seen by a client handler and Boolean.FALSE when seen by a server handler.

The message context object can also hold properties set by the client or provider. For instance, stubs and dispatch objects both extend BindingProvider. A JAXRPCContext object can be obtained from both to represent the request or response context. Properties set in the request context can be read by the handlers, and properties set by the handler will be available in the response context. On the server end, a context object is passed into the invoke method of a Provider.

Handler Chain Configuration

Static Case

Starting from a WSDL file, handler chain configuration is similar to the configuration used in JAX-RPC 1.1. A <handlerChains> element is added to the customization file. The following is a simple handler chain with one handler on the server side:

<handlerChains xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
    <chain runAt="server">
        <handler className="fromwsdlhandler.common.LoggingHandler"/>
    </chain>
</handlerChains>

Next is a more complete example with multiple handlers. The example service has two ports. Note that one handler is set on only one port. Thus, it will be invoked only when a message is sent to that port in the service. The last handler is specific to the SOAP protocol binding. Thus, it will invoked on any SOAP request. If neither port nor protocol is specified, the handler is included in any handler chain for the service. This example shows how to include roles and understood headers as well:

<handlerChains xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
    <chain runAt="server"
            roles="http://example.com/role1 http://example.com/role2">
        <handler className="com.example.MyLogicalHandler"
                port="ns2:Port1" xmlns:ns2="urn:myservice">
            <property name="initProp" value="initPropValue"/>
        </handler>
        <handler className="com.example.MySOAPHandler"/>
        <handler className="com.example.AnotherSOAPHandler"
                headers="ns3:testheader1 ns3:testheader2"
                xmlns:ns3="http://example.com/someheader"/>
        <handler className="com.example.MySOAPHandler"
                protocolBinding="http://schemas.xmlsoap.org/wsdl/soap/http">
        </handler>
    </chain>
</handlerChains>

The <chain> element can contain a mix of handler types with some specific to a port, protocol, or the service itself. When the handler chain is created for a given binding, the order will be changed to:

  1. Per-service logical handlers
  2. Per-port logical handlers
  3. Per-protocol binding logical handlers
  4. Per-service protocol handlers
  5. Per-port protocol handlers
  6. Per-protocol binding protocol handlers

For the client, the same format is used as for the server. The runAt attribute of the <chain> element is set to client instead.

Starting from a Java class, annotations are used to describe the handler chain. The following example uses the @HandlerChain annotation to refer to a file describing the chain:

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

@WebService
@HandlerChain( file="handlers.xml", name="Chain1")
public class MyServiceImpl {
    // implementation of class
}

An example handlers.xml file is shown below:

<?xml version="1.0" encoding="UTF-8"?>
<jws:handler-config xmlns:jws="http://www.bea.com/xml/ns/jws">
    <jws:handler-chain>
        <jws:handler-chain-name>Chain1</jws:handler-chain-name>
        <jws:handler>
            <jws:handler-name>com.example.MySOAPHandler</jws:handler-name>
            <jws:handler-class>com.example.MySOAPHandler</jws:handler-class>
        </jws:handler>
    </jws:handler-chain>
</jws:handler-config>

For full details on handler annotations, see the JSR 181 specification. For the JAX-RPC 2.0 release, the handlers.xml file must be in the classpath when apt is invoked to create the service. When packaging the service with wsdeploy, the file must again be in the classpath within the WAR file, either directly under WEB-INF/classes or further down in the same package as the service class file.

Programmatic Case

Handler chains may be configured on the client side at runtime either by using the HandlerRegistry or by setting a chain directly on a BindingProvider (e.g., a Dispatch object or a statically generated Stub.) The registry object can be obtained directly from a JAX-RPC service. The handler registry has methods for getting and setting java.util.Lists of HandlerInfo objects which decribe the handlers. Handlers may be set on a per-port, per-protocol binding, or per-service basis. This example shows how to add a chain with one handler to a service:

    Service myService = // create service
    service.createPort(...); // needed to create Dispatch

    HandlerRegistry registry = service.getHandlerRegistry();
    List<HandlerInfo> handlerList = new ArrayList<HandlerInfo>();
    HandlerInfo hInfo = new HandlerInfo();
    hInfo.setHandlerClass(MyHandler.class);
    handlerList.add(hInfo);
    registry.setHandlerChain(handlerList);

    Dispatch myDispatch = service.createDispatch(...);
    Stub myStub = service.getPort(...);

For the Dispatch and Stub objects obtained above, a snapshot of the applicable handler chain is set on the objects. Further changes to the registry do not affect existing binding providers.

With an existing binding provider, a Binding object can be obtained with getBinding. The binding object has a setHandlerChain method that takes a list of handler info objects that can be used to set a new handler chain on the client. When the SOAP protocol is being used, the binding can be cast to a SOAPBinding object that can be used to programmatically set the SOAP roles for the binding.

Handler Samples

The fromjavahandler and fromwsdlhandler samples set a SOAPHandler on the client and server. This handler simply outputs the contents of the SOAP message and can be used to see the requests and responses being passed back and forth. See the sample documentation for information on running the samples.


Copyright © 2005 Sun Microsystems, Inc. All rights reserved.