【案例】Kettle通过Http post请求webservice接口以及结果解析处理

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

posted @ 2021-06-11 17:56  程序员微尘  阅读(10918)  评论(0编辑  收藏  举报