Skip Headers
Oracle® Fusion Middleware Programming Advanced Features of JAX-WS Web Services for Oracle WebLogic Server
11g Release 1 (10.3.6)

Part Number E13734-06
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
PDF · Mobi · ePub

17 Creating and Using SOAP Message Handlers

This chapter describes how to create and use SOAP message handlers for WebLogic Web services using Java API for XML Web Services (JAX-WS).

This chapter includes the following sections:

Overview of SOAP Message Handlers

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

A simple example of using handlers is to access information in the header part of the SOAP message. You can use the SOAP header to store Web service specific information and then use handlers to manipulate it.

You can also use SOAP message handlers to improve the performance of your Web service. After your Web service has been deployed for a while, 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.

JAX-WS supports two types of SOAP message handlers: SOAP handlers and logical handlers. SOAP handlers can access the entire SOAP message, including the message headers and body. Logical handlers can access the payload of the message only, and cannot change any protocol-specific information (like headers) in a message.

Note:

If SOAP handlers are used in conjunction with policies (security, WS-ReliableMessaging, MTOM, and so on), for inbound messages, the policy interceptors are executed before the user-defined message handlers. For outbound messages, this order is reversed.

Adding Server-side SOAP Message Handlers: Main Steps

The following procedure describes the high-level steps to add SOAP message handlers to your Web service.

It is assumed that you have created a basic JWS file that implements a Web service and that you want to update the Web service by adding SOAP message handlers and handler chains. It is also assumed that you have set up an Ant-based development environment and that you have a working build.xml file that includes a target for running the jwsc Ant task. For more information, see in Getting Started With JAX-WS Web Services for Oracle WebLogic Server:

Table 17-1 Steps to Add SOAP Message Handlers to a Web Service

#
Step Description

1

Design the handlers and handler chains.

Design SOAP message handlers and group them together in a handler chain. See Designing the SOAP Message Handlers and Handler Chains.

2

For each handler in the handler chain, create a Java class that implements the SOAP message handler interface.

See Creating the SOAP Message Handler.

3

Update your JWS file, adding annotations to configure the SOAP message handlers.

See Configuring Handler Chains in the JWS File.

4

Create the handler chain configuration file.

See Creating the Handler Chain Configuration File.

5

Compile all handler classes in the handler chain and rebuild your Web service.

See Compiling and Rebuilding the Web Service.


Adding Client-side SOAP Message Handlers: Main Steps

You can configure client-side SOAP message handlers for both stand-alone clients and clients that run inside of WebLogic Server. You create the actual Java client-side handler in the same way you create a server-side handler (by creating a Java class that implements the SOAP message 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.

The following procedure describes the high-level steps to add client-side SOAP message handlers to the client application that invokes a Web service operation.

It is assumed that you have created the client application that invokes a deployed Web service, and that you want to update the client application by adding client-side SOAP message handlers and handler chains. It is also assumed that you have set up an Ant-based development environment and that you have a working build.xml file that includes a target for running the clientgen Ant task. For more information, see "Invoking a Web service from a Stand-alone Client: Main Steps" in Getting Started With JAX-WS Web Services for Oracle WebLogic Server.

Table 17-2 Steps to Add SOAP Message Handlers to a Web Service Client

#
Step Description

1

Design the handlers and handler chains.

This step is similar to designing the server-side SOAP message handlers, except the perspective is from the client application, rather than a Web service. See Designing the SOAP Message Handlers and Handler Chains.

2

For each handler in the handler chain, create a Java class that implements the SOAP message handler interface.

This step is similar to designing the server-side SOAP message handlers, except the perspective is from the client application, rather than a Web service. See Creating the SOAP Message Handler for details about programming a handler class.

3

Update your client to programmatically configure the SOAP message handlers.

See Configuring the Client-side SOAP Message Handlers.

4

Update the build.xml file that builds your application, specifying to the clientgen Ant task the customization file.

See Compiling and Rebuilding the Web Service.

5

Rebuild your client application by running the relevant task.

prompt> ant build-client

When you next run the client application, the SOAP messaging handlers listed in the configuration file automatically execute before the SOAP request message is sent and after the response is received.

Note:

You do not have to update your actual client application to invoke the client-side SOAP message handlers; as long as you specify to the clientgen Ant task the handler configuration file, the generated interface automatically takes care of executing the handlers in the correct sequence.

Designing the SOAP Message Handlers and Handler Chains

When designing your SOAP message handlers, you must decide:

You group SOAP message handlers together in a handler chain. Each handler in a handler chain may define methods for both inbound and outbound messages.

Typically, each SOAP message handler defines a separate set of steps to process the request and response SOAP message because the same type of processing typically must happen for the inbound and outbound message. You can, however, design a handler that processes 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.

Server-side Handler Execution

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

  1. The inbound methods for handlers in the handler chain are all executed in the order specified by the JWS annotation. Any of these inbound methods might change the SOAP message request.

  2. When 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.

  3. When the back-end component has finished executing, the outbound methods of the handlers in the handler chain are executed in the reverse order specified by the JWS annotation. Any of these outbound methods might change the SOAP message response.

  4. When 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 are going to use the @HandlerChain JWS annotation in your JWS file to specify an external configuration file, and the configuration file defines a handler chain called SimpleChain that contains three handlers, as shown in the following sample:

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

The following graphic shows the order in which WebLogic Server executes the inbound and outbound methods of each handler.

Figure 17-1 Order of Execution of Handler Methods

Description of Figure 17-1 follows
Description of "Figure 17-1 Order of Execution of Handler Methods"

Client-side Handler Execution

In the case of a client-side handler, the handler executes twice:

  • 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

Creating the SOAP Message Handler

There are two types of SOAP message handlers that you can create, as defined in the following table.

Table 17-3 Types of SOAP Message Handlers

Handler Type Description

SOAP handler

Enables you to access the full SOAP message including headers. SOAP handlers are defined using the javax.xml.ws.handler.soap.SOAPHandler interface. They are invoked using the import javax.xml.ws.handler.soap.SOAPMessageContext which extends javax.xml.ws.handler.MessageContext The SOAPMessageContext.getMessage() method returns a javax.xml.soap.SOAPMessage.

Logical handlers

Provides access to the payload of the message. Logical handlers cannot change any protocol-specific information (like headers) in a message. Logical handlers are defined using the javax.xml.ws.handler.LogicalHandler interface (see http://docs.oracle.com/javaee/5/api/javax/xml/ws/handler/LogicalHandler.html). They are invoked using the javax.xml.ws.handler.LogicalMessageContext which extends javax.xml.ws.handler.MessageContext The LogicalMessageContext.getMessage() method returns a javax.xml.ws.LogicalMessage.

The payload can be accessed either as a JAXB object or as a javax.xml.transform.Source object (see http://download.oracle.com/javaee/5/api/javax/xml/ws/LogicalMessage.html).


Each type of message handler extends the javax.xml.ws.Handler interface (see http://download.oracle.com/javaee/5/api/javax/xml/ws/handler/Handler.html), which defines the methods defined in the following table.

Table 17-4 Handler Interface Methods

Method Description
handleMessage()

Manages normal processing of inbound and outbound messages. A property in the MessageContext object is used to determine if the message is inbound or outbound. See Implementing the Handler.handleMessage() Method.

handleFault()

Manages fault processing of inbound and outbound messages. See Implementing the Handler.handleFault() Method.

close()

Concludes the message exchange and cleans up resources that were accessed during processing. See Implementing the Handler.close() Method.


In addition, you can use the @javax.annotation.PostConstruct and @javax.annotation.PreDestroy annotations to identify methods that must be executed after the handler is created and before the handler is destroyed, respectively.

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 at http://java.net/projects/saaj/ For details, see Directly Manipulating the SOAP Request and Response Message Using SAAJ.

Example of a SOAP Handler

The following example illustrates a simple SOAP handler that returns whether the message is inbound or outbound along with the message content.

package examples.webservices.handler;

import java.util.Set;
import java.util.Collections;
import javax.xml.namespace.QName;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.soap.SOAPMessage;

public class Handler1 implements SOAPHandler<SOAPMessageContext>
{
  public Set<QName> getHeaders()
  {
    return Collections.emptySet();
  }

  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;
  }

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

  public void close(MessageContext messageContext)
  {
  }
}

Example of a Logical Handler

The following example illustrates a simple logical handler that returns whether the message is inbound or outbound along with the message content.

package examples.webservices.handler;

import java.util.Set;
import java.util.Collections;
import javax.xml.namespace.QName;
import javax.xml.ws.handler.LogicalHandler;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.LogicalMessageContext;
import javax.xml.ws.LogicalMessage;
import javax.xml.transform.Source;

public class Handler2 implements LogicalHandler<LogicalMessageContext>
{
  public Set<QName> getHeaders()
  {
    return Collections.emptySet();
  }

  public boolean handleMessage(LogicalMessageContext 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;
  }

  public boolean handleFault(LogicalMessageContext messageContext)
  {
    return true;
  }

  public void close(MessageContext messageContext)
  {
  }
}

Implementing the Handler.handleMessage() Method

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

public boolean handleMessage(C context) 
  throws java.lang.RuntimeException, java.xml.ws.ProtocolException {}

Implement this method to perform such tasks as encrypting/decrypting data in the SOAP message before or after it is processed by the back-end component, and so on.

C extends javax.xml.ws.handler.MessageContext (see http://download.oracle.com/javaee/5/api/javax/xml/ws/handler/MessageContext.html). The MessageContext properties allow the handlers in a handler chain to determine if a message is inbound or outbound and to share processing state. Use the SOAPMessageContext or LogicalMessageContext sub-interface of MessageContext to get or set the contents of the SOAP or logical message, respectively. For more information, see Using the Message Context Property Values and Methods.

After you code all the processing of the SOAP message, code one of the following scenarios:

  • 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 configuration file specified by the @HandlerChain annotation.

  • 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.

  • Throw the java.lang.RuntimeException or java.xml.ws.ProtocolException for any handler-specific runtime errors.

    WebLogic Server catches the exception, terminates further processing of the handler request chain, logs the exception to the WebLogic Server log file, 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(C context) 
  throws java.lang.RuntimeException, java.xml.ws.ProtocolException{}

Implement this method to handle processing of any SOAP faults generated by the handleMessage() method, as well as faults generated by the back-end component.

C extends javax.xml.ws.handler.MessageContext (see http://download.oracle.com/javaee/5/api/javax/xml/ws/handler/MessageContext.html). The MessageContext properties allow the handlers in a handler chain to determine if a message is inbound or outbound and to share processing state.Use the LogicalMessageContext or SOAPMessageContext sub-interface of MessageContext to get or set the contents of the logical or SOAP message, respectively. For more information, see Using the Message Context Property Values and Methods.

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.

Implementing the Handler.close() Method

The Handler.close() method concludes the message exchange and cleans up resources that were accessed during processing. Its signature is:

public boolean close(MessageContext context) {}

Using the Message Context Property Values and Methods

The following context objects are passed to the SOAP message handlers.

Table 17-5 Message Context Property Values

Message Context Property Values Description
javax.xml.ws.handler.LogicalMessageContext

Context object for logical handlers.

javax.xml.ws.handler.soap.SOAPMessageContext

Context object for SOAP handlers.


Each context object extends javax.xml.ws.handler.MessageContext, which enables you to access a set of runtime properties of a SOAP message handler from the client application or Web service, or directly from the javax.xml.ws.WebServiceContext from a Web service (see http://docs.oracle.com/javaee/5/api/javax/xml/ws/WebServiceContext.html).

For example, the MessageContext.MESSAGE_OUTBOUND_PROPERTY holds a Boolean value that is used to determine the direction of a message. During a request, you can check the value of this property to determine if the message is an inbound or outbound request. The property would be true when accessed by a client-side handler or false when accessed by a server-side handler.

For more information about the MessageContext property values that are available, see "Using the MessageContext Property Values" in Getting Started With JAX-WS Web Services for Oracle WebLogic Server.

The LogicalMessageContext class defines the following method for processing the Logical message. For more information, see the java.xml.ws.handler.LogicalMessageContext Javadoc at http://download.oracle.com/javaee/5/api/javax/xml/ws/handler/LogicalMessageContext.html.

Table 17-6 LogicalMessageContext Class Method

Method Description
getMessage()

Gets a javax.xml.ws.LogicalMessage object that contains the SOAP message.


The SOAPMessageContext class defines the following methods for processing the SOAP message. For more information, see the java.xml.ws.handler.soap.SOAPMessageContext Javadoc at http://download.oracle.com/javaee/5/api/javax/xml/ws/handler/soap/SOAPMessageContext.html.

Note:

The SOAP message itself is stored in a javax.xml.soap.SOAPMessage object at http://download.oracle.com/javaee/5/api/javax/xml/soap/SOAPMessage.html. For detailed information on this object, see Directly Manipulating the SOAP Request and Response Message Using SAAJ.

Table 17-7 SOAPMessageContext Class Methods

Method Description
getHeaders()

Gets headers that have a particular qualified name from the message in the message context.

getMessage()

Gets a javax.xml.soap.SOAPMessage object that contains the SOAP message.

getRoles()

Gets the SOAP actor roles associated with an execution of the handler chain.

setMessage()

Sets the SOAP message.


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 at http://java.net/projects/saaj/. 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.

The SOAPPart Object

Note:

The setContent and getContent methods of the SOAPPart object support javax.xml.transform.stream.StreamSource content only; the methods do not support javax.xml.transform.dom.DOMSource content.

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.getMessage();
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 (see http://download.oracle.com/javaee/5/api/javax/xml/soap/AttachmentPart.html) 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.

Note:

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. For more information, see the javax.xml.soap.SOAPMessage Javadoc at http://download.oracle.com/javaee/5/api/javax/xml/soap/SOAPMessage.html.

Table 17-8 SOAPMessage Class Methods to Manipulate Attachments

Method Description
addAttachmentPart()

Adds an AttachmentPart object, after it has been created, to the SOAPMessage.

countAttachments()

Returns the number of attachments in this SOAP message.

createAttachmentPart()

Create an AttachmentPart object from another type of Object.

getAttachments()

Gets all the attachments (as AttachmentPart objects) into an Iterator object.


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-WS ports 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.

Configuring Handler Chains in the JWS File

The @javax.jws.HandlerChain annotation (also called @HandlerChain in this chapter for simplicity) enables you to configure a handler chain for a Web service. Use the file attribute to specify an external file that contains the configuration of the handler chain you want to associate with the Web service. The configuration includes the list of handlers in the chain, the order in which they execute, the initialization parameters, and so on.

The following JWS file shows an example of using the @HandlerChain annotation; the relevant Java code is shown in bold:

package examples.webservices.handler;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.HandlerChain; 
import javax.annotation.Resource;
import javax.xml.ws.WebServiceContext;
@WebService(name = "Handler", targetNamespace = "http://example.org")
@HandlerChain(file="handler-chain.xml") 
public class HandlerWS
{
  @Resource
  WebServiceContext ctx;
  @WebMethod()
  public String getProperty(String propertyName)
  {
    return (String) ctx.getMessageContext().get(propertyName);
  }
}

Before you use the @HandlerChain annotation, you must import it into your JWS file, as shown above.

Use the file attribute of the @HandlerChain annotation to specify the name of the external file that contains configuration information for the handler chain. The value of this attribute is a URL, which may be relative or absolute. Relative URLs are relative to the location of the JWS file at the time you run the jwsc Ant task to compile the file.

Note:

It is an error to specify more than one @HandlerChain annotation in a single JWS file.

For details about creating the external configuration file, see Creating the Handler Chain Configuration File.

For additional detailed information about the standard JWS annotations discussed in this section, see the Web services Metadata for the Java Platform specification at http://www.jcp.org/en/jsr/detail?id=181.

Creating the Handler Chain Configuration File

As described in the previous section, you use the @HandlerChain annotation in your JWS file to associate a handler chain with a Web service. You must create the handler chain file that consists of an external configuration file that specifies the list of handlers in the handler chain, the order in which they execute, the initialization parameters, and so on.

Because this file is external to the JWS file, you can configure multiple Web services to use this single configuration file to standardize the handler configuration file for all Web services in your enterprise. Additionally, you can change the configuration of the handler chains without needing to recompile all your Web services.

The configuration file uses XML to list one or more handler chains, as shown in the following simple example:

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

In the example, the handler chain contains two handlers implemented with the class names specified with the <handler-class> element. The two handlers execute in forward order before the relevant Web service operation executes, and in reverse order after the operation executes.

Use the <init-param> and <soap-role>child elements of the <handler> element to specify the handler initialization parameters and SOAP roles implemented by the handler, respectively.

You can include logical and SOAP handlers in the same handler chain. At runtime, the handler chain is re-ordered so that all logical handlers are executed before SOAP handlers for an outbound message, and vice versa for an inbound message.

For the XML Schema that defines the external configuration file, additional information about creating it, and additional examples, see the Web services Metadata for the Java Platform specification at http://www.jcp.org/en/jsr/detail?id=181.

Compiling and Rebuilding the Web Service

It is assumed in this section that you have a working build.xml Ant file that compiles and builds your Web service, and you want to update the build file to include handler chain. See "Developing WebLogic Web Services" in Getting Started With JAX-WS Web Services for Oracle WebLogic Server for information on creating this build.xml file.

Follow these guidelines to update your development environment to include message handler compilation and building:

Configuring the Client-side SOAP Message Handlers

You configure client-side SOAP message handlers in one of the following ways: