Java SOAP 将名称空间声明添加到 SOAP 主体的子元素

Java SOAP adding namespace declaration to child element of SOAP body

我正在尝试创建具有特定结构的 SOAP 消息,但我 运行 遇到了命名空间问题。

我无法修改消费者使用消息的方式,并且我不知道为什么在目标元素中没有命名空间的情况下会给我一个错误。我已经在 C# 中成功地做到了这一点,所以如果消息在正确的位置有命名空间,它就可以工作。

我正在使用 Java 7,无法使用任何第三方库。

我目前的结果是这样的:

<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

我想要的是:

<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

请注意 myElement 元素中重复的命名空间声明。

我尝试过的:

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

我也曾尝试只添加一个属性,但结果出错。 所有其他尝试都只是导致目标元素上没有命名空间声明。

有谁知道如何实现我所追求的目标?

根据上面评论中的详细信息,我认为发生的情况是 Web 服务仅解析 SOAP 负载。这就是为什么它在 myElement.

中找不到名称空间声明时失败的原因

像这样的 XML 是完全有效的:

<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>

但是当只解析有效负载时,它会导致 Web 服务只看到这个:

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

现在它不再有效,因为没有命名空间声明来说明 myns 的含义。

因此,从信封中删除命名空间声明并将其添加到有效负载的元素上允许服务对其进行解析(我不确定这样做是否出于 interoperability 原因,或者您是否只是在处理写得不好的 Web 服务)。

话虽如此,关于 post 中关于在信封和 myElement 上添加命名空间声明的方法的问题,仅使用来自JDK,我不确定这是否有效。

据我所知,当您使用 SOAPMessageSOAPElement 等构建消息时,XML 命名空间声明会添加到前缀-uri 对的内部字典中,并且当消息被序列化时,为了消除冗余并减小消息的大小,命名空间声明只在顶级祖先元素上写一次,子元素只使用前缀。

解决方案会很丑陋,它涉及构建您的 SOAP 消息,将其转储到一个字符串中并在将其附加到 POST 请求发送之前操纵该字符串。您可能已经在 myElement 上添加了一个属性,如下所示:

<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>

并在发送消息之前将 C762CCEA30CE8CE22F2C6E737D7AA2B023DD9EBE="bla" 的字符串替换为 xmlns:myns="http://example.com/myns"。丑!