views:

324

answers:

2

How can I add an object into the soap header of a org.springframework.ws.WebServiceMessage

This is the structure I'm looking to end up with:

 <soap:Header>
    <credentials xmlns="http://example.com/auth"&gt;
      <username>username</username>
      <password>password</password>
    </credentials>
  </soap:Header>
+1  A: 

You need to cast the WebServiceMessage to SoapMessage, which has a getSoapHeader() method you can use to modify the header. In turn, SoapHeader has various methods for adding elements, including getResult() (which can be used as the output of a Transformer.transform() operation).

skaffman
+2  A: 

Basically, you need to use a WebServiceMessageCallback in your client to modify the message after its creation but before it is sent. To rest of the code has been described pretty accurately by @skaffman so the whole stuff might look like this:

public void marshalWithSoapActionHeader(MyObject o) {

    webServiceTemplate.marshalSendAndReceive(o, new WebServiceMessageCallback() {

        public void doWithMessage(WebServiceMessage message) {
            try {
                SoapMessage soapMessage = (SoapMessage)message;
                SoapHeader header = soapMessage.getSoapHeader();
                StringSource headerSource = new StringSource("<credentials xmlns=\"http://example.com/auth\"&gt;\n +
                        <username>"+username+"</username>\n +
                        <password>"+password"+</password>\n +
                        </credentials>");
                Transformer transformer = TransformerFactory.newInstance().newTransformer();
                transformer.transform(headerSource, header.getResult());
            } catch (Exception e) {
                // exception handling
            }
        }
    });
}

Personally, I find that Spring-WS sucks hard for such a basic need, they should fix SWS-479.

Pascal Thivent
Spring-WS is pretty much a one-man operation, and Arjen isn't quite as suggestible as the rest of them :)
skaffman
Thanks Pascal, that works perfectly. I ended up using javax.xml.bind.util.JAXBSource instead of StringSource like so:JAXBSource headerSource = new JAXBSource(jaxbContext, credentials);
Scobal
@skaffman Indeed :)
Pascal Thivent
@Scobal You're welcome. Thanks for the feedback.
Pascal Thivent