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);
            }
        }
    }