Using handlers in JAX-WS web services
Java™ API for XML Web Services (JAX-WS) provides you with a standard way of developing interoperable and portable web services. Use JAX-WS handlers to customize web services requests or response handling.
Before you begin
You need an enterprise archive (EAR) file for the applications that you want to configure. If you are running in a Thin Client for JAX-WS environment, then you are not required to begin with an EAR file. For some handler use, such as logging or tracing, only the server or client application needs to be configured. For other handler use, including sending information in SOAP headers, the client and server applications must be configured with symmetrical handlers.
javax.xml.ws.handler.LogicalHandler<LogicalMessageContext>
interface
or the javax.xml.ws.handler.soap.SOAPHandler<SOAPMessageContext>
interface. SOAPMessage m = context.getMessage();
AttachmentPart ap1 = m.createAttachmentPart();
ap1.setContent("abc", "text/plain");
m.addAttachmentPart(ap1);
context.setMessage(m);
About this task
As in the Java API for XML-based RPC (JAX-RPC) programming model, the JAX-WS programming model provides an application handler facility that enables you to manipulate a message on either an inbound or an outbound flow. You can add handlers into the JAX-WS runtime environment to perform additional processing of request and response messages. You can use handlers for a variety of purposes such as capturing and logging information and adding security or other information to a message. Because of the support for additional protocols beyond SOAP, JAX-WS provides two different classifications for handlers. One type of handler is a logical handler that is protocol independent and can obtain the message in the flow as an extensible markup language (XML) message. The logical handlers operate on message context properties and message payload. These handlers must implement the javax.xml.ws.handler.LogicalHandler interface. A logical handler receives a LogicalMessageContext object from which the handler can get the message information. Logical handlers can exist on both SOAP and XML/HTTP-based configurations.
The second type of handler is a protocol handler. The protocol handlers operate on message context properties and protocol-specific messages. Protocol handlers are limited to SOAP-based configurations and must implement the javax.xml.ws.handler.soap.SOAPHandler interface. Protocol handlers receive the message as a javax.xml.soap.SOAPMessage to read the message data.
The JAX-WS runtime makes no distinction between server-side and client-side handler classes. The runtime does not distinguish between inbound or outbound flow when a handleMessage(MessageContext) method or handleFault(MessageContext) method for a specific handler is invoked. You must configure the handlers for the server or client, and implement sufficient logic within these methods to detect the inbound or outbound direction of the current message.
To use handlers with web services client applications, you must add the @HandlerChain annotation to the service endpoint interface or the generated service class and provide the handler chain configuration file. The @HandlerChain annotation contains a file attribute that points to a handler chain configuration file that you create. For web services client applications, you can also configure the handler chain programmatically using the Binding API. To modify the handlerchain class programmatically, use either the default implementation or a custom implementation of the HandlerResolver method.
To use handlers with your server application, you must set the @HandlerChain annotation on either the service endpoint interface or the endpoint implementation class, and provide the associated handler chain configuration file. Handlers for the server are only configured by setting the @HandlerChain annotation on the service endpoint implementation or the implementation class. The handler classes must be included in the server application EAR file.
@HandlerChain(file="../../common/handlers/myhandlers.xml")
or @HandlerChain(file="http://foo.com/myhandlers.xml")
For
more information on the schema of the handler configuration file,
see the JSR 181 specification.For more information regarding JAX-WS handlers, see chapter 9 of the JAX-WS specification.
Procedure
Results
You have the enabled your JAX-WS web service or web services client to use handlers to perform additional processing of request and response message exchange.
Example
The following example illustrates the steps necessary to configure JAX-WS handlers on a service endpoint interface using the @HandlerChain annotation.
<?xml version="1.0" encoding="UTF-8"?>
<jws:handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee">
<!-- Note: The '*" denotes a wildcard. -->
<jws:handler-chain name="MyHandlerChain">
<jws:protocol-bindings>##SOAP11_HTTP ##ANOTHER_BINDING</jws:protocol-bindings>
<jws:port-name-pattern
xmlns:ns1="http://handlersample.samples.ibm.com/">ns1:MySampl*</jws:port-name-pattern>
<jws:service-name-pattern
xmlns:ns1="http://handlersample.samples.ibm.com/">ns1:*</jws:service-name-pattern>
<jws:handler>
<jws:handler-class>com.ibm.samples.handlersample.SampleLogicalHandler</jws:handler-class>
</jws:handler>
<jws:handler>
<jws:handler-class>com.ibm.samples.handlersample.SampleProtocolHandler2</jws:handler-class>
</jws:handler>
<jws:handler>
<jws:handler-class>com.ibm.samples.handlersample.SampleLogicalHandler</jws:handler-class>
</jws:handler>
<jws:handler>
<jws:handler-class>com.ibm.samples.handlersample.SampleProtocolHandler2</jws:handler-class>
</jws:handler>
</jws:handler-chain>
</jws:handler-chains>
</jws:handler-chains>
Make sure that you add the handler.xml file and the handler classes contained in the handler.xml file in your class path.
package com.ibm.samples.handlersample;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class SampleProtocolHandler implements
javax.xml.ws.handler.soap.SOAPHandler<SOAPMessageContext> {
public void close(MessageContext messagecontext) {
}
public Set<QName> getHeaders() {
return null;
}
public boolean handleFault(SOAPMessageContext messagecontext) {
return true;
}
public boolean handleMessage(SOAPMessageContext messagecontext) {
Boolean outbound = (Boolean) messagecontext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outbound) {
// Include your steps for the outbound flow.
}
return true;
}
}