A SOAP handler provides an opportunity to modify incoming requests before processing and outgoing responses just before they are sent. Assuming you have already created a SOAP WebService, these are the steps to implement a SOAP Handler:
1) Create a class that implements SOAPHandler<SOAPMessageContext>
This class could be in the same package as the WebService implementation class and will contain the methods shown in the following example:
public class SiteHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public boolean handleMessage(SOAPMessageContext context) {
System.out.println("handleMessage");
boolean isReponse = (boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if(isReponse){
System.out.println("Response on the way.");
} else{
SOAPMessage message = context.getMessage();
SOAPPart part = message.getSOAPPart();
try {
SOAPEnvelope envelope = part.getEnvelope();
SOAPHeader header = envelope.getHeader();
@SuppressWarnings("rawtypes")
Iterator iterator = header.getChildElements();
while(iterator.hasNext()){
Node node = (Node) iterator.next();
String name = node.getNodeName();
if(name != null && name.equals("SiteName")){
System.out.println("Site name is " + node.getValue());
}
}
} catch (SOAPException e) {
e.printStackTrace();
}
}
return true;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
System.out.println("handleFault");
return false;
}
@Override
public void close(MessageContext context) {
System.out.println("close");
}
@Override
public Set<QName> getHeaders() {
System.out.println("getHeaders");
return null;
}
}
2) Add a soap-handler.xml file
Add a soap-handler.xml file to the package containing the SOAPHandler implementation class:
<?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>my.package.SiteHandler </javaee:handler-class> </javaee:handler> </javaee:handler-chain> </javaee:handler-chains>
3) Add a @HandlerChain annotation to the WebService implementation class
@HandlerChain(file="soap-handler.xml")
public class CustomerOrdersWsImpl implements CustomerOrdersPortType {
Map<BigInteger, List<Order>> customerOrders = new HashMap<>();
4) Add a Bean reference to the cxf-servlet.xml file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/core" xmlns:soap="http://cxf.apache.org/bindings/soap" xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:endpoint id="CustomerOrderWs" address="/customerOrders" wsdlLocation="WEB-INF/wsdl/CustomerOrders.wsdl" implementor="my.package.WsImplementation" serviceName="customerOrders:CustomerOrdersService" xmlns:customerOrders="http://my.namespace.com/"> <jaxws:handlers> <ref bean="SiteHandler" /> </jaxws:handlers> </jaxws:endpoint> <bean id="SiteHandler" class="my.package.SiteHandler" /> <cxf:bus> <cxf:features> <cxf:logging /> </cxf:features> </cxf:bus> </beans>