Thursday 14 November 2013

Spring WS Interceptor

Using the spring interceptor methods a SOAP message can be manipulated by adding or removing elements.

Create an interceptor and add it to the spring config
   
    <bean id="myInterceptor" class="com.me.MyInterceptor">
    </bean>
    
    <sws:interceptors>
    <ref bean="myInterceptor" />
    </sws:interceptors>

The interceptor class implements the EndpointInterceptor

    public class MyInterceptor implements EndpointInterceptor

This interface defines four methods,

    // Used to read and / or manipulate the request coming in the endpoint
    boolean handleRequest(MessageContext paramMessageContext, Object paramObject)

    // Used to read and / or manipulate the response coming out of the endpoint
    boolean handleResponse(MessageContext paramMessageContext, Object paramObject)

    // Used to read and / or manipulate any faults that have occurred
    boolean handleFault(MessageContext paramMessageContext, Object paramObject)

    // Called after the interceptor has finished.
    void afterCompletion(MessageContext paramMessageContext, Object paramObject, Exception paramException)

Java Soap Objects

The default java soap objects are from the java.xml.soap package,

    SOAPBody
    SOAPHeader
    SOAPMessage

These objects use the standard org.w3c.dom objects to manipulate the contents.  These objects can be obtained using the following,

    SaajSoapMessage message = (SaajSoapMessage) messageContext.getRequest();
    SOAPMessage soapMessage = message.getSaajMessage();
    SOAPHeader soapHeader = soapMessage.getSOAPHeader();
    SOAPBody soapBody = soapMessage.getSOAPBody();

Spring Soap Objects

The spring objects are in the package org.springframework.ws.soap,

    SoapBody
    SoapHeader
    SoapEnvelope
    SoapElement

and have only a few methods.  The Body and Header can be used to get a standard javax.xml.transform.Source or Result object.  These objects can be obtained using,

    SaajSoapMessage message = (SaajSoapMessage) messageContext.getRequest();
    SoapBody soapHeader = message.getSoapHeader();
    SoapBody soapBody = message.getSoapBody();

Reading using the Java Objects

Reading using the java objects is pretty easy. Using the java SOAPBody a node list can be obtained,

    SOAPBody soapBody = soapMessage.getSOAPBody();
    NodeList soapBodyNodeList = soapBody.getChildNodes();
    String soapBodyStr = null;
    for (int i = 0; i < soapBodyNodeList.getLength(); i++)
    {
        String localName = soapBodyNodeList.item(i).getLocalName();
    }

or other standard dom manipulation eg getElementByTagName("myTag").

Reading using the Spring Objects

Using the Spring soap header or body can really simply be read using a Transformer,

    SoapBody springSoapBody = message.getSoapBody();
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer();
    StringWriter stringWriter = new StringWriter();
    transformer.transform(springSoapBody.getPayloadSource(), new StreamResult(stringWriter));

The contents can then be obtained from the stringWriter using the toString().  Alternatively a DOMResult can be used,

    DOMResult result = new DOMResult();
    transformer.transform(springSoapBody.getPayloadSource(), result);

Adding using the Spring Objects

Added an object in easy using the transformer defined above,

    SoapHeader soapHeader = message.getSoapHeader();
    StringSource stringSource = new StringSource("<xmlToAdd>Hello</xmlToAdd>");
    transformer.transform(stringSource , soapHeader.getResult());

The header will now include the xml.  At the point above the xml is just a string so could be generated using JAXB to create complicated additional nested xml tags if necessary.






No comments:

Post a Comment