java - 如何将 XML 请求附加到 SOAP Body 的唯一 SOAPElement 子级?

标签 java xml soap

用例

我需要以编程方式联系外部 SOAP 服务。为此,我需要创建一个 SOAP 请求,如下所示:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pric="http://myURI/">
   <soapenv:Header/>
   <soapenv:Body>
      <pric:myAPI>
        <XmlDocument>
            <OtherXmlContent>
            </OtherXmlContent>
        </XmlDocument>
      </pric:myAPI>
   </soapenv:Body>
</soapenv:Envelope>

我被阻止的任务

我设法创建以下 SOAP 信封:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pric="http://myURI/">
   <soapenv:Header/>
   <soapenv:Body>
      <pric:myAPI>

      </pric:myAPI>
   </soapenv:Body>
</soapenv:Envelope>

如果有输入,我需要做的是添加 XML 请求:

<XmlDocument>
    <OtherXmlContent>
    </OtherXmlContent>
</XmlDocument>

...作为<pric:myAPI>的 child ,这是我 <soapenv:Body> 的独生子.

仅供引用,上面的 Soap 信封(还没有 XmlDocument)是通过以下代码创建的:

MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration(pricingNamespace, pricingNamespaceURI);
SOAPBody soapBody = envelope.getBody();
SOAPElement pricingWrapper = soapBody.addChildElement(pricingAction, pricingNamespace);

...因此,我需要做的是将一个子项附加到 pricingWrapper 。我选择如何创建这个 child ,我可以完全控制生成它的函数,即这个:

private static String createXmlProductFromDealingDocument(Document dealings) 

尝试 1 - 将文档添加为文本

我尝试添加 XmlDocument作为 pricingWrapper 的文本。 我就是这样做的:

pricingWrapper.addTextNode(createXmlProductFromDealingDocument(dealingFile));

问题是,所有字符 <> XmlDocument的呈现为 String通过方法 addTextNode 进行转义。换句话说,我可以看到我的 body 有正确的内容,但是 <替换为 &lt;>替换为 &gt; ,因此使 SOAP 请求对于目标服务无效。

尝试 2 - 将文档添加为子节点

我所做的另一次尝试是返回 Node而不是String从我的功能:

private static Node createXmlProductFromDealingDocument(Document dealings) 

并附加此 Node作为 pricingWrapper 的 child :

pricingWrapper.appendChild(createXmlProductFromDealingDocument(dealingFile));

上面引发了类型的异常:

org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR: A node is used in a different document than the one that created it.

好吧,很公平。昨天我发布了一个问题(由于我想更深入地研究而很快被删除),一位用户在评论中善意地建议我检查如何通过引用 this answer 来克隆 DOM 节点。 。

我尝试这样做:

Node pricingRequest = createXmlProductFromDealingDocument(dealingFile);
Node soapPricingRequest = pricingRequest.cloneNode(true);
pricingWrapper.getOwnerDocument().adoptNode(soapPricingRequest);
pricingWrapper.appendChild(soapPricingRequest);

但是,这引发了一个新的异常:

org.w3c.dom.DOMException: NOT_SUPPORTED_ERR: The implementation does not support the requested type of object or operation.

...在下面一行:

pricingWrapper.getOwnerDocument().adoptNode(soapPricingRequest);

...而且我真的不知道我还能如何以与上面所做的不同的方式附加 child 。

我的问题是什么

我只想以正确的方式完成我的 SOAP 请求。对于是否通过将 XML 作为文本或作为 Node 注入(inject)来完成,我没有任何偏好。 ,只要是正确的方法,特别是只要它有效:) 有人可以告诉我如何解决上述问题吗?

最佳答案

阅读领养节点()的javadoc:

DOMException - NOT_SUPPORTED_ERR: Raised if the source node is of type DOCUMENT, DOCUMENT_TYPE. ".

那么,您可以检查一下 soapPrinceingRequest 是否确实是 DOCUMENT 类型的节点(使用 getNodeType())吗?

如果是这样,我建议您将 soapPrinceingRequest 转换为 Document,然后使用 getDocumentElement() 访问其根 NODE,并尝试 adopt()NODE,而不是 DOCUMENT

XML API 在追求正确性时总是有点棘手,并且 Document 及其根元素 之间的区别实际上很重要。所以这有点痛苦,但我们最终还是做到了。

关于java - 如何将 XML 请求附加到 SOAP Body 的唯一 SOAPElement 子级?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54782892/

相关文章:

java - 将 Jersey 从 1.x 迁移到 2.x 时出现编译错误

python/BeautifulSoup 使用字符串值访问子对象/标签

java - Spring WS/启动: How to set WebServiceTemplate property in client interceptor?

xml - 是否允许多个 XML 默认命名空间?

java - 忽略 XML 文件中的 SOAP 标记

java - 从java内部访问javascript

java - 在 hadoop 中获取作业配置

java - 具有依赖泛型类型的泛型类,不能专门化?

php - 您如何在PHP中解析和处理HTML/XML?

android drawable选择器兼容性问题