kettle中有兩種方式請求webservice服務,一個是Web服務查詢,但是這個有缺陷,無法處理復雜的需求,遇到這種情況就需要用Http post來處理了。
網上也有很多關於Http post請求webservice服務的,但是無一例外的都對請求響應后的結果沒有做出處理的教程,調用結果最終目的是為了拿到數據,有時候返回的是一個xml格式的集合,就需要用【XML文件輸入】來解析每一個節點。而SOAP標准的響應結果不能直接用【XML文件輸入】進行解析,下面就針對這種情況該如何處理做個簡單的介紹。
轉換腳本預覽:
主要包括獲取變量、設置參數(SOAP請求入參)、發起請求(Http post)、獲取body(過濾soap響應結果)、解析xml等;
第一步:獲取變量
這里定義入參的值,模擬作業情況下上一步驟傳過來的參數,這里直接設置默認值,在下一個步驟中使用。
我這里定義了三個參數,分別為orgCode、deptCode、staffName。
第二步:設置參數
這里主要是安裝SOAP接口參數格式定義入參,他有一定標准的格式,其中藍色框是接口的真正入參,動態變化的是紅色框,也就是上一步傳進來的參數,通過占位符的方式賦值。
這里用到了E4X,E4X 是添加了對 XML 支持的 JavaScript 正式標准,通過 E4X,可以通過聲明變量的方法來聲明 XML 對象變量;
第三步:發起請求
需要填入接口地址,選擇字符編碼為UTF-8,上一步驟傳過來的入參,及響應結果變量名稱,另外根據接口情況可能還需要設置頭部信息之類的,在Fields頁面設置,我的接口不需要,這里就不做展示。
第四步:獲取body
下面是我的webService接口通過SoapUI工具測試的響應的結果示例:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getDataResponse xmlns:ns2="http://webservice.ks.com">
<ns2:return>
<result>
<staff>
<identityNo>身份證號碼0</identityNo>
<employeNo>工牌號0</employeNo>
<spellCode>拼音碼0</spellCode>
<deptName>所屬部門名稱0</deptName>
<sexCode>性別代碼0</sexCode>
<staffNo>員工內部號0</staffNo>
<sexName>性別名稱0</sexName>
<staffName>員工姓名0</staffName>
<account>賬戶0</account>
<staffBirthdate>出生日期0</staffBirthdate>
<deptCode>所屬部門代碼0</deptCode>
</staff>
<!-- 以下忽略部分staff-->
</result>
<code>100</code>
<success>true</success>
<message>查詢成功</message>
</ns2:return>
</ns2:getDataResponse>
</soap:Body>
</soap:Envelope>
我的目的是獲取到節點result下的所有staff節點的內容,所以需要用到【XML文件輸入】來解析這些節點。但是如果直接把響應結果進行解析,不管選擇那個節點,執行時會報錯:Can not apply XPath!
所以需要通過JavaScript腳本解析響應結果,只獲取Body下的返回值內容:
其中轉義符轉換可以忽略,因為我的webservice接口通過http post請求返回的結果將<>符號進行轉義,所以需要轉成符號才可以進行下一步。
kettle中JavaScript腳本沒有replaceAll()函數,所以如果要替換所有就需要用到正則表達式去找到要替換的內容。
首先是將Http post請求響應的字符串結果創建一個出XML對象,然后獲取soap的命名空間及響應結果的命名空間,根據這些信息拿到響應結果的body部分,最后轉成格式化的字符串輸出。
最終responseXML為:
<ns2:getDataResponse xmlns:ns2="http://webservice.ks.com">
<ns2:return>
<result>
<staff>
<identityNo>身份證號碼0</identityNo>
<employeNo>工牌號0</employeNo>
<spellCode>拼音碼0</spellCode>
<deptName>所屬部門名稱0</deptName>
<sexCode>性別代碼0</sexCode>
<staffNo>員工內部號0</staffNo>
<sexName>性別名稱0</sexName>
<staffName>員工姓名0</staffName>
<account>賬戶0</account>
<staffBirthdate>出生日期0</staffBirthdate>
<deptCode>所屬部門代碼0</deptCode>
</staff>
<!-- 以下忽略部分staff-->
</result>
<code>100</code>
<success>true</success>
<message>查詢成功</message>
</ns2:return>
</ns2:getDataResponse>
再用【XML文件輸入】來解析responseXML就成功了
后來,我驚訝的發現,獲取body這個步驟這么復雜,目的不就是只取getDataResponse嗎,那我是不是可以通過replace()函數把前后部分去掉呢?
於是我的獲取body步驟變成了:
然后打印輸出到excel也是可以的: