SOAP 消息在 SOAPHandler 中的 saveChanges 之后被更改

SOAP Message is changed after saveChanges in SOAPHandler

我在客户端创建了一个 SOAPHandler 来记录对服务器的传出请求并使用 JAX-WS 修改一些元素。

修改元素后,保存消息:

try {
    // modifying elements
    SOAPBody body = soapMsg.getSOAPBody();
    NodeList blst = body.getElementsByTagName("ns6:exportNsiItemRequest");
    Node itm = blst.item(0);
    Node itm2 = itm.getFirstChild();

    Document doc = body.getOwnerDocument();

    doc.adoptNode(nd);

    itm.insertBefore(nd, itm2);

    soapMsg.saveChanges();
    log.info("XML saved!");
} catch (SOAPException e1) {
    log.info("XML DOESN'T saved!");
    e1.printStackTrace();
}

然后我打印消息:

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    msg.writeTo(baos);
    System.out.println(baos.toString(getMessageEncoding(msg)));

这是打印消息的一部分:

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="xmldsig-4cf24b6d-5c1a-4756-9657-3ba87c3af164">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>

我使用 Wireshark 查看发送到服务器的实际 soap 消息的上下文。

我看到了什么??它是:

        <ds:Signature
            xmlns=""
            Id="xmldsig-4cf24b6d-5c1a-4756-9657-3ba87c3af164"
            xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <ds:SignedInfo>
                <ds:CanonicalizationMethod
                    Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>

为什么有人修改了我的消息并插入空的 xlnms="" 标签???

插入的标签与XML Namespaces. They were defined by the World Wide Web Consortium in 1999 (you can check the document here, and also its more recent version)有关。如这些文件中所述:

XML namespaces provide a simple method for qualifying element and attribute names used in Extensible Markup Language documents by associating them with namespaces identified by URI references.

通过一些研究,我发现 this 参考文献讨论了 xmlns 标签,从其内容中提取:

The prefix xmlns: was specified as a syntactic device for declaring namespaces, but was not itself associated with any namespace name by the Jan 1999 namespaces specification ...

Note that you must use the reserved prefix xmlns: when declaring namespaces ...

The attribute name xmlns, which is used to declare the default namespace, is also hereby associated with this namespace name...

正如我在评论中提到的,我相信您可以分享更多代码,这些代码可能会更清楚地说明为什么会发生这种情况,但正如我们从参考文献中看到的空 xmlns标记可能作为必需的默认值添加(即,文档中的 URI 没有默认名称空间前缀)。

为了进一步解释,让我们看看您在文档中声明的其他名称空间(您在其中正确使用 xmlns: 前缀作为参考状态):

xmlns:ds="http://www.w3.org/2000/09/xmldsig#"

在这里,命名空间前缀(就像一个别名)是ds命名空间URI http://www.w3.org/2000/09/xmldsig#。这意味着在您的文档中,像 <ds:foo /> 这样的元素在解析文档时将等同于具有标识符 <http://www.w3.org/2000/09/xmldsig#:foo />

如果您想了解更多信息,可以查看 this 很好的问答,其中详细解释了命名空间并提供了一些有用的外部参考。