C H A P T E R 4 |
Using Message Handlers |
This chapter provides an introduction to handlers and describes how the IDE supports the use of handlers with web services and clients.
A JAX-RPC message handler is a user-written class that can modify a SOAP message representing an RPC request or response. Handlers can be associated with a web service or a web service client. A handler has access to the body and header blocks of a message, but a handler does not have access to client or server application code. Handlers are normally designed to work with the header blocks and to supplement the processing done by web service or client application code.
A handler chain organizes handler classes so they execute in a designated sequence and can share data. When you add the first handler to a web service or client, the IDE automatically creates a handler chain. Any additional handlers become part of the same handler chain. There is at most one handler chain for a given web service or client.
Typical uses of handlers include:
For detailed information about how to code handlers, see Java API for XML-Based RPC (JAX-RPC) Specification 1.0: http://java.sun.com/xml/jaxrpc.
For detailed information about SOAP messages and headers, see the SOAP 1.1 specification: http://www.w3.org/TR/2000/NOTE-SOAP-20000508.
Note - This chapter should be read as an advanced topic. Most web services and clients do not require the use of handlers. |
The purpose of this section is to provide basic information about handlers so you can understand the handler features of the IDE, and to provide a lead-in to more detailed sources of information about handlers. If you are writing handler classes, you should also read the handler material in the JAX-RPC and SOAP specification documents.
SOAP headers are an extension to a SOAP message. Headers are typically used to support higher level functions such as security and auditing.
In a SOAP message XML document, the Header element, if present, is the first immediate child element of the SOAP Envelope element. The immediate child elements of the Header, if present, are called header entries or header blocks.
CODE EXAMPLE 4-1 shows a SOAP header with one header block. The actor and mustUnderstand attributes are explained later in this chapter.
A handler class can process SOAP messages representing RPC requests and RPC responses. The main processing is done by two methods:
public boolean handleRequest (MessageContext context) {...}
public boolean handleResponse (MessageContext context) {...}
A handleRequest or handleResponse method gets the parts of the SOAP message from the MessageContext parameter. This includes the envelope, header, header elements, body, and body elements. See CODE EXAMPLE 4-2 for sample code.
A handleRequest or handleResponse method can modify the headers or body of a message. The method can consume a header block (remove it from the message) or add a header block.
For example, a handleRequest or handleResponse method can write to an external log or audit file, or it can call routines to encrypt or decrypt the body of a message. A handler is not normally used to analyze or modify elements within the body of a message.
The action taken by a handleRequest or handleResponse method can depend on the content of the header or data in the body of the message, such as the name of the web service method in an RPC request or response.
There are four places in a client-service interaction where handlers can execute.
A single handler class can have both handleRequest and handleResponse methods.
See Sample Handler Code for an example of a handler with a handleRequest method.
Note - A JAX-RPC handler class is required to implement the interface javax.xml.rpc.handler.Handler interface. |
A handler chain for a given web service or client is illustrated schematically in CODE EXAMPLE 4-3:
The handler chain in the example has two handler classes, acme.MyHandler1 and acme.MyHandler2. The class acme.MyHandler1 is configured with three properties and two header blocks. Two SOAP actor roles are associated with the handler chain.
The uses of handler properties, header blocks, and SOAP actor roles are described in this chapter. The IDE manages handler chains for you. No coding is necessary.
You can use SOAP actor roles to ensure that designated header blocks are processed by handlers or by the ultimate destination (web service or client) of a message.
A SOAP actor is an attribute of a SOAP header block, typically used in conjunction with the mustUnderstand attribute, as illustrated in CODE EXAMPLE 4-1.
Suppose that a header block has the following attributes:
SOAP-ENV:mustUnderstand="1"
SOAP:actor="www.xyz.com/actor1"
If a SOAP message with this header block is processed by a handler chain that has the actor role "www.xyz.com/actor1", the header block must be consumed by one of the handlers in the handler chain or by the destination web service or client. If the header block is not consumed, the SOAP runtime throws an exception before any business method is called by the destination web service or client.
If the mustUnderstand attribute is omitted or has the value "0", the SOAP runtime does not enforce the consumption or use of the header block, regardless of any actor attribute in the header block.
The SOAP 1.1 specification explains that tagging elements with the attribute mustUnderstand="1" is intended to ensure that developers who might not understand the purpose of those elements will not erroneously ignore them. (Handlers might not be written by the same developers who design the SOAP message and its header blocks.)
A handler property can be used to configure a handler. The property and its value are passed to a handler instance at initialization time, through the HandleInfo parameter. CODE EXAMPLE 4-6 shows how a handler property might be used. The IDE enables you to add properties to a handler during development. (See Adding a Handler Property.)
Two different web services or clients might use the same handler, but with different property values, such as different log files or different encryption and decryption routines.
The action taken by a handler can depend on the header blocks passed in RPC requests and responses, including header blocks added to a message by other handlers executed earlier in the same handler chain. A handler might use some headers blocks and ignore others.
Note - Header blocks are the immediate child elements of the Header element (if present) in a SOAP message. See SOAP Message Headers and Header Blocks. |
When you add a handler to a web service or client, you can configure the handler to process certain header blocks. The IDE enables you to provide a list of header block names during the development of a web service or client. (See Adding a SOAP Header Block To a Handler.)
The header block names that you set in the IDE are passed to the handler in a parameter of type HandlerInfo. The code fragment in CODE EXAMPLE 4-4 shows how the handler can obtain the array of headers to process. The requestHandler or responseHandler method can iterate through the QName array to get the header block names.
A runtime SOAP message in an RPC request or response might have many header blocks. They are all available to the handler through a parameter of type Message Context in the handleRequest and handleResponse methods, as illustrated in CODE EXAMPLE 4-7. However, you can code the handler so that it only processes the header blocks whose names are gathered from the Handler Info parameter during initialization.
Handlers are not intended to be a major source of new headers, but there are some scenarios in which you must add a header block to a SOAP message. Suppose, for example, that you want a given header block to be processed by more than one handler or by a handler and the target web service or client. The problem is that if a handler consumes a header block, it is no longer part of the SOAP message. You can solve this problem by having your handler copy the header block before consuming it, add the copy to the SOAP message, and then pass the message up the chain.
The code fragment in CODE EXAMPLE 4-5 shows how to add a header block to a message. The header block must be a child element of a header element, so if the message does not already have a header element, the code adds one.
You can also add header elements to a SOAP message through WSDL code. See the WSDL 1.1 specification: http://www.w3.org/TR/wsdl#_soap:header.
The procedures in this section assumes that you have created a web service, a client, and handler classes in the IDE.
To add handler classes to a web service or client:
1. Right-click the web service or client node and choose Properties.
The SOAP Message Handlers properties shows the number of handlers currently associated with the web service, as illustrated in FIGURE 4-1.
2. Click the value of the Soap Message Handlers property, and click the ellipsis (...) button.
The IDE displays the SOAP Message Handlers dialog box, as illustrated in FIGURE 4-2. In this example two handler classes are already associated with the web service.
The SOAP Message Handlers dialog box provides several features to help you manage handlers and handler chains:
Each of these features is described in this chapter.
3. Click Add, select one or more desired handlers from the chooser, and click OK.
The selected handlers appear in the SOAP Message Handlers dialog box and become part of the handler chain for the web service or client.
To add a property and value to a handler:
1. Right-click the web service or client node and choose Properties.
The SOAP Message Handlers properties shows the number of handlers currently associated with the web service, as illustrated in FIGURE 4-1.
2. Click the value of the Soap Message Handlers property, and click the ellipsis (...) button.
The IDE displays the SOAP Message Handlers dialog box, as illustrated in FIGURE 4-3. In this example the web service has one handler class.
3. Highlight a handler and click Modify properties.
The Set Properties dialog box appears, as illustrated in FIGURE 4-4. In this example, the handler has a property named logFile, whose value is the fully-qualified name of the file to which the handler writes log information.
The dialog box displays properties and values for the selected handler. You can remove a property or add a property.
The Add Properties dialog box appears, as illustrated in FIGURE 4-5. In this example, a new property is added named auditFile, whose value is the fully-qualified name of the file to which the handler writes audit information.
5. Enter a property name and value, and click OK.
The Set Properties dialog box appears showing the new property and value, as illustrated in FIGURE 4-6.
See CODE EXAMPLE 4-6 for sample handler code that initializes a handler with the value of the logFile property.
To add a SOAP header block to a handler:
1. Right-click the web service or client node and choose Properties.
The SOAP Message Handlers properties shows the number of handlers currently associated with the web service, as illustrated in FIGURE 4-1.
2. Click the value of the Soap Message Handlers property, and click the ellipsis (...) button.
The IDE displays the SOAP Message Handlers dialog box, as illustrated in FIGURE 4-3.
3. Highlight a handler and click Modify SOAP headers.
The Set SOAP Header dialog box appears, as illustrated in FIGURE 4-7.
The dialog box displays SOAP header blocks (SOAP Header QNames) for the selected handler. You can remove a QName or add a QName.
A dialog box appears, as illustrated in FIGURE 4-8.
5. Enter the SOAP Header QName and click OK.
The new SOAP header block name appears in the Set SOAP Header dialog box, as illustrated in FIGURE 4-7.
Note - If the header block has a namespace qualifier, it should be entered in the following syntax: {namespace-uri}localpart. The syntax is displayed in the Set SOAP Header dialog box in FIGURE 4-8. For example, {foo/myNS}header1. |
These header names are available to a handler instance when it is configured at runtime. See Getting Header Blocks at Handler Initialization for information and a code sample, showing how this feature is used.
Note - This list of SOAP header block names is static information that is set up at development time for a given web service or client, and is passed to a handler when it is initialized at runtime. For information about how a handler can add a header block to a SOAP message dynamically at runtime, see Adding a Header Block to a SOAP Message. |
The IDE enables you to associate one or more SOAP actor roles with a handler chain. See Handler chains, SOAP Actor Roles, and Enforcing the Processing of Header Blocks for an explanation of how SOAP actor roles are used.
1. Right-click the web service or client node and choose Properties.
The SOAP Message Handlers properties shows the number of handlers currently associated with the web service, as illustrated in FIGURE 4-1.
2. Click the value of the Soap Message Handlers property, and click the ellipsis (...) button.
The IDE displays the SOAP Message Handlers dialog box, as illustrated in FIGURE 4-3.
You can set SOAP actor roles for the handler chain, not for individual handlers.
The IDE displays the Configure SOAP Actor Roles dialog box, as illustrated in FIGURE 4-9.
The dialog box displays SOAP actor roles for the handler chain. You can remove an actor role or add an actor role.
A dialog box appears, as illustrated in FIGURE 4-10.
5. Enter the desired SOAP actor role and click OK.
The SOAP actor role must be expressed as a valid URI.
The new SOAP actor role appears in the Set SOAP Header dialog box, as illustrated in FIGURE 4-11.
This section explains how you can ensure that a handler chain processes mandatory headers that are intended for certain SOAP actors.
A handler chain can be configured to act in the role of one or more SOAP actors, expressed as a valid URI. A handler in the handler chain can be configured to process header blocks with specified qualified names (QNames) and return the header blocks in the handler's getHeaders() method.
When a SOAP message is processed, the handler chain does the following:
1. Determines what actor roles (from the configured actors) the handler chain is to play. It also keeps track of all header blocks that each handler in the chain intends to process.
2. Examines the SOAP message header blocks (if any) and determines which ones must be processed by the handler chain, by finding all header blocks that are mandatory for its configured actors. It does this by looking at the values of the "actor" and "mustUnderstand" attributes of the header blocks.
3. Checks if each mandatory header block is in the list that the handlers intend to process, that is, it is "understood" by the handler chain. If a mandatory header block is not "understood" by the chain, a SOAPFaultException is thrown.
4. Processes the header blocks that are intended for the chain by invoking the individual handlers.
To enforce the processing of mandatory header blocks by a handler chain:
1. Add the appropriate actor roles to the handler chain.
The procedure is described in Setting a SOAP Actor Role For a Handler Chain.
2. Specify the handlers' intent to process certain headers by configuring each handler with the designated header blocks.
The procedure is described in Adding a SOAP Header Block To a Handler.
3. In the handler's code, return the designated header blocks in the getHeaders() method.
You can get the header blocks from the HandlerInfo that is passed to the init() method of the handler.
4. Process the header blocks in the handler code.
The web service handler in CODE EXAMPLE 4-7 processes an RPC request message as follows:
1. During handler initialization, the init method gets a property that specifies the name of a file to be the target for logging messages.
2. The handleRequest method builds a log message consisting of the date and time followed by the data in the request
3. The handleRequest method writes the log message to the target log file.
Copyright © 2003, Sun Microsystems, Inc. All rights reserved.