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>