Skip navigation.
Downloads | Product Documentation | Support

Programming WebLogic Web Services

# Creating SOAP Message Handlers to Intercept the SOAP Message

The following sections discuss how to use SOAP message handlers to intercept the request and response SOAP messages when developing a WebLogic Web Service:

- Overview of SOAP Message Handlers and Handler Chains
- Creating SOAP Message Handlers: Main Steps
- Designing the SOAP Message Handlers and Handler Chains
- Implementing the Handler Interface
- Extending the GenericHandler Abstract Class
- Updating the web-services.xml File with SOAP Message Handler Information
- Using SOAP Message Handlers and Handler Chains in a Client Application
- Accessing the MessageContext of a Handler From the Backend Component

# Overview of SOAP Message Handlers and Handler Chains

A SOAP message handler intercepts the SOAP message in both the request and response of the Web Service. You can create handlers in both the Web Service itself and the client applications that invoke the Web Service. Refer to Using SOAP Message Handlers to Intercept the SOAP Message for examples of when to use handlers.

The following table describes the main classes and interfaces of the `javax.xml.rpc.handler` API; later sections in this chapter describe how to use them to create handlers.

Table 12-1 JAX-RPC Handler Interfaces and Classes

javax.xml.rpc.handler Classes and Interfaces | Description
--- | ---
`Handler` | Main interface that you implement when creating a handler. Contains methods to handle the SOAP request, response, and faults.
`HandlerInfo` | Contains information about the handler, in particular the initialization parameters, specified in the web-services.xml file.
`MessageContext` | Abstracts the message context processed by the handler. The MessageContext properties allow the handlers in a handler chain to share processing state.
`soap.SOAPMessageContext` | Sub-interface of the MessageContext interface used to get at or update the SOAP message.
`javax.xml.soap.SOAPMessage` | Object that contains the actual request or response SOAP message, including its header, body, and attachment.

# Creating SOAP Message Handlers: Main Steps

The following procedure assumes that you have already implemented and assembled a WebLogic Web Service using the `servicegen` Ant task, and you want to update the Web Service by adding handlers and handler chains.

1. Design the handlers and handler chains. See Designing the SOAP Message Handlers and Handler Chains.
2. For each handler in the handler chain, create a Java class that implements the `javax.xml.rpc.handler.Handler` interface. See Implementing the Handler Interface.

WebLogic Server includes an extension to the JAX-RPC handler API which you can use to simplify the coding of your handler class: an abstract class called `weblogic.webservice.GenericHandler`. See Extending the GenericHandler Abstract Class.

3. Compile the Java code into class files.
4. Update the `build.xml` file that contains the call to the `servicegen` Ant task, adding the `<handlerChain>` child element to the `<service>` element that builds your Web Service, as shown in the following example:

>           <servicegen
>              destEar="ears/myWebService.ear"
>              warName="myWAR.war"
>              contextURI="web_services" >
>              <service
>                  ejbJar="jars/myEJB.jar"
>                  targetNamespace="http://www.bea.com/examples/Trader"
>                  serviceName="TraderService"
>                  serviceURI="/TraderService"
>                  generateTypes="True"
>                  expandMethods="True" >
>                  <handlerChain
>                      name="myChain"
>                      handlers="myHandlers.handlerOne,
>                               myHandlers.handlerTwo,
>                               myHandlers.handlerThree"
>                  />
>              </service>
>          </servicegen>

For more information on the attributes of the `<handlerChain>` element, see servicegen.

Note: When you regenerate your Web Service using this `build.xml` file, every operation will be associated with the handler chain. Additionally, there is no way to specify input parameters for a handler using `servicegen`. If you want only certain operations to be associated with this handler chain, or you prefer not to regenerate your Web Service using `servicegen`, you can update the `web-services.xml` file of your WebLogic Web Service manually. For details, see Updating the web-services.xml File with SOAP Message Handler Information.

1. Re-run the `servicegen` Ant task to regenerate your Web Service.

For information about creating client-side SOAP message handlers and handler chains, see Using SOAP Message Handlers and Handler Chains in a Client Application.

# Designing the SOAP Message Handlers and Handler Chains

When designing your SOAP message handlers, you must decide:

- The number of handlers needed to perform all the work
- The sequence of execution
- Whether to invoke a back-end component or whether the Web Service consists of only a handler chain.

Each handler in a handler chain has one method for handling the request SOAP message and another method for handling the response SOAP message. You specify the handlers in the `web-services.xml` deployment descriptor file. An ordered group of handlers is referred to as a handler chain.

When invoking a Web Service, WebLogic Server executes handlers as follows:

1. The `handleRequest()` methods of the handlers in the handler chain are all executed, in the order specified in the `web-services.xml` file. Any of these `handleRequest()` methods might change the SOAP message request.
2. When the `handleRequest()` method of the last handler in the handler chain executes, WebLogic Server invokes the back-end component that implements the Web Service, passing it the final SOAP message request.

Note: This step only occurs if a back-end component has actually been defined for the Web Service; it is possible to develop a Web Service that consists of only a handler chain.

3. When the back-end component has finished executing, the `handleResponse()` methods of the handlers in the handler chain are executed in the reverse order specified in the `web-services.xml` file. Any of these `handleResponse()` methods might change the SOAP message response.
4. When the `handleResponse()` method of the first handler in the handler chain executes, WebLogic server returns the final SOAP message response to the client application that invoked the Web Service.

For example, assume that you have specified a handler chain called `myChain` that contains three handlers in the `web-services.xml` deployment descriptor, as shown in the following excerpt:

>     <handler-chains>
>        <handler-chain name="myChain">
>          <handler class-name="myHandlers.handlerOne" />
>          <handler class-name="myHandlers.handlerTwo" />
>          <handler class-name="myHandlers.handlerThree" />
>        </handler-chain>
>     </handler-chains>

The following graphic shows the order in which WebLogic Server executes the `handleRequest()` and `handleResponse()` methods of each handler:

Figure 12-1 Order of Execution of Handler Methods

Each SOAP message handler has a separate method to process the request and response SOAP message because the same type of processing typically must happen in both places. For example, you might design an Encryption handler whose `handleRequest()` method decrypts secure data in the SOAP request and `handleResponse()` method encrypts the SOAP response.

You can, however, design a handler that process only the SOAP request and does no equivalent processing of the response.

You can also choose not to invoke the next handler in the handler chain and send an immediate response to the client application at any point. The way to do this is discussed in later sections.

Finally, you can design a Web Service that contains only handlers in a handler chain, and no back-end component at all. In this case, when the `handleRequest()` method in the last handler has executed, the chain of `handleResponse()` methods is automatically invoked. See Updating the web-services.xml File with SOAP Message Handler Information for an example of using the `web-services.xml` file to specify that only a handler chain, and no back-end component, implements a Web Service.

# Implementing the Handler Interface

Your SOAP message handler class must implement the `javax.rpc.xml.handler.Handler` interface, as shown in the example at the end of this section. In particualr, the Handler interface contains the following methods that you must implement:

- `init()`

See Implementing the Handler.init() Method.

- `destroy()`

See Implementing the Handler.destroy() Method.

- `getHeaders()`

See Implementing the Handler.getHeaders() Method.

- `handleRequest()`

See Implementing the Handler.handleRequest() Method.

- `handleResponse()`

See Implementing the Handler.handleResponse() Method.

- `handleFault()`

See Implementing the Handler.handleFault() Method.

Sometimes you might need to directly view or update the SOAP message from within your handler, in particular when handling attachments, such as image. In this case, use the `javax.xml.soap.SOAPMessage` abstract class, which is part of the SOAP With Attachments API for Java 1.1 (SAAJ) specification For details, see Directly Manipulating the SOAP Request and Response Message Using SAAJ.

The following example demonstrates a simple SOAP message handler that prints out the SOAP request and response messages:

>     package examples.webservices.handler.log;

>     import java.util.Map;

>     import javax.xml.rpc.handler.Handler;
>     import javax.xml.rpc.handler.HandlerInfo;
>     import javax.xml.rpc.handler.MessageContext;
>     import javax.xml.rpc.handler.soap.SOAPMessageContext;
>     import javax.xml.rpc.JAXRPCException;
>     import javax.xml.namespace.QName;

>     import weblogic.logging.NonCatalogLogger;

>     /**
>      * Class that implements a handler in the handler chain, used to access the SOAP
>      * request and response message.
>      * <p>
>      * The class implements the <code>javax.xml.rpc.handler.Handler</code>
>      *  interface. The class simply prints the SOAP request and response messages
>      * to a log file before the messages are processed by the backend component.
>      *
>      * @author Copyright (c) 2003 by BEA Systems. All Rights Reserved.
>      */

>     public final class LogHandler
>       implements Handler
>     {
>       private NonCatalogLogger log;

>       private HandlerInfo handlerInfo;

>       /**
>        *  Initializes the instance of the handler.  Creates a nonCatalogLogger to
>        *  log messages to.
>        */
>       public void init(HandlerInfo hi) {
>         log = new NonCatalogLogger("WebService-LogHandler");
>         handlerInfo = hi;
>       }

>       /**
>        * Destroys the Handler instance.
>        */
>       public void destroy() {}

>       public QName[] getHeaders() { return handlerInfo.getHeaders(); }

>       /**
>        * Specifies that the SOAP request message be logged to a log file before the
>        * message is sent to the Java class backend component
>        */
>       public boolean handleRequest(MessageContext mc) {
>         SOAPMessageContext messageContext = (SOAPMessageContext) mc;

>         System.out.println("** Request: "+messageContext.getMessage().toString());
>         log.info(messageContext.getMessage().toString());
>         return true;
>       }

>       /**
>        * Specifies that the SOAP response message be logged to a log file before the
>        * message is sent back to the client application that invoked the Web service.
>        */
>       public boolean handleResponse(MessageContext mc) {

>         SOAPMessageContext messageContext = (SOAPMessageContext) mc;

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

>       /**
>        * Specifies that a message be logged to the log file if a SOAP fault is
>        * thrown by the Handler instance.
>        */
>       public boolean handleFault(MessageContext mc) {
>         SOAPMessageContext messageContext = (SOAPMessageContext) mc;

>         System.out.println("** Fault: "+messageContext.getMessage().toString());
>         log.info(messageContext.getMessage().toString());
>             return true;
>       }

## Implementing the Handler.init() Method

The `Handler.init()` method is called to create an instance of a `Handler` object and to enable the instance to initialize itself. Its signature is:

>       public void init(HandlerInfo config) throws JAXRPCException {}

The `HandlerInfo` object contains information about the SOAP message handler, in particular the initialization parameters, specified in the `web-services.xml` file. Use the `HandlerInfo.getHandlerConfig()` method to get the parameters; the method returns a `Map` object that contains name-value pairs.

Implement the `init()` method if you need to process the initialization parameters or if you have other initialization tasks to perform.

Sample uses of initialization parameters are to turn debugging on or off, specify the name of a log file to which to write messages or errors, and so on.

## Implementing the Handler.destroy() Method

The `Handler.destroy()` method is called to destroy an instance of a `Handler` object. Its signature is:

>       public void destroy() throws JAXRPCException {}

Implement the `destroy()` method to release any resources acquired throughout the handler's lifecycle.

## Implementing the Handler.getHeaders() Method

The `Handler.getHeaders()` method gets the header blocks processed by this Handler instance. Its signature is:

>       public QName[] getHeaders() {}

## Implementing the Handler.handleRequest() Method

The `Handler.handleRequest()` method is called to intercept a SOAP message request before it is processed by the back-end component. Its signature is:

>       public boolean handleRequest(MessageContext mc) throws JAXRPCException  {}

Implement this method to decrypt data in the SOAP message before it is processed by the back-end component, to make sure that the request contains the correct number of parameters, and so on.

The `MessageContext` object abstracts the message context processed by the SOAP message handler. The `MessageContext` properties allow the handlers in a handler chain to share processing state.

Use the `SOAPMessageContext` sub-interface of `MessageContext` to get at or update the contents of the SOAP message request. The SOAP message request itself is stored in a `javax.xml.soap.SOAPMessage` object. For detailed information on this object, see Directly Manipulating the SOAP Request and Response Message Using SAAJ.

The `SOAPMessageContext` class defines two methods for processing the SOAP request:

- `SOAPMessageContext.getMessage()`returns a `javax.xml.soap.SOAPMessage` object that contains the SOAP message request.
- `SOAPMessageContext.setMessage(javax.xml.soap.SOAPMessage)`updates the SOAP message request after you have made changes to it.

After you code all the processing of the SOAP request, do one of the following:

- Invoke the next handler on the handler request chain by returning `true`.

The next handler on the request chain is specified as the next `<handler>` subelement of the `<handler-chain>` element in the `web-services.xml` deployment descriptor. If there are no more handlers in the chain, the method either invokes the back-end component, passing it the final SOAP message request, or invokes the `handleResponse()` method of the last handler, depending on how you have configured your Web Service.

- Block processing of the handler request chain by returning `false`.

Blocking the handler request chain processing implies that the back-end component does not get executed for this invoke of the Web Service. You might want to do this if you have cached the results of certain invokes of the Web Service, and the current invoke is on the list.

Although the handler request chain does not continue processing, WebLogic Server does invoke the handler response chain, starting at the current handler. For example, assume that a handler chain consists of two handlers: handlerA and handlerB, where the `handleRequest()` method of handlerA is invoked before that of handlerB. If processing is blocked in handlerA (and thus the `handleRequest()` method of handlerB is not invoked), the handler response chain starts at handlerA and the `handleRequest()` method of handlerB is not invoked either.

- Throw the `javax.xml.rpc.soap.SOAPFaultException` to indicate a SOAP fault.

If the `handleRequest()` method throws a `SOAPFaultException`, WebLogic Server catches the exception, terminates further processing of the handler request chain, and invokes the `handleFault()` method of this handler.

- Throw a `JAXRPCException` for any handler specific runtime errors.

If the `handleRequest()` method throws a `JAXRPCException`, WebLogic Server catches the exception, terminates further processing of the handler request chain, logs the exception to the WebLogic Server logfile, and invokes the `handleFault()` method of this handler.

## Implementing the Handler.handleResponse() Method

The `Handler.handleResponse()` method is called to intercept a SOAP message response after it has been processed by the back-end component, but before it is sent back to the client application that invoked the Web Service. Its signature is:

>       public boolean handleResponse(MessageContext mc) throws JAXRPCException  {}

Implement this method to encrypt data in the SOAP message before it is sent back to the client application, to further process returned values, and so on.

The `MessageContext` object abstracts the message context processed by the SOAP message handler. The `MessageContext` properties allow the handlers in a handler chain to share processing state.

Use the `SOAPMessageContext` sub-interface of `MessageContext` to get at or update the contents of the SOAP message response. The SOAP message response itself is stored in a `javax.xml.soap.SOAPMessage` object. See Directly Manipulating the SOAP Request and Response Message Using SAAJ.

The `SOAPMessageContext` class defines two methods for processing the SOAP response:

- `SOAPMessageContext.getMessage()`: returns a `javax.xml.soap.SOAPMessage` object that contains the SOAP message response.
- `SOAPMessageContext.setMessage(javax.xml.soap.SOAPMessage)`: updates the SOAP message response after you have made changes to it.

After you code all the processing of the SOAP response, do one of the following:

- Invoke the next handler on the handler response chain by returning `true`.

The next response on the handler chain is specified as the preceding `<handler>` subelement of the `<handler-chain>` element in the `web-services.xml` deployment descriptor. (Remember that responses on the handler chain execute in the reverse order that they are specified in the `web-services.xml` file. See Designing the SOAP Message Handlers and Handler Chains for more information.)

If there are no more handlers in the chain, the method sends the final SOAP message response to the client application that invoked the Web Service.

- Block processing of the handler response chain by returning `false`.

Blocking the handler response chain processing implies that the remaining handlers on the response chain do not get executed for this invoke of the Web Service and the current SOAP message is sent back to the client application.

- Throw a `JAXRPCException` for any handler specific runtime errors.

If the `handleRequest()` method throws a `JAXRPCException`, WebLogic Server catches the exception, terminates further processing of the handler request chain, logs the exception to the WebLogic Server logfile, and invokes the `handleFault()` method of this handler.

## Implementing the Handler.handleFault() Method

The `Handler.handleFault()` method processes the SOAP faults based on the SOAP message processing model. Its signature is:

>         public boolean handleFault(MessageContext mc) throws JAXRPCException  {}

Implement this method to handle processing of any SOAP faults generated by the `handleResponse()` and `handleRequest()` methods, as well as faults generated by the back-end component.

The `MessageContext` object abstracts the message context processed by the SOAP message handler. The `MessageContext` properties allow the handlers in a handler chain to share processing state.

Use the `SOAPMessageContext` sub-interface of `MessageContext` to get at or update the contents of the SOAP message. The SOAP message itself is stored in a `javax.xml.soap.SOAPMessage` object. See Directly Manipulating the SOAP Request and Response Message Using SAAJ.

The `SOAPMessageContext` class defines the following two methods for processing the SOAP message:

- `SOAPMessageContext.getMessage()`: returns a `javax.xml.soap.SOAPMessage` object that contains the SOAP message.
- `SOAPMessageContext.setMessage(javax.xml.soap.SOAPMessage)`: updates the SOAP message after you have made changes to it.

After you code all the processing of the SOAP fault, do one of the following:

- Invoke the `handleFault()` method on the next handler in the handler chain by returning `true`.
- Block processing of the handler fault chain by returning `false`.

## Directly Manipulating the SOAP Request and Response Message Using SAAJ

The `javax.xml.soap.SOAPMessage` abstract class is part of the SOAP With Attachments API for Java 1.1 (SAAJ) specification. You use the class to manipulate request and response SOAP messages when creating SOAP message handlers. This section describes the basic structure of a `SOAPMessage` object and some of the methods you can use to view and update a SOAP message.

A `SOAPMessage` object consists of a `SOAPPart` object (which contains the actual SOAP XML document) and zero or more attachments.

Refer to the SAAJ Javadocs for the full description of the `SOAPMessage` class. For more information on SAAJ, go to http://java.sun.com/xml/saaj/index.html.

### The SOAPPart Object

The `SOAPPart` object contains the XML SOAP document inside of a `SOAPEnvelope` object. You use this object to get the actual SOAP headers and body.

The following sample Java code shows how to retrieve the SOAP message from a `MessageContext` object, provided by the `Handler` class, and get at its parts:

>     SOAPMessage soapMessage =  messageContext.getRequest();
>     SOAPPart soapPart = soapMessage.getSOAPPart();
>     SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
>     SOAPBody soapBody = soapEnvelope.getBody();
>     SOAPHeader soapHeader = soapEnvelope.getHeader();

### The AttachmentPart Object

The `javax.xml.soap.AttachmentPart` object contains the optional attachments to the SOAP message. Unlike the rest of a SOAP message, an attachment is not required to be in XML format and can therefore be anything from simple text to an image file.

Warning: If you are going to access a `java.awt.Image` attachment from your SOAP message handler, see Manipulating Image Attachments in a SOAP Message Handler for important information.

Use the following methods of the `SOAPMessage` class to manipulate the attachments:

- `countAttachments()`: returns the number of attachments in this SOAP message.
- `getAttachments()`: retrieves all the attachments (as `AttachmentPart` objects) into an `Iterator` object.
- `createAttachmentPart()`: create an `AttachmentPart` object from another type of `Object`.
- `addAttachmentPart()`: adds an `AttachmentPart` object, after it has been created, to the `SOAPMessage`.

The following example shows how you can create a SOAP message handler that accesses the SOAP attachment using the SAAJ API. The example uses the `weblogic.webservice.GenericHandler` abstract class, which is a WebLogic Server extension to the JAX-RPC handler API. For details about the `GenericHandler` class, see Extending the GenericHandler Abstract Class.

>     import java.util.Iterator;

>     import javax.xml.rpc.handler.MessageContext;
>     import javax.xml.rpc.handler.soap.SOAPMessageContext;
>     import javax.xml.rpc.JAXRPCException;

>     import javax.xml.soap.AttachmentPart;
>     import javax.xml.soap.SOAPException;
>     import javax.xml.soap.SOAPMessage;

>     import weblogic.webservice.GenericHandler;

>     import weblogic.utils.Debug;

>     public final class ServerHandler
>       extends GenericHandler
>     {
>       public boolean handleRequest(MessageContext m) {

>         SOAPMessageContext ctx = (SOAPMessageContext) m;

>         SOAPMessage request = ctx.getMessage();

>         if (request.countAttachments() == 0) {
>           throw new JAXRPCException("** Expected attachments");
>         }

>         Iterator it = request.getAttachments();

>         try {
>           while(it.hasNext()) {
>             AttachmentPart part = (AttachmentPart) it.next();
>             Debug.say("** Received attachment: "+
>               part.getContent());
>           }
>         } catch (SOAPException e) {
>           e.printStackTrace();
>           throw new JAXRPCException(e);
>         }

>         return true;

>       }

>     public boolean handleResponse(MessageContext m) {

>         SOAPMessageContext ctx = (SOAPMessageContext) m;

>         SOAPMessage response = ctx.getMessage();

>         if (response.countAttachments() != 0) {
>           throw new JAXRPCException("** Expected no attachments");
>         }

>         AttachmentPart part = response.createAttachmentPart();

>         part.setContent("<weblogic>RESPONSE</weblogic>", "text/xml");
>         response.addAttachmentPart(part);

>         return true;
>       }
>     }

### Manipulating Image Attachments in a SOAP Message Handler

It is assumed in this section that you are creating a SOAP message handler that accesses a `java.awt.Image` attachment and that the `Image` has been sent from a client application that uses the client JAX-RPC stubs generated by the `clientgen` Ant task.

In the client code generated by the `clientgen` Ant task, a `java.awt.Image` attachment is sent to the invoked WebLogic Web Service with a MIME type of `text/xml` rather than `image/gif`, and the Image is serialized into a stream of integers that represents the image. In particular, the client code serializes the `Image` using the following format:

- `int width`
- `int height`
- `int[] pixels`

This means that, in your SOAP message handler that manipulates the received Image attachment, you must deserialize this stream of data to then re-create the original Image.

The following example shows an implementation of the `handleRequest()` method of the `Handler` interface that iterates through the attachments of a SOAP message, and for each attachment, gets the input stream, deserializes it into a `java.awt.Image`, and then displays it in a frame using the Java Swing classes. It is assumed in the handler that all attachments are Images.

>     // it is assumed in this handler that all attachments are Image attachments

>       public boolean handleRequest(MessageContext mc)
>       {
>          try {
>            SOAPMessageContext messageContext = (SOAPMessageContext) mc;

>            SOAPMessage soapmsg = messageContext.getMessage();
>            Iterator iter = soapmsg.getAttachments();

>            // iterate through the attachments
>            while ( iter.hasNext() ) {
>              AttachmentPart part = (AttachmentPart) iter.next();

>              // get the input stream from the attachment and read the bytes into a byte[]

>              DataHandler dh = part.getDataHandler();
>              InputStream is = dh.getInputStream();
>              int size = is.available();
>              byte[] bytes = new byte[size];
>              is.read( bytes, 0, size);

>              // create a String from the byte[]
>              String content = new String(bytes);

>              // decode the String
>              byte[] bin = weblogic.xml.schema.types.XSDBase64Binary.convertXml(content );

>              // get an input stream for the binary object
>              ByteArrayInputStream in = new ByteArrayInputStream( bin );
>              ObjectInputStream oin = new ObjectInputStream( in );

>              // deserialize the stream.
>              // the format for an image is:
>              // int width
>              // int height
>              // int[] pix -- an array of pixels
>              int width = oin.readInt();
>              int height = oin.readInt();
>              int[] pix = (int[])oin.readObject();

>              // create an Image from the deserialized pieces
>              java.awt.image.MemoryImageSource source =
>                new java.awt.image.MemoryImageSource(width, height, pix, 0, width);

>              // this is sample code for displaying the image in a frame
>              java.awt.Panel panel = new java.awt.Panel();
>              java.awt.Image image = panel.createImage( source );

>             javax.swing.ImageIcon ii = new javax.swing.ImageIcon(image);
>             javax.swing.JLabel label = new javax.swing.JLabel(ii);
>             javax.swing.JFrame mainframe = new javax.swing.JFrame();
>             mainframe.getContentPane().add(label);
>             mainframe.pack();
>             mainframe.setVisible(true);
>           }
>         } catch (Exception ex) { ex.printStackTrace(); }

>         return true;
>      }

# Extending the GenericHandler Abstract Class

WebLogic Server includes an extension to the JAX-RPC handler API that you can use to simplify the Java code of your SOAP message handler class. This extension is the abstract class `weblogic.webservices.GenericHandler`. It implements the JAX-RPC javax.xml.rpc.handler.Handler interface.

Note: The `weblogic.webservices.GenericHandler` abstract class was originally developed for WebLogic Server when the JAX-RPC specification was not yet final and did not include this functionality. However, now that JAX-RPC includes its own `GenericHandler` class which is almost exactly the same as the WebLogic Server class, BEA highly recommends that you use the standard JAX-RPC abstract class rather than the WebLogic-specific one. The documentation in this section is provided for compatibility reasons only. For more information about the JAX-RPC `javax.xml.rpc.handler.GenericHandler` abstract class, see the JAX-RPC Javadocs.

Because `GenericHandler` is an abstract class, you need only implement the methods that will contain actual code, rather than having to implement every method of the `Handler` interface even if the method does nothing. For example, if your handler does not use initialization parameters and you do not need to allocate any additional resources, you do not need to implement the `init()` method.

The GenericHandler class is defined as follows:

>     package weblogic.webservice;

>     import javax.xml.rpc.handler.Handler;
>     import javax.xml.rpc.handler.HandlerInfo;
>     import javax.xml.rpc.handler.MessageContext;
>     import javax.xml.namespace.QName;

>     /**
>      * @author Copyright (c) 2002 by BEA Systems. All Rights Reserved.
>      */

>     public abstract class GenericHandler
>       implements Handler
>     {

>       private HandlerInfo handlerInfo;

>       public void init(HandlerInfo handlerInfo) {
>         this.handlerInfo = handlerInfo;
>       }

>       protected HandlerInfo getHandlerInfo() { return handlerInfo; }

>       public boolean handleRequest(MessageContext msg) {
>         return true;
>       }

>       public boolean handleResponse(MessageContext msg) {
>         return true;
>       }

>       public boolean handleFault(MessageContext msg) {}

>       public void destroy() {}
>       public QName[] getHeaders() { return handlerInfo.getHeaders(); }

>     }

The following sample code, taken from the `examples.webservices.handler.nocomponent` product example, shows how to use the `GenericHandler` abstract class to create your own handler. The example implements only the `handleRequest()` and `handleResponse()` methods. It does not implement (and thus does not include in the code) the `init()`, `destroy()`, `getHeaders()`, and `handleFault()` methods.

>     package examples.webservices.handler.nocomponent;

>     import java.util.Map;

>     import javax.xml.rpc.JAXRPCException;
>     import javax.xml.rpc.handler.MessageContext;
>     import javax.xml.rpc.handler.soap.SOAPMessageContext;
>     import javax.xml.soap.*;

>     import weblogic.webservice.GenericHandler;

>     import weblogic.utils.Debug;

>     /**
>      * @author Copyright (c) 2002 by BEA Systems. All Rights Reserved.
>      */

>     public final class EchoStringHandler
>       extends GenericHandler
>     {
>       private int me = System.identityHashCode(this);

>       public boolean handleRequest(MessageContext messageContext) {
>         System.err.println("** handleRequest called in: "+me);
>         return true;
>       }

>       public boolean handleResponse(MessageContext messageContext) {

>         try {
>           MessageFactory messageFactory = MessageFactory.newInstance();

>           SOAPMessage m = messageFactory.createMessage();

>           SOAPEnvelope env = m.getSOAPPart().getEnvelope();

>           SOAPBody body = env.getBody();

>           SOAPElement fResponse =
>             body.addBodyElement(env.createName("echoResponse"));

>           fResponse.addAttribute(env.createName("encodingStyle"),
>             "http://schemas.xmlsoap.org/soap/encoding/");

>           SOAPElement result =
>             fResponse.addChildElement(env.createName("result"));

>           result.addTextNode("Hello World");

>           ((SOAPMessageContext)messageContext).setMessage(m);

>           return true;

>         } catch (SOAPException e) {
>           e.printStackTrace();
>           throw new JAXRPCException(e);
>         }
>       }
>     }

# Updating the web-services.xml File with SOAP Message Handler Information

The `web-services.xml` deployment descriptor file describes the SOAP message handlers and handler chains defined for a Web Service and the order in which they should be executed.

To update the `web-services.xml` file with handler information:

1. Create a `<handler-chains>` child element of the `<web-services>` root element that will contain a list of all handler chains defined for the Web Service.
2. Create a `<handler-chain>` child element of the `<handler-chains>` element; within this element list all the handlers in the handler chain. For each handler, use the `class-name` attribute to specify the fully qualified name of the Java class that implements the handler. Use the `<init-params>` element to specify any initialization parameters of the handler.

The following sample excerpt shows a handler chain called `myChain` that contains three handlers, the first of which has an initialization parameter:

>     <web-services>
>        <handler-chains>
>           <handler-chain name="myChain">
>             <handler class-name="myHandlers.handlerOne" >
>                 <init-params>
>                    <init-param name="debug" value="on" />
>                 </init-params>
>             </handler>
>             <handler class-name="myHandlers.handlerTwo" />
>             <handler class-name="myHandlers.handlerThree" />
>           </handler-chain>
>        </handler-chains>
>     ...
>     </web-services>

3. Use the `<operation>` child element of the `<operations>` element (which itself is a child of the `<web-service>` element) to specify that the handler chain is an operation of the Web Service. Follow one of the next two scenarios:

- The handler chain executes together with a back-end component, such as a stateless session EJB.

In this case use the `component`, `method`, and `handler-chain` attributes of the `<operation>` element, as shown in the following partial excerpt of a `web-services.xml` file:

>     <web-service>
>       <components>
>         <stateless-ejb name="myEJB">
>           ...
>         </stateless-ejb>
>       </components>
>       <operations>
>         <operation name="getQuote"
>                    method="getQuote"
>                    component="myEJB"
>                    handler-chain="myChain" />
>        </operations>
>     </web-service>

In the example, the request chain of the `myChain` handler chain executes first, then the `getQuote()` method of the `myEJB` stateless session EJB component, and finally the response chain of `myChain`.

- The handler chain executes on its own, without a back-end component.

In this case use only the handler-chain attribute of the `<operation>` element and explicitly do not specify the component or method attributes, as shown in the following excerpt:

>     <web-service>
>       <operations>
>         <operation name="chainService"
>                    handler-chain="myChain" />
>        </operations>
>     </web-service>

In the example, the Web Service consists solely of the `myChain` handler chain.

# Using SOAP Message Handlers and Handler Chains in a Client Application

Most of this chapter describes how to create SOAP message handlers in a handler chain that execute as part of the Web Service running on WebLogic Server. You can also create handlers that execute in a client application. In the case of a client-side handler, the handler executes twice when a client application invokes a Web Service:

- directly before the client application sends the SOAP request to the Web Service
- directly after the client application receives the SOAP response from the Web Service

You create a client-side handler in the same way you create a server-side handler: write a Java class that implements the `javax.rpc.xml.handler.Handler` interface. In many cases you can use the exact same handler class on both the Web Service running on WebLogic Server and the client applications that invoke the Web Service. For example, you can write a generic logging handler class that logs all sent and received SOAP messages, both for the server and for the client. For details about writing the handler Java class, see Implementing the Handler Interface.

After you have created your client-side handler class, the process for registering the handler on the client application is different from that of the server. Because client applications do not have deployment descriptors, you must register the handler programmatically using the j`avax.xml.rpc.handler.HandlerInfo` and `javax.xml.rpc.handler.HandlerRegistry` classes. The following sample client application shows how to do this, with relevant sections in bold discussed after the example:

>     import java.util.ArrayList;

>     import java.io.IOException;

>     import javax.xml.namespace.QName;

>     import javax.xml.rpc.ServiceException;

>     import javax.xml.rpc.handler.HandlerInfo;
>     import javax.xml.rpc.handler.HandlerRegistry;

>     public class Main{

>       public static void main( String[] args ){

>         if( args.length == 1 ){
>           new Main( args[0] );
>         }else{
>           throw new IllegalArgumentException( "URL of the service not specified" );
>         }
>       }

>       public Main( String wsdlUrl ){
>         try{

>           HelloWorldService service = new HelloWorldService_Impl( wsdlUrl );
>           HelloWorldServicePort port = service.getHelloWorldServicePort();

>           QName portName = new QName( "http://tutorial/sample4/",
>             "HelloWorldServicePort");

>           HandlerRegistry registry = service.getHandlerRegistry();

>           List handlerList = new ArrayList();
>           handlerList.add( new HandlerInfo( ClientHandler.class, null, null ) );

>           registry.setHandlerChain( portName, handlerList );

>           System.out.println( port.helloWorld() );
>         }catch( IOException e ){
>           System.out.println( "Failed to create web service client:" + e );
>         }catch( ServiceException e ){
>           System.out.println( "Failed to create web service client:" + e );
>         }
>       }
>     }

The main points to notice about the example are as follows:

- Import the JAX-RPC `HandlerInfo` and `HandlerRegistry` classes which will be used to register the client-side handler class:

>     import javax.xml.rpc.handler.HandlerInfo;
>     import javax.xml.rpc.handler.HandlerRegistry;

- Create a `QName` object that contains the qualified name of the Web Service port:

>      QName portName = new QName( "http://tutorial/sample4/",
>             "HelloWorldServicePort");

Refer to the WSDL of the Web Service you are invoking for the name of the port and its namespace.

- Create a `HandlerRegistry` object:

>     HandlerRegistry registry = service.getHandlerRegistry();

- Create a `List` object that contains a list of the handlers you want to register. This list becomes the client-side handler chain. Use the `HandlerInfo` class to specify the name of your Java handler class:

>     List handlerList = new ArrayList();
>     handlerList.add( new HandlerInfo( ClientHandler.class, null, null ) );

In the example, the handler chain consists of just one handler: `ClientHandler.class`. You can, however, create a handler chain of as many handlers as you want.

Warning: The order in which you add the handlers to the `List` object specifies the order in which the handlers are executed in the client application. For example, if you want `HandlerA.class` to execute first and then `HandlerB.class`, be sure you add `HandlerA.class` to the list before `HandlerB.class`.

- Register the handler chain with the client application using the `HandlerRegistry.setHandlerChain()` method:

>     registry.setHandlerChain( portName, handlerList );

# Accessing the MessageContext of a Handler From the Backend Component

When you create a handler by implementing the `Handler` interface, you can set properties of the `MessageContext` object in one of the handler methods (such as `handleRequest()`), by using the `MessageContext.setProperty()` method. To access these properties from the backend component that is invoked after the handler chain, you must use the `weblogic.webservice.context.WebServiceContext` API to get the `MessageContext`.

For example, the following code snippet shows an implementation of the `Handler.handleRequest()` method in which a user-defined property `TransID` is set for the `MessageContext` object:

>     import javax.xml.rpc.handler.MessageContext;

>      ...

>      public boolean handleRequest(MessageContext mc) {
>        try {
>           mc.setProperty("TransId", "AX123");
>        }
>        catch (Exception ex) {
>           System.out.println("exception from Handler: " + ex.getLocalizedMessage());
>        }

>        return true;
>     }

The following sample code from the Java class that implements the backend component shows how to access the `TransID` property using the `weblogic.webservice.context.WebServiceContext` API:

>     import javax.xml.rpc.handler.soap.SOAPMessageContext;
>     import javax.xml.rpc.handler.MessageContext;
>     import weblogic.webservice.context.WebServiceContext;

>      ...

>       public String someMethod(String s) {
>        try {
>           SOAPMessageContext soapMessageContext =
>              WebServiceContext.currentContext().getLastMessageContext();
>           String somePropery = (String)soapMessageContext.getProperty("TransId");
>           System.out.println("TransId =" + someProperty);

>        }
>        catch(Exception ex) {
>          System.out.println("exception from service: " + ex.getLocalizedMessage());
>        }

>        return s;
>       }