![]() ![]() ![]() ![]() ![]() ![]() |
The following sections provide information about 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.
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.
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.
|
|
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:
See Designing the SOAP Message Handlers and Handler Chains.
javax.xml.rpc.handler.GenericHandler
abstract class. See Creating the GenericHandler Class.
See Configuring Handlers in the JWS File.
@HandlerChain
standard annotation in your JWS file, create the handler chain configuration file. See Creating the Handler Chain Configuration File.
For information about creating client-side SOAP message handlers and handler chains, see Creating and Using Client-Side SOAP Message Handlers.
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:
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.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. 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.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.
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 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.
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
:
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()
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();
}
}
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.
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.
The Handler.getHeaders()
method gets the header blocks that can be processed by this Handler
instance. Its signature is:
public QName[] getHeaders() {}
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:
true
.
The next handler on the request chain is specified as either the next <handler>
subelement of the <handler-chain>
element in the configuration file specified by the @HandlerChain
annotation, or the next @SOAPMessageHandler
in the array specified by the @SOAPMessageHandlers
annotation. 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.
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.
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.
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 log file, and invokes the handleFault()
method of this handler.
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:
true
.
The next response on the handler chain is specified as either the preceding <handler>
subelement of the <handler-chain>
element in the configuration file specified by the @HandlerChain
annotation, or the preceding @SOAPMessageHandler
in the array specified by the @SOAPMessageHandlers
annotation. (Remember that responses on the handler chain execute in the reverse order that they are specified in the JWS 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.
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.
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.
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:
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 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 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:
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
.
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.
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
.
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.
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.SOAPBinding;
import javax.jws.soap.SOAPMessageHandler;
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.
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.
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:
@HandlerChain
or @SOAPMessageHandlers
annotation, you must rerun the jwsc
Ant task to recompile the JWS file and generate a new Web Service. This is true anytime you make a change to an annotation in the JWS file.
If you used the @HandlerChain
annotation in your JWS file, reran the jwsc
Ant task to regenerate the Web Service, and subsequently changed only the external configuration file, you do not need to rerun jwsc
for the second change to take affect.
jwsc
Ant task compiles SOAP message handler Java files into handler classes (and then packages them into the generated application) if all the following conditions are true:@HandlerChain
or @SOAPMessageHandler(s)
annotations of the JWS file.sourcepath
attribute.
If you want to compile the handler classes yourself, rather than let jwsc
compile them automatically, ensure that the compiled classes are in your CLASSPATH before you run the jwsc
Ant task.
The preceding sections describe how to create server-side SOAP message handlers that execute as part of the Web Service running on WebLogic Server. You can also create client-side handlers that execute as part of the client application that invokes a Web Service operation. In the case of a client-side handler, the handler executes twice:
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: write a Java class that extends the javax.xml.rpc.handler.GenericHandler
abstract class. 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.
Similar to the server-side SOAP handler programming, you use an XML file to specify to the clientgen
Ant task that you want to invoke client-side SOAP message handlers. However, the XML Schema of this XML file is slightly different, as described in the following procedure.
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 already 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.
See Designing the SOAP Message Handlers and Handler Chains.
javax.xml.rpc.handler.GenericHandler
abstract class. This step is very similar to the corresponding server-side step, except that the handler executes in a chain in the client rather than the server.See Creating the GenericHandler Class for details about programming a handler class. See Example of a Client-Side Handler Class for an example.
See Creating the Client-Side SOAP Handler Configuration File.
build.xml
file that builds your client application, specifying to the clientgen
Ant task the name of the SOAP handler configuration file. Also ensure that the build.xml
file compiles the handler files into Java classes and makes them available to your client application.See Specifying the Client-Side SOAP Handler Configuration File to clientgen.
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 JAX-RPC stubs automatically take care of executing the handlers in the correct sequence. |
The following example shows a simple SOAP message handler class that you can configure for a client application that invokes a Web Service.
package examples.webservices.client_handler.client;
import javax.xml.namespace.QName;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.GenericHandler;
import javax.xml.rpc.handler.MessageContext;
public class ClientHandler1 extends GenericHandler {
private QName[] headers;
public void init(HandlerInfo hi) {
System.out.println("in " + this.getClass() + " init()");
}
public boolean handleRequest(MessageContext context) {
System.out.println("in " + this.getClass() + " handleRequest()");
return true;
}
public boolean handleResponse(MessageContext context) {
System.out.println("in " + this.getClass() + " handleResponse()");
return true;
}
public boolean handleFault(MessageContext context) {
System.out.println("in " + this.getClass() + " handleFault()");
return true;
}
public QName[] getHeaders() {
return headers;
}
}
The client-side SOAP handler configuration file specifies the list of handlers in the handler chain, the order in which they execute, the initialization parameters, and so on. See XML Schema for the Client-Side Handler Configuration File for a full description of this file.
The configuration file uses XML to describe a single handler chain that contains one or more handlers, as shown in the following simple example:
<weblogic-wsee-clientHandlerChain
xmlns="http://www.bea.com/ns/weblogic/90"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:j2ee="http://java.sun.com/xml/ns/j2ee">
<handler>
<j2ee:handler-name>clienthandler1</j2ee:handler-name>
<j2ee:handler-class>examples.webservices.client_handler.client.ClientHandler1</j2ee:handler-class>
<j2ee:init-param>
<j2ee:param-name>ClientParam1</j2ee:param-name>
<j2ee:param-value>value1</j2ee:param-value>
</j2ee:init-param>
</handler>
<handler>
<j2ee:handler-name>clienthandler2</j2ee:handler-name>
<j2ee:handler-class>examples.webservices.client_handler.client.ClientHandler2</j2ee:handler-class>
</handler>
</weblogic-wsee-clientHandlerChain>
In the example, the handler chain contains two handlers: clienthandler1
and clienthandler2
, implemented with the class names specified with the <j2ee:handler-class>
element. The two handlers execute in forward order directly before the client application sends the SOAP request to the Web Service, and then in reverse order directly after the client application receives the SOAP response from the Web Service.
The example also shows how to use the <j2ee:init-param>
element to specify one or more initialization parameters to a handler.
Use the <soap-role>
, <soap-header>
, and <port-name>
child elements of the <handler>
element to specify the SOAP roles implemented by the handler, the SOAP headers processed by the handler, and the port-name element in the WSDL with which the handler is associated with, respectively.
The following XML Schema file defines the structure of the client-side SOAP handler configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<schema
targetNamespace="http://www.bea.com/ns/weblogic/90"
xmlns:wls="http://www.bea.com/ns/weblogic/90"
xmlns:j2ee="http://java.sun.com/xml/ns/j2ee"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
>
<include schemaLocation="weblogic-j2ee.xsd"/>
<element name="weblogic-wsee-clientHandlerChain"
type="wls:weblogic-wsee-clientHandlerChainType">
<xsd:key name="wsee-clienthandler-name-key">
<xsd:annotation>
<xsd:documentation>
Defines the name of the handler. The name must be unique within the
chain.
</xsd:documentation>
</xsd:annotation>
<xsd:selector xpath="j2ee:handler"/>
<xsd:field xpath="j2ee:handler-name"/>
</xsd:key>
</element>
<complexType name="weblogic-wsee-clientHandlerChainType">
<sequence>
<xsd:element name="handler"
type="j2ee:service-ref_handlerType"
minOccurs="0" maxOccurs="unbounded">
</xsd:element>
</sequence>
</complexType>
</schema>
A single configuration file specifies a single client-side handler chain. The root of the configuration file is <weblogic-wsee-clientHandlerChain>,
and the file contains zero or more <handler>
child elements, each of which describes a handler in the chain.
The structure of the <handler>
element is described by the J2EE service-ref_handlerType
complex type, specified in the
J2EE 1.4 Web Service client XML Schema.
Use the handlerChainFile
attribute of the clientgen
Ant task to specify the client-side SOAP handler configuration file, as shown in the following excerpt from a build.xml
file:
<clientgen
wsdl="http://ariel:7001/handlers/ClientHandlerService?WSDL"
destDir="${clientclass-dir}"
handlerChainFile="ClientHandlerChain.xml"
packageName="examples.webservices.client_handler.client"/>
The JAX-RPC stubs generated by clientgen
automatically ensure that the handlers described by the configuration file execute in the correct order before and after the client application invokes the Web Service operation
![]() ![]() ![]() |