將字串轉換為 SOAPMessage
1. 簡介
在本教學中,我們將探討如何將原始 SOAP XML 字串轉換為 Java 中可用的SOAPMessage
物件。
SOAPMessage
是基於 XML 的訊息傳遞的 Java API (SAAJ) 的一部分,代表完整的 SOAP 請求或回應,包括信封、標頭和正文。
2. 使用SAAJ MessageFactory
第一種方法使用javax.xml.soap
套件提供的標準MessageFactory
。該工廠直接從輸入流建立SOAPMessage
。原始字串被轉換為位元組流並傳遞給工廠,工廠建構結構化的 SOAP 訊息。
以下是名為usingSAAJMessageFactory(),
該方法執行此轉換:
static SOAPMessage usingSAAJMessageFactory(String soapXml) throws Exception {
ByteArrayInputStream input = new ByteArrayInputStream(soapXml.getBytes(StandardCharsets.UTF_8));
MessageFactory factory = MessageFactory.newInstance();
return factory.createMessage(null, input);
}
在上面的範例中,我們首先將原始 SOAP 字串轉換為基於位元組的輸入流。這是因為MessageFactory
中的createMessage()
方法需要一個InputStream
。我們使用StandardCharsets.UTF_8
來確保在轉換過程中保留字元編碼。
一旦準備好流,我們就呼叫MessageFactory.newInstance()
來取得預設實現,然後呼叫createMessage()
將流解析為SOAPMessage
。
接下來,我們準備一個代表股票價格請求的範例 SOAP 字串:
String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"<soapenv:Header/>" +
"<soapenv:Body>" +
"<m:GetStockPrice xmlns:m=\"http://example.com/stock\">" +
"<m:StockName>GOOG</m:StockName>" +
"</m:GetStockPrice>" +
"</soapenv:Body>" +
"</soapenv:Envelope>";
SOAPMessage message = SoapParser.usingSAAJMessageFactory(xml);
讓我們使用一些斷言來驗證結果的正確性:
SOAPBody body = message.getSOAPBody();
assertNotNull(message, "SOAPMessage should not be null");
assertNotNull(body, "SOAP Body should not be null");
assertTrue(body.getTextContent().contains("GOOG"), "Expected 'GOOG' not found in the SOAP body");
對於需要完全存取 SOAP 訊息元件(包括信封、標題和正文)的情況,此解決方案非常理想。
3. 使用 DOM 解析
從字串建立 SOAPMessage 的另一種方法是先使用 DOM(文檔對像模型)API 將 XML 解析為Document
對象,然後使用該 DOM 表示來填入SOAPPart
。
讓我們定義一個名為usingDOMParsing()
的實用方法來示範這個方法:
static SOAPMessage usingDOMParsing(String soapXml) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream(soapXml.getBytes(StandardCharsets.UTF_8)));
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();
SOAPPart part = message.getSOAPPart();
part.setContent(new DOMSource(doc.getDocumentElement()));
message.saveChanges();
return message;
}
在這個方法中,我們首先建立一個啟用了命名空間感知的DocumentBuilderFactory
這對於正確解析 SOAP 訊息至關重要,因為SOAP 嚴重依賴 XML 命名空間。然後我們建立一個DocumentBuilder
並使用它將輸入的 SOAP 字串解析為Document
物件。
一旦我們有了 SOAP 內容的 DOM 表示,我們就使用MessageFactory
初始化SOAPMessage
。我們檢索此訊息的SOAPPart
,並使用setContent()
方法將其內容替換為包裝已解析文件的根元素的DOMSource
。
最後,我們呼叫saveChanges()
來完成訊息結構。
為了測試此實現,我們可以使用與先前相同的範例 SOAP XML 字串:
SOAPMessage message = SoapParser.usingDOMParsing(xml);
然後我們應用類似的斷言來驗證產生的SOAPMessage
的正確性:
SOAPBody body = message.getSOAPBody();
assertNotNull(message, "SOAPMessage should not be null");
assertNotNull(body, "SOAP Body should not be null");
assertTrue(body.getTextContent().contains("GOOG"), "Expected 'GOOG' not found in the SOAP body");
這種方法為我們提供了更大的靈活性,特別是當我們需要在建立SOAPMessage
之前更改 XML 結構時。當使用已經使用Document
物件來處理 XML 的系統時它也很有用。
4. 結論
在本文中,我們學習如何將 SOAP XML 字串轉換為SOAPMessage
。 MessageFactory
方法更簡單,適合直接轉換。基於 DOM 的方法提供了更多的控制,當我們需要在建構 SOAP 訊息之前處理或修改 XML 時很有用。
與往常一樣,原始碼可在 GitHub 上取得。