Kettle通過Http post請求webservice介面以及結果解析處理

蒲公英不是夢發表於2021-06-11

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也是可以的:

相關文章