我在這一天的工作,得到了同樣的問題時,我們必須注入過定義成從銀行Web服務公開一個WSDL的數據結構的字段中的文本CDATA節。
要求是引入CDATA部分以將Unicode字符「+」轉義爲數字電話字段。 WSDL不可能因各種動機而改變。
我們有相同的環境:
org.springframework.oxm.jaxb.Jaxb2Marshaller
webServiceTemplate.marshalSendAndReceive(payloadRequest, SoapActionCallback)
和相同的失敗結果
<![CDATA[<tag>+<\tag>
,而不是
<[[CDATA[+]]>
經過多次和許多測試之後對諮詢很多字體Stackoverflow和其他網站,我們已經瞭解到該解決方案並非由JAXB eng本機支持ine,並且需要將SOAP消息操作爲處理請求的雙重步驟。
其他的解決方案表明使用第三方插件和庫,廣告例如莫西,到CDATA節還JAXB的實現了強有力的支持。但是這種解決方案不可能在ASAP的形式中快速集成到巨大的企業應用程序中。
此解決方案,我在此回覆許可證發佈使用經典對象爲DOMSource鑄造從MessageContext的消息SOAP的規範的方法中注入的CDATASection。
在你的答案中,你公開了解決方案的一部分,這是marshalSendAndReceive的回調。
如果您定義了marshalSendAndReceive
方法支持的臨時回調,並且在此回調中操縱注入CDATASection的DOMSource,則可以解決此問題。
這是代碼:
WebServiceMessageCallback callbackCDATANumTelefono = new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) {
//Recover the DOMSource dal message soap
DOMSource domSource = (DOMSource)message.getPayloadSource();
//recover set of child nodes of domsource
NodeList nodeList = domSource.getNode().getChildNodes();
//definisco il nome del tag da cercare
String nameNumTel = "ns2:sNumTel"; //in this example, but you can define another QName string to recover the target node (or nodes)
Node nodeNumTel = null;
for (int i = 0; i < nodeList.getLength(); i++) {
//search of text node of this tag name
if (nodeList.item(i).getNodeName().compareTo(nameNumTel) == 0) {
nodeNumTel = nodeList.item(i);
break;
}
}
//recover the string value (in this case of telephone number)
String valueNumTelefono = nodeNumTel.getTextContent();
//clean of value of target text node
nodeNumTel.setTextContent("");
//define and inject of CDATA section, in this case encapsulate "+" character
CDATASection cdata = nodeNumTel.getOwnerDocument().createCDATASection("+");
//create of new text node
Text tnode = nodeNumTel.getOwnerDocument().createTextNode(valueNumTelefono);
//append of CDATASection (in this point is possible to inject many CDATA section on various parts of string (very usefull)
nodeNumTel.appendChild(cdata);
nodeNumTel.appendChild(tnode);
//done!
}
};
這個回調函數將被從marshalSendAndReceive
PayloadSoapResponse output = (PayloadSoapResponse) getWebServiceTemplate()
.marshalSendAndReceive(input, callbackCDATANumTelefono);
調用的結果是與CDATA部分有效並以ASCII字符不轉換請求正確的發送。
該解決方案的目標是使用JAXB技術在Spring基礎結構上操縱CDATA節,而不是使用第三方庫。 一般來說,回調方法的指令集非常值得信賴,並且在web服務soap的所有環境中都很好注入。關鍵的方面是將SoapMessage轉換爲更加友好的DOMSource,並使用規範的方法來探索節點。也可以使用XPath引擎來導航此DOMSource。
祝你好運!
是