Skip navigation.

Programming Web Services for WebLogic Server

  Previous Next vertical dots separating previous/next from contents/index/pdf Contents View as PDF   Get Adobe Reader

Advanced JWS Programming: JMS Tranpsort and SOAP Message Handlers

The following sections provide information about the following advanced JWS programming topics:

 


Using JMS Transport as the Connection Protocol

Typically, client applications use HTTP/S as the connection protocol when invoking a WebLogic Web Service. You can, however, configure a WebLogic Web Service so that client applications use JMS as the transport instead. You configure transports using either JWS annotations or child elements of the jwsc Ant task, as described in later sections.

When a WebLogic Web Service is configured to use JMS as the connection transport, the endpoint address specified for the corresponding port in the generated WSDL of the Web Service uses jms:// in its URL rather than http://. An example of a JMS endpoint address is as follows:

jms://myHost:7001/transports/JMSTransport?URI=JMSTransportQueue

The URI=JMSTransportQueue section of the URL specifies the JMS queue that has been configured for the JMS transport feature. Although you cannot invoke the Web Service using HTTP, you can view its WSDL using HTTP, which is how the clientgen is still able to generate JAX-RPC stubs for the Web Service.

For each transport that you specify, WebLogic Server generates an additional port in the WSDL. For this reason, if you want to give client applications a choice of transports they can use when they invoke the Web Service (JMS, HTTP, or HTTPS), you should explicitly add the transports using the appropriate JWS annotations or child elements of jwsc.

Caution: Using JMS transport is an added-value WebLogic feature; non-WebLogic client applications, such as a .NET client, may not be able to invoke the Web Service using the JMS port.

Using JMS Transport: Main Steps

The following procedure describes how to specify that your Web Service can be invoked using the JMS transport.

It is assumed that you have already created a basic JWS file that implements a Web Service and that you want to configure the Web Service to be invoked using JMS. 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 targets for running the jwsc Ant task and deploying the service. For more information, see Iterative Development of WebLogic Web Services, and Programming the JWS File.

  1. Invoke the Administration Console in your browser, as described in Invoking the Administration Console.
  2. Using the Administration Console, create and configure the following JMS components, if they do not already exist:
  3. Except for the JNDI name of the JMS queue, you can name the other components anything you want.

  4. Add the @WLJmsTransport annotation to your JWS file.
  5. See Using the @WLJmsTransport JWS Annotation.

  6. Optionally add a <WLJmsTransport> child element to the jwsc Ant task if you want to override JMS ports from the one you specified in the preceding step.
  7. See Using the <WLJmsTransport> Child Element of the jwsc Ant Task for details.

  8. Rebuild your Web Service by re-running the target in the build.xml Ant file that calls the jwsc task.
  9. For example, if the target that calls the jwsc Ant task is called build-service, then you would run:

    prompt> ant build-service
  10. Redeploy your Web Service to WebLogic Server.

See Invoking a WebLogic Web Service Using JMS Transport for information about updating your client application to invoke the Web Service using JMS transport.

Using the @WLJmsTransport JWS Annotation

If you know at the time that you program the JWS file that you want client applications to use JMS transport (instead of HTTP/S) to invoke the Web Service, you can use the @WLJmsTransport to specify the details of the invoke. Later, at build-time, you can override the one in the JWS file and add additional JMS transport specifications, by specifying the <WLJmsTransport> child element of the jwsc Ant task, as described in Using the <WLJmsTransport> Child Element of the jwsc Ant Task.

Follow these guidelines when using the @WLJmsTranport annotation:

The following example shows a simple JWS file that uses the @WLJmsTransport annotation, with the relevant code in bold:

package examples.webservices.jmstransport;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import weblogic.jws.WLJmsTransport;
@WebService(name="JMSTransportPortType",
serviceName="JMSTransportService",
targetNamespace="http://example.org")
@SOAPBinding(style=SOAPBinding.Style.DOCUMENT,
use=SOAPBinding.Use.LITERAL,
parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
// WebLogic-specific JWS annotation that specifies the context path and
// service URI used to build the URI of the Web Service is
// "transports/JMSTransport"
@WLJmsTransport(contextPath="transports", serviceUri="JMSTransport",
queue="JMSTransportQueue", portName="JMSTransportServicePort")
/**
* This JWS file forms the basis of simple Java-class implemented WebLogic
* Web Service with a single operation: sayHello
*
* @author Copyright (c) 2005 by BEA Systems. All rights reserved.
*/
public class JMSTransportImpl {
  @WebMethod()
public String sayHello(String message) {
System.out.println("sayHello:" + message);
return "Here is the message: '" + message + "'";
}
}

Using the <WLJmsTransport> Child Element of the jwsc Ant Task

You can also specify the JMS transport at build-time by using the <WLJmsTransport> child element of the <jws> element of the jwsc Ant task. Reasons for specifying the transport at build-time include:

If you specify a transport to the jwsc Ant task, it takes precedence over any transport annotation in the JWS file.

The following example shows how to specify a transport to the jwsc Ant task:

  <target name="build-service">
    <jwsc
srcdir="src"
destdir="${ear-dir}">
<jws file="examples/webservices/jmstransport/JMSTransportImpl.java">
        <WLJmsTransport
contextPath="transports"
serviceUri="JMSTransport"
portName="JMSTransportServicePort"
queue="JMSTransportQueue"/>
      </jws>
    </jwsc>
  </target>

The preceding example shows how to specify the same values for the URL and JMS queue as were specified in the JWS file shown in Using the @WLJmsTransport JWS Annotation.

For more information about using the jwsc Ant task, see jwsc.

Invoking a WebLogic Web Service Using JMS Transport

You write a client application to invoke a Web Service using JMS transport in the same way as you write one using the HTTP transport; the only difference is that you must ensure that the JMS queue (specified by the @WLJmsTransport annotation or <WLJmsTransport> child element of the jwsc Ant task) and other JMS objects have already been created. See Using JMS Transport: Main Steps for more information.

Although you cannot invoke a JMS-transport-configured Web Service using HTTP, you can view its WSDL using HTTP, which is how the clientgen Ant task is still able to create the JAX-RPC stubs for the Web Service. For example, the URL for the WSDL of the Web Service shown in this section would be:

http://host:port/transports/JMSTransport?WSDL

However, because the endpoint address in the WSDL of the deployed Web Service uses jms:// instead of http://, and the address includes the qualifier ?URI=JMS_QUEUE, the clientgen Ant task automatically creates the stubs needed to use the JMS transport when invoking the Web Service, and your client application need not do anything different than normal. An example of a JMS endpoint address is as follows:

jms://host:port/transports/JMSTransport?URI=JMSTransportQueue

For general information about invoking a Web Service, see Invoking Web Services.

 


Creating and Using SOAP Message Handlers

Some Web Services need access to the SOAP message, for which you can create SOAP message handlers.

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 handlers in both the Web Service itself and the client applications that invoke the Web Service.

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.

The following table lists the standard JWS annotations that you can use in your JWS file to specify that a Web Service has a handler chain configured; later sections discuss how to use the annotations in more detail. For additional information, see the Web Services MetaData for the Java Platform (JSR-181) specification.

Table 7-1 JWS Annotations Used To Configure SOAP Message Handler Chains

JWS Annotation

Description

javax.jws.HandlerChain

Associates the Web Service with an externally defined handler chain. Use this annotation (rather than @SOAPMessageHandlers) when multiple Web Services need to share the same handler configuration, or if the handler chain consists of handlers for multiple transports.

javax.jws.soap.SOAPMessageHandlers

Specifies a list of SOAP handlers that run before and after the invocation of each Web Service operation. Use this annotation (rather than @HanderChain) if embedding handler configuration information in the JWS file itself is preferred, rather than having an external configuration file.

The @SOAPMessageHandler annotation is an array of @SOAPMessageHandlers. The handlers are executed in the order they are listed in this array.

javax.jws.soap.SOAPMessageHandler

Specifies a single SOAP message handler in the @SOAPMessageHandlers array.

The following table describes the main classes and interfaces of the javax.xml.rpc.handler API, some of which you use when creating the handler itself. These APIs are discussed in detail in a later section. For additional information about these APIs, see the JAX-RPC 1.1 specification.

Table 7-2 JAX-RPC Handler Interfaces and Classes

javax.xml.rpc.handler Classes and Interfaces

Description

Handler

Main interface that is implemented when creating a handler. Contains methods to handle the SOAP request, response, and faults.

GenericHandler

Abstract class that implements the Handler interface. User should extend this class when creating a handler, rather than implement Handler directly.

The GenericHandler class is a convenience abstract class that makes writing handlers easy. This class provides default implementations of the lifecycle methods init and destroy and also different handle methods. A handler developer should only override methods that it needs to specialize as part of the derived handler implementation class.

HandlerChain

Interface that represents a list of handlers. An implementation class for the HandlerChain interface abstracts the policy and mechanism for the invocation of the registered handlers.

HandlerRegistry

Interface that provides support for the programmatic configuration of handlers in a HandlerRegistry.

HandlerInfo

Class that contains information about the handler in a handler chain. A HandlerInfo instance is passed in the Handler.init method to initialize a Handler instance.

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.

Adding SOAP Message Handlers to a Web Service: 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 already 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 Iterative Development of WebLogic Web Services, and Programming the JWS File.

  1. Design the handlers and handler chains.
  2. See Designing the SOAP Message Handlers and Handler Chains.

  3. For each handler in the handler chain, create a Java class that extends the javax.xml.rpc.handler.GenericHandler abstract class.
  4. See Creating the GenericHandler Class.

  5. Update your JWS file, adding annotations to configure the SOAP message handlers.
  6. See Configuring Handlers in the JWS File.

  7. If you are using the @HandlerChain standard annotation in your JWS file, create the handler chain configuration file.
  8. See Creating the Handler Chain Configuration File.

  9. Compile all handler classes in the handler chain and rebuild your Web Service.
  10. See Compiling and Rebuilding the Web Service.

For information about creating client-side SOAP message handlers and handler chains, see Creating and Using Client-Side SOAP Message Handlers.

Designing the SOAP Message Handlers and Handler Chains

When designing your SOAP message handlers and handler chains, you must decide:

Each handler in a handler chain has one method for handling the request SOAP message and another method for handling the response SOAP message. An ordered group of handlers is referred to as a handler chain. You specify that a Web Service has a handler chain attached to it with one of two JWS annotations: @HandlerChain or @SOAPMessageHandler. When to use which is discussed in a later section.

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 by the JWS annotation. 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.
  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 by the JWS annotation. 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 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:

<jwshc:handler-config xmlns:jwshc="http://www.bea.com/xml/ns/jws"
xmlns:soap1="http://HandlerInfo.org/Server1"
xmlns:soap2="http://HandlerInfo.org/Server2"
xmlns="http://java.sun.com/xml/ns/j2ee" >
   <jwshc:handler-chain>
     <jwshc:handler-chain-name>SimpleChain</jwshc:handler-chain-name>
     <jwshc:handler>
<handler-name>handlerOne</handler-name>
<handler-class>examples.webservices.soap_handlers.global_handler.ServerHandler1</handler-class>
</jwshc:handler>
     <jwshc:handler>
<handler-name>handlerTwo</handler-name>
<handler-class>examples.webservices.soap_handlers.global_handler.ServerHandler2</handler-class>
</jwshc:handler>
     <jwshc:handler>
<handler-name>handlerThree</handler-name>
<handler-class>examples.webservices.soap_handlers.global_handler.ServerHandler3</handler-class>
</jwshc:handler>
   </jwshc:handler-chain>
</jwshc:handler-config>

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

Figure 7-1 Order of Execution of Handler Methods0

Order of Execution of Handler Methods0


 

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 for the the inbound and outbound message. 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.

Creating the GenericHandler Class

Your SOAP message handler class should extend the javax.rpc.xml.handler.GenericHandler abstract class, which itself implements the javax.rpc.xml.handler.Handler interface.

The GenericHandler class is a convenience abstract class that makes writing handlers easy. This class provides default implementations of the lifecycle methods init() and destroy() and the various handleXXX() methods of the Handler interface. When you write your handler class, only override those methods that you need to customize as part of your Handler implementation class.

In particular, the Handler interface contains the following methods that you can implement in your handler class that extends GenericHandler:

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 to the WebLogic Server log file:

package examples.webservices.soap_handlers.global_handler;
import javax.xml.namespace.QName;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.GenericHandler;
import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.rpc.JAXRPCException;
import weblogic.logging.NonCatalogLogger;
/**
* This class implements a handler in the handler chain, used to access the SOAP
* request and response message.
* <p>
* This class extends the <code>javax.xml.rpc.handler.GenericHandler</code>
* abstract classs and simply prints the SOAP request and response messages to
* the server log file before the messages are processed by the backend
* Java class that implements the Web Service itself.
*/
public class ServerHandler1 extends GenericHandler {
  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;
  }
  /**
* Specifies that the SOAP request message be logged to a log file before the
* message is sent to the Java class that implements the Web Service.
*/
  public boolean handleRequest(MessageContext context) {
   SOAPMessageContext messageContext = (SOAPMessageContext) context;
   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 context) {
    SOAPMessageContext messageContext = (SOAPMessageContext) context;
    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 context) {
   SOAPMessageContext messageContext = (SOAPMessageContext) context;
   System.out.println("** Fault: "+messageContext.getMessage().toString());
log.info(messageContext.getMessage().toString());
return true;
  }
  public QName[] getHeaders() {
    return handlerInfo.getHeaders();
  }
}

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. Use the HandlerInfo.getHandlerConfig() method to get the parameters; the method returns a java.util.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 that can be 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,SOAPFaultException {}

Implement this method to perform such tasks as decrypting data in the SOAP message before it is processed by the back-end component, 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:

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

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 perform such tasks as encrypting 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:

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

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:

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

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

Caution: 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:

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:

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 Handlers in the JWS File

There are two standard annotations you can use in your JWS file to configure a handler chain for a Web Service: @javax.jws.HandlerChain and @javax.jws.soap.SOAPMessageHandlers.

@javax.jws.HandlerChain

When you use the @javax.jws.HandlerChain annotation (also called @HandlerChain in this chapter for simplicity) you 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.

Use the @HandlerChain annotation, rather than the @SOAPMessageHandlers annotation, in your JWS file if one or more of the following conditions apply:

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

package examples.webservices.soap_handlers.global_handler;
import java.io.Serializable;
import javax.jws.HandlerChain;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;
import weblogic.jws.WLHttpTransport;
@WebService(serviceName="HandlerChainService",
name="HandlerChainPortType")
// Standard JWS annotation that specifies that the handler chain called
// "SimpleChain", configured in the HandlerConfig.xml file, should fire
// each time an operation of the Web Service is invoked.
@HandlerChain(file="HandlerConfig.xml", name="SimpleChain")
@SOAPBinding(style=SOAPBinding.Style.DOCUMENT,
use=SOAPBinding.Use.LITERAL,
parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
@WLHttpTransport(contextPath="HandlerChain", serviceUri="HandlerChain",
portName="HandlerChainServicePort")
/**
* This JWS file forms the basis of simple Java-class implemented WebLogic
* Web Service with a single operation: sayHello. The Web Service also
* has a handler chain associated with it, as specified by the
* @HandlerChain annotation.
* <p>
* @author Copyright (c) 2005 by BEA Systems, Inc. All Rights Reserved.
*/
public class HandlerChainImpl  {
   public String sayHello(String input) {
weblogic.utils.Debug.say( "in backend component. input:" +input );
return "'" + input + "' to you too!";
}
}

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

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.

Use the name attribute to specify the name of the handler chain in the configuration file that you want to associate with the Web Service. The value of this attribute corresponds to the name attribute of the <handler-chain> element in the configuration file.

Warning: It is an error to specify more than one @HandlerChain annotation in a single JWS file. It is also an error to combine the @HandlerChain annotation with the @SOAPMessageHandlers annotation.

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.

@javax.jws.soap.SOAPMessageHandlers

When you use the @javax.jws.soap.SOAPMessageHandlers (also called @SOAPMessageHandlers in this section for simplicity) annotation, you specify, within the JWS file itself, an array of SOAP message handlers (specified with the @SOAPMessageHandler annotation) that execute before and after the operations of a Web Service. The @SOAPMessageHandler annotation includes attributes to specify the class name of the handler, the initialization parameters, list of SOAP headers processed by the handler, and so on. Because you specify the list of handlers within the JWS file itself, the configuration of the handler chain is embedded within the Web Service.

Use the @SOAPMessageHandlers annotation if one or more of the following conditions apply:

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

package examples.webservices.soap_handlers.simple;
import java.io.Serializable;
import javax.jws.soap.SOAPMessageHandlers;
import javax.jws.soap.SOAPMessageHandler;
import javax.jws.soap.SOAPBinding;
import javax.jws.WebService;
import javax.jws.WebMethod;
import weblogic.jws.WLHttpTransport;
@WebService(name="SimpleChainPortType",  
serviceName="SimpleChainService")
// Standard JWS annotation that specifies a list of SOAP message handlers
// that exeucte before and after an invocation of all operations in the
// Web Serice.
@SOAPMessageHandlers ( {
@SOAPMessageHandler (
className="examples.webservices.soap_handlers.simple.ServerHandler1"),
@SOAPMessageHandler (
className="examples.webservices.soap_handlers.simple.ServerHandler2")
} )
@SOAPBinding(style=SOAPBinding.Style.DOCUMENT,
use=SOAPBinding.Use.LITERAL,
parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
@WLHttpTransport(contextPath="SimpleChain", serviceUri="SimpleChain",
portName="SimpleChainServicePort")
/**
* This JWS file forms the basis of simple Java-class implemented WebLogic
* Web Service with a single operation: sayHello. The Web Service also
* has a handler chain associated with it, as specified by the
* @SOAPMessageHandler/s annotations.
* <p>
* @author Copyright (c) 2005 by BEA Systems, Inc. All Rights Reserved.
*/
public class SimpleChainImpl  {
   // by default all public methods are exposed as operations
   public String sayHello(String input)  {
weblogic.utils.Debug.say( "in backend component. input:" +input );
return "'" + input + "' to you too!";
}
}

Before you use the @SOAPMessageHandlers and @SOAPMessageHandler annotations, you must import them into your JWS file, as shown in the preceding example. Note that these annotations are in the javax.jws.soap package.

The order in which you list the handlers (using the @SOAPMessageHandler annotation) in the @SOAPMessageHandlers array specifies the order in which the handlers execute: in forward order before the operation, and in reverse order after the operation. The preceding example configures two handlers in the handler chain, whose class names are examples.webservices.soap_handlers.simple.ServerHandler1 and examples.webservices.soap_handlers.simple.ServerHandler2.

Use the initParams attribute of @SOAPMessageHandler to specify an array of initialization parameters expected by a particular handler. Use the @InitParam standard JWS annotation to specify the name/value pairs, as shown in the following example:

@SOAPMessageHandler(
className = "examples.webservices.soap_handlers.simple.ServerHandler1",
initParams = { @InitParam(name="logCategory", value="MyService")}
)

The @SOAPMessageHandler annotation also includes the roles attribute for listing the SOAP roles implemented by the handler, and the headers attribute for listing the SOAP headers processed by the handler.

Warning: It is an error to combine the @SOAPMessageHandlers annotation with the @HandlerChain annotation.

For additional detailed information about the standard JWS annotations discussed in this section, see the Web Services Metadata for the Java Platform specification.

Creating the Handler Chain Configuration File

If you decide to use the @HandlerChain annotation in your JWS file to associate a handler chain with a Web Service, you must create 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. Finally, if you include handlers in your handler chain that use a non-SOAP transport, then you are required to use the @HandlerChain annotation rather than the @SOAPMessageHandler annotation.

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

<jwshc:handler-config xmlns:jwshc="http://www.bea.com/xml/ns/jws"
xmlns:soap1="http://HandlerInfo.org/Server1"
xmlns:soap2="http://HandlerInfo.org/Server2"
xmlns="http://java.sun.com/xml/ns/j2ee" >
<jwshc:handler-chain>
<jwshc:handler-chain-name>SimpleChain</jwshc:handler-chain-name>
<jwshc:handler>
<handler-name>handler1</handler-name>
<handler-class>examples.webservices.soap_handlers.global_handler.ServerHandler1</handler-class>
</jwshc:handler>
<jwshc:handler>
<handler-name>handler2</handler-name>
<handler-class>examples.webservices.soap_handlers.global_handler.ServerHandler2</handler-class>
</jwshc:handler>
</jwshc:handler-chain>
</jwshc:handler-config>

In the example, the handler chain called SimpleChain contains two handlers: handler1 and handler2, 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>, <soap-role>, and <soap-header> child elements of the <handler> element to specify the handler initialization parameters, SOAP roles implemented by the handler, and SOAP headers processed by the handler, respectively.

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.

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 Iterative Development of WebLogic Web Services, for information on creating this build.xml file.

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

 

Skip navigation bar  Back to Top Previous Next