JAX-WS - SOAP Handlers
What is SOAP Handlers ?
SOAP Handlers are interceptor to do additional processing of incoming and outgoing message at Client as well as Server level. For example, to check properties in handler, to audit req/response or to do any filtering.
SOAP message contains three parts as below:-
JAX-WS 2.0 defines 2 types of Handlers - Logical and Message Handler.SOAP Handlers are interceptor to do additional processing of incoming and outgoing message at Client as well as Server level. For example, to check properties in handler, to audit req/response or to do any filtering.
SOAP message contains three parts as below:-
- SOAP Header [Optional]
- SOAP Body
- Attachments [Optional]
- Logical Handlers operates on message context properties and message payload only. Logical handlers are handlers that implements - javax.xml.ws.handler.LogicalHandler
- Message Handlers operates all parts of SOAP, i.e. SOAP Header, Body and attachments. it implements - javax.xml.ws.handler.soap.SOAPHandler
- handleMessage() - This method is called for both incoming and outgoing message for any additional processing
- handleFault() - This handles any fault generated by service implementation or exception generated from above method
- close() - called at last to do clean up resources.
Senders -> Logical Handler -> Message Handler -> Transport [HTTP?] -> Message Handler -> Logical handler -> Receiver |
Example:
Let us explore small web service example - echoservice, there are 2 handlers - one is checking for soap header parameter and second one is logging request / response console.
EchoServiceInterface.java
package soap.handler;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
@WebService
@SOAPBinding(style = Style.DOCUMENT)
public interface EchoServiceInterface {
String getMessage(@WebParam(name = "message") String message);
}
EchoServiceImpl.java package soap.handler;
import javax.jws.HandlerChain;
import javax.jws.WebService;
@WebService(endpointInterface = "soap.handler.EchoServiceInterface")
@HandlerChain(file = "handlers.xml")
public class EchoServiceImpl implements EchoServiceInterface {
@Override
public String getMessage(String message) {
return message;
}
}
EchoServiceExecutor.java package soap.handler;
import javax.xml.ws.Endpoint;
public class EchoServiceExecutor {
public static void main(String[] args) {
Endpoint.publish("http://localhost:8888/echo-service", new EchoServiceImpl());
}
}
ClientValidator.java - Message Handler package soap.handler;
import java.util.Iterator;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.ws.soap.SOAPFaultException;
public class ClientValidator implements SOAPHandler<SOAPMessageContext> {
private String SERVICE_CONSUMER = "serviceconsumer";
@Override
public boolean handleMessage(SOAPMessageContext context) {
Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
// incoming request
if (!outboundProperty) {
System.out.println("Client Request...");
checkMessage(context);
}else{
System.out.println("Client Response...");
}
return true;
}
// Check ConsumerApplication
private boolean checkMessage(SOAPMessageContext context) {
try {
SOAPMessage soapMessage = context.getMessage();
SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();
SOAPHeader soapHeader = soapEnvelope.getHeader();
Iterator<?> headers = soapHeader.extractHeaderElements(SOAPConstants.URI_SOAP_ACTOR_NEXT);
if (headers != null && headers.hasNext()) {
Node node = (Node) headers.next();
if (node != null) {
if (!SERVICE_CONSUMER.equals(node.getNodeName())) {
System.out.println("Missing ServiceConsumer Header");
SOAPBody soapBody = soapMessage.getSOAPPart().getEnvelope().getBody();
SOAPFault soapFault = soapBody.addFault();
soapFault.setFaultString("Invalid Service Consumer..!!");
throw new SOAPFaultException(soapFault);
}
}
}
} catch (SOAPException e) {
System.err.println(e);
}
return true;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
return false;
}
@Override
public void close(MessageContext context) {
}
@Override
public Set<QName> getHeaders() {
return null;
}
}
LoggingHandler.java - Logical handler package soap.handler;
import javax.xml.transform.Source;
import javax.xml.ws.LogicalMessage;
import javax.xml.ws.handler.LogicalHandler;
import javax.xml.ws.handler.LogicalMessageContext;
import javax.xml.ws.handler.MessageContext;
public class LoggingHandler implements LogicalHandler<LogicalMessageContext> {
@Override
public boolean handleMessage(LogicalMessageContext context) {
Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
System.out.println("Response:-");
} else {
System.out.println("Request:-");
}
LogicalMessage message = context.getMessage();
try {
Source src = message.getPayload();
Utility.print(src);
} catch (Exception e) {
System.err.println(e);
}
return true;
}
@Override
public boolean handleFault(LogicalMessageContext context) {
return false;
}
@Override
public void close(MessageContext context) {
}
}
handlers.xml <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<javaee:handler-chain>
<javaee:handler>
<javaee:handler-class>soap.handler.ClientValidator
</javaee:handler-class>
</javaee:handler>
<javaee:handler>
<javaee:handler-class>soap.handler.LoggingHandler
</javaee:handler-class>
</javaee:handler>
</javaee:handler-chain>
</javaee:handler-chains>
soap-ui Request / Response <soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:han="http://handler.soap/">
<soapenv:Header>
<serviceconsumer soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next">Application</serviceconsumer>
</soapenv:Header>
<soapenv:Body>
<han:getMessage>
<message>Demo Application</message>
</han:getMessage>
</soapenv:Body>
</soapenv:Envelope>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getMessageResponse xmlns:ns2="http://handler.soap/">
<return>Demo Application</return>
</ns2:getMessageResponse>
</S:Body>
</S:Envelope>
Console Output
Client Request...
Request:-
<?xml version="1.0" encoding="UTF-8"?><han:getMessage xmlns:han="http://handler.soap/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<message>Demo Application</message>
</han:getMessage>
Response:-
<?xml version="1.0" encoding="UTF-8"?><ns2:getMessageResponse xmlns:ns2="http://handler.soap/"><return>Demo Application</return></ns2:getMessageResponse>
Client Response...
Download Example
Comments
Post a Comment