Category Archives: Spring

Setting the soap response header in spring-ws

Filling the response body of a soap message in spring ws is normally well explained on various websites. Figuring out how to also fill the response header took me a bit more investigation.

There are several options, which are described below. First you have to ensure that the messageContext is added as a parameter in the payload. Alternatively you can use a interceptor.

    @PayloadRoot(localPart = LOCAL_PART, namespace = NAMESPACE)
    @ResponsePayload
    public <return type> handleRequest(@RequestPayload final <request type> request,
                                                 MessageContext messageContext) {

With this messageContext you can set the response header the following ways.

Fill the response header 1-on-1 the same as the request header
The following will get the request header from the message context at puts that back exactly the same in the response header.

    
    public void appendHeader(MessageContext messageContext ){
        SaajSoapMessage soapRequest = (SaajSoapMessage) messageContext.getRequest();
        SoapHeader reqheader = soapRequest.getSoapHeader();
        SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
        SoapHeader respheader = soapResponse.getSoapHeader();
 
        try {
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            Iterator<SoapHeaderElement> itr = reqheader.examineAllHeaderElements();
            while (itr.hasNext()) {
                SoapHeaderElement ele = itr.next();
                transformer.transform(ele.getSource(), respheader.getResult());
            }
        } catch (TransformerException e) {
            LOG.error("error adding header", e);
        }
    }

(Un)marshall the response header from it’s object type
The following code will get you the unmarshalled request header object, which will give you the opportunity to use it’s getters and setters.

Note that you have to replace the in below example code with the class name of your own response header object.

public void appendHeader(MessageContext messageContext ){
        
        SaajSoapMessage soapRequest = (SaajSoapMessage) messageContext.getRequest();
        SoapHeader reqheader = soapRequest.getSoapHeader();
        SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
        SoapHeader respheader = soapResponse.getSoapHeader();
 
        Iterator<SoapHeaderElement> itr = reqheader.examineAllHeaderElements();
        while (itr.hasNext()) {
            SoapHeaderElement ele = itr.next();
 
            try {
                JAXBContext context = JAXBContext.newInstance(<T>.class);
                Unmarshaller unmarshaller = context.createUnmarshaller();
                Marshaller marshaller = context.createMarshaller();
 
                <T> headerType = unmarshaller.unmarshal(ele.getSource(), <T>.class).getValue();
                headerType.setRelatesTo(auditHeaderType.getMessageID());
 
                JAXBElement<T> responseHeader = new JAXBElement<T>(ele.getName(), <T>, headerType);
                marshaller.marshal(responseHeader, respheader.getResult());
 
            } catch (JAXBException e) {
                throw new RuntimeException(e);
            }
        }
    }

Choose unique values for the ‘webAppRootKey’ context-param in your web.xml files!

You will have this issue when you are running multiple Spring webapplications in the same container.


java.lang.IllegalStateException: Web app root system property
already set to different value: 'webapp.root' =
[/tmp/jetty-0.0.0.0-8080-springdemo.war-_springdemo-any-/webapp]
instead of [/tmp/jetty-0.0.0.0-8080-greeting.war-_greeting-any-/webapp]
- Choose unique values for the 'webAppRootKey' context-param in
your web.xml files!

In Spring the webAppRootKey has a default value, which in this case obviously is the same for both applications.

Solve this by specifying the contextparam in your web.xml:


<context-param>
    <param-name>webAppRootKey</param-name>
    <param-value>specify.a.value.here</param-value>
</context-param>