简体   繁体   中英

Java SOAP adding namespace declaration to child element of SOAP body

I'm trying to create a SOAP message with a specific structure and I am running into an issue with namespaces.

I cannot modify the way the consumer consumes the message and I don't know why it gives me an error without the namespace in the target element. I have already successfully done this in C# so it is known to work if the message has the namespace in the correct location.

I am using Java 7 and cannot use any third-party libraries.

I currently end up with something like this:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://..." xmlns:myns="http://.../myns">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
        <myns:myElement>
            ...
        </myns:myElement>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope

What I would like is:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://..." xmlns:myns="http://.../myns">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
        <myns:myElement xmlns:myns="http://.../myns">
            ...
        </myns:myElement>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope

Note the duplicate namespace declaration in the myElement element.

What I have tried:

SOAPElement myElement = body.addChildElement("myElement" namespace);
myElement.addNamespaceDeclaration("myns", "http://.../myns");
Name myElementName = envelope.createName("myElement", "myns", "http://.../myns");
SOAPElement myElement = body.addBodyElement(myElementName);

I have also attempted to just add an attribute but that results in an error. All other attempts have simply resulted in no namespace declaration on the target element.

Does anyone know how to achieve what I'm after?

Based on the details in the comments above, what I believe is happening is that the web service is only parsing the SOAP payload. That's why it fails if it doesn't find a namespace declaration in myElement .

An XML like this is perfectly valid:

<SOAP-ENV:Envelope 
      xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:myns="http://example.com/myns">
  <SOAP-ENV:Body>
    <myns:myElement>whatever</myns:myElement>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

but when parsing only the payload it results in the web service only seeing this:

<myns:myElement>whatever</myns:myElement>

which now it is no longer valid because there is no namespace declaration to say what myns means.

So removing the namespace declaration from the envelope and adding it on the elements of the payload allows the service to parse it (I'm not sure if this would be done for interoperability reasons or if you are just dealing with a badly written web service).

With this being said, regarding your question in the post about a way to add the namespace declaration on both the envelope and myElement , using only the javax.xml.soap package from the JDK, I'm not sure that would have worked.

From what I remember, when you build your message with SOAPMessage , SOAPElement , etc, the XML namespace declarations are added to an internal dictionary of prefix-uri pairs and when the message is serialized, to eliminate redundancy and decrease the size of the message, the namespace declaration is written only once on a top ancestor element and children elements just make use of the prefix.

The solution would have been ugly and it involved building your SOAP message, dumping it into a string and manipulate that string before sending it attached to a POST request. You probably could have added an attribute on myElement like so:

<SOAP-ENV:Envelope 
      xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:myns="http://example.com/myns">
  <SOAP-ENV:Body>
    <myns:myElement C762CCEA30CE8CE22F2C6E737D7AA2B023DD9EBE="bla">whatever</myns:myElement>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

and before sending the message to just do a string replacement of C762CCEA30CE8CE22F2C6E737D7AA2B023DD9EBE="bla" with xmlns:myns="http://example.com/myns" . Ugly!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM