我需要以编程方式联系外部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>
的孩子,这是我<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
上。我选择如何创建这个孩子,我完全控制生成这个孩子的功能:
private static String createXmlProductFromDealingDocument(Document dealings)
我尝试将XmlDocument
添加为pricingWrapper
的文本。
这是我的方法:
pricingWrapper.addTextNode(createXmlProductFromDealingDocument(dealingFile));
但是,问题是,<
中呈现为>
的{{1}}的所有字符XmlDocument
和String
都被方法addTextNode
转义。换句话说,我可以看到我的身体内容正确,但是<
替换为<
,>
替换为>
,因此使SOAP请求对于目标服务。
我所做的另一种尝试是从函数中返回Node
而不是String
:
private static Node createXmlProductFromDealingDocument(Document dealings)
并将此Node
附加为pricingWrapper
的子代:
pricingWrapper.appendChild(createXmlProductFromDealingDocument(dealingFile));
上面引发了一个类型异常:
org.w3c.dom.DOMException:WRONG_DOCUMENT_ERR:一个节点在与创建它的节点不同的文档中使用。
好的,很公平。昨天,我发布了一个问题(由于想进一步深入研究而删除),一位用户在评论中建议我,以检查如何通过引用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:该实现不支持所请求的对象或操作类型。
...在以下行上:
pricingWrapper.getOwnerDocument().adoptNode(soapPricingRequest);
...而且我真的不知道我可以怎样追加孩子而不是上面的工作。
我只是想以正确的方式完成我的SOAP请求。我不希望通过将XML作为文本或Node
注入的方式来完成此操作,只要适当的方式,尤其是在可行的范围内:)
谁能给我小费我如何解决以上问题?
答案 0 :(得分:1)
读取acceptNode()的javadoc:
DOMException-NOT_SUPPORTED_ERR:如果源节点的类型为DOCUMENT,DOCUMENT_TYPE,则引发。 “
因此,您可以检查soapPrincingRequest
是否确实是DOCUMENT
类型的节点(使用getNodeType()
)吗?
如果是这样,我建议您将soapPrincingRequest
转换为Document
,然后使用NODE
访问其根getDocumentElement()
,并尝试adopt()
NODE
,而不是DOCUMENT
。
XML API在争取正确性时总是很难使用,Document
及其root element
之间的区别实际上很重要。因此,这有点痛苦,但是我们最终还是做到了。