Chapter 7. Handler Framework

Table of Contents

7.1. Overview
7.2. Handler Chain Execution Order
7.3. Handler Class Organization
7.3.1. Declaring Handler Classes
7.4. Configuring a Handler Class
7.4.1. Creating a Web service from Java Class
7.4.2. Creating a Web Service from WSDL
7.4.3. Creating a Client
7.5. Example of a Web Service that Use a Handler Chain
7.6. Executing Handler Framework in Web Services

This chapter describes the basic concepts and components of the handler framework with examples.

7.1. Overview

JAX-WS Web services provide a plug-in style framework, which is more convenient for the handlers and also improves the runtime system functionality of JEUS 8 web services.

The following are two types of handlers.

  • Logical handler

    Accesses the message payload regardless of the protocol.

  • SOAP handler

    Accesses the entire content of a SOAP message including the headers.

[Figure 7.1] Relationship between message contexts

Relationship between message contexts

Use the following criteria to select a handler.

  • Use the SOAP handler if the entire SOAP message is needed.

  • Use the logical handler if only the XML document payload of the SOAP message is needed.

In other cases, web services configure the endpoint class to process messages. In a special case where the Java object is required, the Interceptor class supported by JEUS EJB is used. For more information about the JEUS EJB Interceptor class, refer to "JEUS EJB Guide".

7.2. Handler Chain Execution Order

For an outbound message, all logical handlers in the handler chain are processed before SOAP handlers. For an inbound message, all SOAP handlers are processed before logical handlers.

Caution

In programming client or service-endpoint interfaces, even though logical handlers are configured before SOAP handlers, all logical handlers are processed before SOAP handlers in creating or calling the services.

[Figure 7.2] Handler Framework

Handler Framework

7.3. Handler Class Organization

This section describes how to organize a handler class and discusses about the MessageContext class.

7.3.1. Declaring Handler Classes

To organize a handler class, a user creates a class that implements a logical handler or SOAP handler interface.

The following is an example of each handler class.

[Example 7.1] << MyLogicalHandler.java >>

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

[Example 7.2] << MySOAPHandler.java >>

public class MySOAPHandler implements
    SOAPHandler<SOAPMessageContext> {
    public boolean handleMessage(SOAPMessageContext messageContext) {
        SOAPMessage msg = messageContext.getMessage();
        return true;
    }
}

As shown in the previous example, both logical and SOAP handlers implement a handler interface, and the handler interface implements two methods, handlerMessage( ) and handleFault( ).

Each method receives an instance that inherits the MessageContext class as a parameter, and the instance is used to determine whether the message is inbound or outbound. The @PostConstruct and @PreDestroy annotations can be used in a user handler class as shown in the following example.

[Example 7.3] << MyLogicalHandler.java >>

public class MyLogicalHandler implements
    LogicalHandler<LogicalMessageContext> {
    @PostConstruct
    public void methodA() {}

    @PreDestroy
    public void methodB() {}
}

In the previous MyLogicalHandler class, methodA, declared with the @PostConstruct annotation, is invoked after the handler is created and methodB, declared with the @PreDestroy annotation, is invoked before the handler is destroyed.

7.4. Configuring a Handler Class

This section describes how to attach a user handler to a web service.

7.4.1. Creating a Web service from Java Class

To create a web service using a Java class, configure the @HandlerChain annotation in the service endpoint implementation class with the wsgen tool.

[Example 7.4] << MyServiceImpl.java >>

@WebService
@HandlerChain( file="handlers.xml")
public class MyServiceImpl {
    ...
}

The following is the handlers.xml file that is set as the @HandlerChain annotation in the previous example. A server handler is configured in the metadata file, handlers.xml.

[Example 7.5] << handlers.xml >>

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


7.4.2. Creating a Web Service from WSDL

To create a web service from WSDL, indirectly embed binding customization into the WSDL document, which is used to create the web service, by using the wsimport tool.

The following is an example of indirectly embedding binding customization into the WSDL document by using an external file.

<bindings xmlns="http://java.sun.com/xml/ns/jaxws">
    <handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
        <handler-chain>
            <handler>
                <handler-class>fromwsdl.handler.TmaxHandler</handler-class>
            </handler>
        </handler-chain>
    </handler-chains>
</bindings>

Note that the <handler-chains> element is added to the binding customization file in this example.

As shown in the following example, multiple <handler-chain> elements can be created inside the <handler-chains> element.

<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
    <handler-chain>
        <service-name-pattern xmlns:tm="http://tmaxsoft.com">
            tm:Tmax*Service
        </service-name-pattern>
        <handler>...</handler>
    </handler-chain>

    <handler-chain>
        <port-name-pattern xmlns:tm="http://tmaxsoft.com">
            tm:TmaxPort
        </port-name-pattern>
        <handler>...</handler>
    </handler-chain>

    <handler-chain>
        <protocol-bindings>##SOAP11_HTTP</protocol-bindings>
        <handler>...</handler>
    </handler-chain>
</handler-chains>

If multiple <handler-chain> elements are created inside the <handler-chains> element, some attributes such as service name, port name, or protocol can be applied to any handler.

7.4.3. Creating a Client

A client is created in the same way as creating a web service from WSDL.

7.5. Example of a Web Service that Use a Handler Chain

This section shows a simple example of implementing a user SOAP handler, that is used to output the log, and using it for a web service.

The javax.xml.ws.handler.LogicalHandler class, a logical handler class, or the javax.xml.ws.handler.SOAPHandler class, a SOAP handler class, inherits the abstract interface, javax.xml.ws.handler.Handler. A user can create a handler, as needed, by implementing the two classes.

The aforementioned handler class, LoggingHandler, that will be implemented in the example is a class that implements the SOAP handler class, javax.xml.ws.handler.soap.SOAPHandler.

[Example 7.6] << LoggingHandler.java >>

public class LoggingHandler implements SOAPHandler<SOAPMessageContext> {

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

    public void close(MessageContext messageContext) {

    }

    public boolean handleFault(SOAPMessageContext smc) {
        return true;
    }

    public boolean handleMessage(SOAPMessageContext smc) {
        Boolean inboundProperty = 
                 (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        System.out.println("\n##############################################");
        System.out.println("### JAX-WS Webservices examples - handler  ###");
        System.out.println("##############################################");

        if (inboundProperty.booleanValue()) {
            System.out.println("\nClient message:");
        } else {
            System.out.println("\nServer message:");
        }

        SOAPMessage message = smc.getMessage();
        try {
            message.writeTo(System.out);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }
}


As shown in the previous example, the handler checks whether the message coming into the handler is coming into the server or going out to the client.

Service Class

The following is the service block from the example Java class. In the service block, the @HandlerChain annotation is used to set the handler class of the server.

[Example 7.7] << handlers.xml >>

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


The following example shows the handlers.xml file, which is registered as the @HandlerChain annotation.

[Example 7.8] << AddNumbersImpl.java >>

@WebService
@HandlerChain(file = "handlers.xml")
public class AddNumbersImpl {

    public int addNumbers(int number1, int number2) {
        return number1 + number2;
    }
}


Client Class

The following shows the client block of the example Java class. In the client block, binding user declaration is added when using the wsimport tool to create a client through the WSDL document.

[Example 7.9] << AddNumbersClient.java >>

public class AddNumbersClient {

    public static void main(String[] args) {
        AddNumbersImpl port = new AddNumbersImplService().getAddNumbersImplPort();
        port.addNumbers(10, 20);
    }
}


The following example shows the binding user declaration.

[Example 7.10] << custom-client.xml >>

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    wsdlLocation="http://localhost:8088/AddNumbers/addnumbers?wsdl"
    xmlns="http://java.sun.com/xml/ns/jaxws">
    <bindings node="wsdl:definitions"
        xmlns:jws="http://java.sun.com/xml/ns/javaee">
        <jws:handler-chains>
            <jws:handler-chain>
                <jws:handler>
                    <jws:handler-class>
                        fromjavahandler.common.LoggingHandler
                    </jws:handler-class>
                </jws:handler>
            </jws:handler-chain>
        </jws:handler-chains>
    </bindings>
</bindings>


7.6. Executing Handler Framework in Web Services

This section describes how to execute the handler framework using the implemented classes and other configuration files from previous examples. Other service endpoint interface implementation classes and configuration files are the same as those from the previous examples.

Create a service by configuring the handler framework and deploy it to JEUS by executing the following command.

$ ant build deploy

Once the previous step is completed successfully, build and call the client. Since the client is processed by using the wsimport tool, it can only be built after the service has been deployed.

As shown in the following example, create a service with the configured handler framework and then call it. In the console, the LoggingHandler outputs the service-client message exchanges on both the service and client screens.

$ ant run

...

run:

     [java] ##############################################
     [java] ### JAX-WS Webservices examples - handler  ###
     [java] ##############################################

     [java] Client message:
     [java] <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body><ns2:addNumbers xmlns:ns2="http://server.fromjavahandler/"><arg0>10</arg0>
<arg1>20</arg1></ns2:addNumbers></S:Body></S:Envelope>
     [java] ##############################################
     [java] ### JAX-WS Webservices examples - handler  ###
     [java] ##############################################

     [java] Server message:
     [java] <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header/><S:Body><ns2:addNumbersResponse xmlns:ns2="http://server.fromjavahandler/">
<return>30</return></ns2:addNumbersResponse></S:Body></S:Envelope>

...

BUILD SUCCESSFUL