Add child elements to custom SOAP header in Spring-WS
Asked Answered
U

4

16

I am calling a SOAP webservice with Spring-WS. The webservice in question requires me to pass some information in the SOAP header as shown here:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header>
      <CustomHeaderElement>
         <clientID>xyz</clientID>
         <wsdlVersion>1.0</wsdlVersion>
         <serviceType>ExampleService_v1</serviceType>
      </CustomHeaderElement>
   </soapenv:Header>
   <soapenv:Body>
   ...
   </soapenv:Body>
</soapenv:Envelope>

I've figured out how to had the top level CustomHeaderElement, but I don't see anything in the Spring-WS API that allows me to add a child element. Here is what I have so far:

WebServiceTemplate template = ...;

template.marshalSendAndReceive(request, new WebServiceMessageCallback(){
    public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException{
        SoapMessage soapMessage = (SoapMessage)message;
        SoapHeader soapHeader = soapMessage.getSoapHeader();
        QName qName = new QName("CustomHeaderElement");
        SOAPHeaderElement headerElement = soapHeader.addHeaderElement(qName);
        //would like to do something like headerElement.addChild(clientIdNode);
    }
});

The problem is headerElement doesn't seem to expose any means of actually adding a child. I know I can add an attribute, but that's not what I need for this service call. Does anyone know how I could add the necessary child elements to my custom header?

Urena answered 27/10, 2010 at 16:26 Comment(0)
U
1

I'm not pleased with this solution, but as it turns out you can actually cast the message to a SOAPMessage which gives you full access to all the SAAJ apis. From there you can build whatever elements you want inside the header.

Urena answered 15/11, 2010 at 16:3 Comment(3)
Do you mean something similar to this post: #4046575 where a Transformer is use after casting the message to a SOAPMessage? I agree that it's not really pleasing nor elegant. I wonder why.Haggis
-1 Not really an answer. P.S. the link provided by @Haggis has good solutions.Phylum
Your answer, even marked as the right one, didn't help us at all.Bioscopy
C
8

I came across the same issue, here's my solution but it will work only simple elements not for complex:

template.marshalSendAndReceive(request, new WebServiceMessageCallback(){
    public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException{
        SaajSoapMessage soapMessage = (SaajSoapMessage) message;
        SoapHeaderElement messageId =  soapMessage.getSoapHeader().addHeaderElement(new QName("http://www.w3.org/2005/08/addressing", "MessageID", "wsa"));
        messageId.setText("urn:abcdef1234");
    }
});

it produces following XML:

<SOAP-ENV:Header>
  <wsa:MessageID>urn:abcdef1234</wsa:MessageID>
</SOAP-ENV:Header>

BTW javax.xml.soap.SOAPMessage can work too, see here: http://docs.oracle.com/javaee/5/tutorial/doc/bnbhr.html#bnbia

Christie answered 15/2, 2012 at 1:11 Comment(0)
T
3
final String datPrefix = "dat";
final String datNamespaceUri = "UPRS/Services/IProviderDataManagement/Datatypes";

final String mesPrefix = "mes";
final String mesNamespaceUri = "UPRS/Services/IProviderDataManagement/Messages";

SoapEnvelope se = s.getEnvelope();
se.addNamespaceDeclaration(mesPrefix,
        mesNamespaceUri);
se.addNamespaceDeclaration(datPrefix,
        datNamespaceUri);

SoapMessage s = (SoapMessage) message;

Element root = new Element("requestContext", mesPrefix, mesNamespaceUri);
Element child = new Element("commandId", datPrefix, datNamespaceUri).addContent(guid);
root.addContent(child);

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new JDOMSource(root), s.getSoapHeader().getResult());

It produced output

<SOAP-ENV:Header>
        <mes:requestContext xmlns:mes="UPRS/Services/IProviderDataManagement/Messages">
            <dat:commandId xmlns:dat="UPRS/Services/IProviderDataManagement/Datatypes">ba7b1e13-8a06-49b6-a264-fc0298f55f4f</dat:commandId>
        </mes:requestContext>
    </SOAP-ENV:Header>
Treasatreason answered 17/2, 2014 at 11:50 Comment(1)
Welcome to SO! Please include explanation of what your code does and how it answers the question. If you get a code snippet as an answer, you may not know what to do with it. Answer should give the OP guidance on how to debug and fix their problem. Pointing out, what the idea behind your code is, greatly helps in understanding the issue and applying or modifying your solution.Bombastic
U
1

I'm not pleased with this solution, but as it turns out you can actually cast the message to a SOAPMessage which gives you full access to all the SAAJ apis. From there you can build whatever elements you want inside the header.

Urena answered 15/11, 2010 at 16:3 Comment(3)
Do you mean something similar to this post: #4046575 where a Transformer is use after casting the message to a SOAPMessage? I agree that it's not really pleasing nor elegant. I wonder why.Haggis
-1 Not really an answer. P.S. the link provided by @Haggis has good solutions.Phylum
Your answer, even marked as the right one, didn't help us at all.Bioscopy
K
0

I had the same issue and resolved it with the following snippet:

Result result = ((SoapMessage) message).getSoapHeader().getResult();
webServiceTemplate.getMarshaller().marshal(createCustomHeader(), result);

The createCustomerHeader() method creates a JAXB bean which was generated from the XSD.

Kinematics answered 18/8, 2016 at 6:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.