Kettle WebService组件无法传参问题解决

原创 2016年05月30日 14:00:17

1. Kettle WebService组件

kettle WebService转换组件【Web 服务查询】可以用来调用我们发布的webservice。

2. WebService组件使用限制

在使用的过程中,发现这个组件存在一些使用上的限制,如下说明:

(1) 不能调用wsdl和xsd分离的webservice,在点击“加载”按钮会抛异常。首先Spoon弹出对话框提示错误:

Could not find the schema with the name xxx within the specified wsdl.

详细异常堆栈如下所示:

org.pentaho.di.core.exception.KettleStepException: 
Could not retrieve WSDL Operator for operation name: sayHello

Could not find the schema with the name {http://jws.com/}sayHello within the specified wsdl.


    at org.pentaho.di.trans.steps.webservices.wsdl.Wsdl.getOperation(Wsdl.java:216)
    at org.pentaho.di.trans.steps.webservices.wsdl.Wsdl.getOperations(Wsdl.java:236)
    at org.pentaho.di.ui.trans.steps.webservices.WebServiceDialog.loadWebService(WebServiceDialog.java:233)
    at org.pentaho.di.ui.trans.steps.webservices.WebServiceDialog.initTreeTabWebService(WebServiceDialog.java:365)
    at org.pentaho.di.ui.trans.steps.webservices.WebServiceDialog.access$11(WebServiceDialog.java:362)
    at org.pentaho.di.ui.trans.steps.webservices.WebServiceDialog$5.widgetSelected(WebServiceDialog.java:870)
    at org.eclipse.swt.widgets.TypedListener.handleEvent(Unknown Source)
    at org.eclipse.swt.widgets.EventTable.sendEvent(Unknown Source)
    at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Unknown Source)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source)
    at org.pentaho.di.ui.trans.steps.webservices.WebServiceDialog.open(WebServiceDialog.java:1295)
    at org.pentaho.di.ui.spoon.delegates.SpoonStepsDelegate.editStep(SpoonStepsDelegate.java:124)
    at org.pentaho.di.ui.spoon.Spoon.editStep(Spoon.java:8777)
    at org.pentaho.di.ui.spoon.trans.TransGraph.editStep(TransGraph.java:3027)
    at org.pentaho.di.ui.spoon.trans.TransGraph.mouseDoubleClick(TransGraph.java:744)
    at org.eclipse.swt.widgets.TypedListener.handleEvent(Unknown Source)
    at org.eclipse.swt.widgets.EventTable.sendEvent(Unknown Source)
    at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Unknown Source)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source)
    at org.pentaho.di.ui.spoon.Spoon.readAndDispatch(Spoon.java:1317)
    at org.pentaho.di.ui.spoon.Spoon.waitForDispose(Spoon.java:7958)
    at org.pentaho.di.ui.spoon.Spoon.start(Spoon.java:9290)
    at org.pentaho.di.ui.spoon.Spoon.main(Spoon.java:654)
Caused by: org.pentaho.di.core.exception.KettleStepException: 
Could not find the schema with the name {http://jws.com/}sayHello within the specified wsdl.

    at org.pentaho.di.trans.steps.webservices.wsdl.WsdlTypes.findNamedElement(WsdlTypes.java:86)
    at org.pentaho.di.trans.steps.webservices.wsdl.WsdlOpParameterList.resolvePartElement(WsdlOpParameterList.java:220)
    at org.pentaho.di.trans.steps.webservices.wsdl.WsdlOpParameterList.getParameter(WsdlOpParameterList.java:141)
    at org.pentaho.di.trans.steps.webservices.wsdl.WsdlOpParameterList.add(WsdlOpParameterList.java:107)
    at org.pentaho.di.trans.steps.webservices.wsdl.WsdlOperation.loadParameters(WsdlOperation.java:232)
    at org.pentaho.di.trans.steps.webservices.wsdl.WsdlOperation.<init>(WsdlOperation.java:111)
    at org.pentaho.di.trans.steps.webservices.wsdl.Wsdl.getOperation(Wsdl.java:210)
    ... 24 more

(2) 调用不同标准发布的webservice可能会出现参数无法传递到实际webservice调用方法的情况。

在测试的时候发现,采用不同的技术来发布webservice,如CXF、Asix2等,均会出现参数无法传递到实际的webservice调用方法的情况。

3. 解决限制

在我们的实际项目中并不会发布wsdl和xsd分离的webservice,因此第1点暂时不在我们的考虑范围之内。

然而第2点严重影响了webservice组件的使用。由于我们的使用需求,必须要修复这个缺陷。

通过调试源码发现原因:
WsdlOpParameterList这个类的resolvePartElement方法不能正确解析参数值,因此我们通过改造这个方法来修复这个bug,改造后的resolvePartElement方法如下所示:

private List<WsdlOpParameter> resolvePartElement( Part p ) throws KettleStepException {

    List<WsdlOpParameter> resolvedParams = new ArrayList<WsdlOpParameter>();
    Element schemaElement = _wsdlTypes.findNamedElement( p.getElementName() );

    if ( schemaElement.hasAttribute( WsdlUtils.ELEMENT_TYPE_ATTR ) ) {

        String eleName;

        String typeValue = schemaElement.getAttribute("type");
        String tns = typeValue.split(":")[0];
        if (!"xsd".equals(tns)) {
          String complexTypeName = typeValue.split(":")[1];
          ComplexType complexType = this._wsdlTypes.getNamedComplexTypes().getComplexType(complexTypeName);
                for (Iterator<String> localIterator = complexType.getElementNames()
                        .iterator(); localIterator.hasNext();) {
                    eleName = (String) localIterator.next();
                    QName qName = this._wsdlTypes.getTypeQName(typeValue);
                    resolvedParams.add(new WsdlOpParameter(eleName,
                            this._wsdlTypes.findNamedType(qName),
                            this._wsdlTypes));
                }
        }
        else {
             // this is a simple type
            resolvedParams.add( new WsdlOpParameter( p.getName(), schemaElement, _wsdlTypes ) );
        }

    } else {
      // this is a complex type
      Element complex = DomUtils.getChildElementByName( schemaElement, WsdlUtils.COMPLEX_TYPE_NAME );
      Element sequence = DomUtils.getChildElementByName( complex, WsdlUtils.SEQUENCE_TAG_NAME );

      // may occasionally find a <complex/> tag map to empty but this may be a bug in WSM
      //
      if ( sequence == null ) {
        return resolvedParams;
      }

      List<Element> seqElements = DomUtils.getChildElementsByName( sequence, WsdlUtils.ELEMENT_NAME );

      for ( Element e : seqElements ) {
        WsdlOpParameter op = new WsdlOpParameter( e, _wsdlTypes );

        // special case for bare arrays, change the name of the param
        // to the name of the complex type.
        if ( op.isArray() && _parameterStyle == WsdlOperation.SOAPParameterStyle.BARE ) {
          op.setName( schemaElement.getAttribute( WsdlUtils.NAME_ATTR ), _wsdlTypes );
        }
        resolvedParams.add( op );
      }
    }
    return resolvedParams;
  }

修改完后需要重新编译得到WsdlOpParameterList.class,并使用这个class文件替换原来的class文件,这个文件所在的位置如下:

kettle安装目录 /lib子目录 kettle-engine-xxx.jar

用解压工具打开并实现替换:

替换文件包目录:

org/pentaho/di/trans/steps/webservices/wsdl

为了方便大家快速替换,直接提供这个修改后的文件:

http://pan.baidu.com/s/1kVctSY7

大家可以在上面的百度云链接地址下载编译好的修改文件,直接替换原来的文件即可。

【温馨提示】

1) 修复后测试CXF和Axis2发布的WebService均能成功传递参数,其他发布方式并没有测试过,如果在使用过程中发现这个修复并不生效,可以与我联系。

2) 对于限制1,暂时不考虑修复,如果你有好的修复方式,也请联系下我,愿意请教请教。

版权声明:本文为博主原创文章,未经博主允许不得转载。

一个Kettle异常的解决方式

最近kettle中的几个转换抛出如下异常: Because of an error, this step can't continue:  org.pentaho.di.core.exception...
  • shuishouhcd
  • shuishouhcd
  • 2013年09月23日 12:40
  • 6094

kettle连接mysql错误连接数据库org.pentaho.di.core.exception.KettleDatabaseException

错误连接数据库 [MySql-1] :org.pentaho.di.core.exception.KettleDatabaseException: Erroroccured while trying...
  • philip502
  • philip502
  • 2014年01月02日 19:04
  • 12806

KETTLE_内存溢出错误

原创作品,出自 “深蓝的blog” 博客,欢迎转载,转载时请务必注明以下出处,否则追究版权法律责任。 深蓝的blog:   kettle内存溢出错误解决 环境: 源端数据库:oracle 10G R2...
  • huangyanlong
  • huangyanlong
  • 2015年01月06日 08:57
  • 14056

Kettle表输出报关闭的连接问题的解决方法

Kettle表输出报关闭的连接问题的解决方法最近在使用Kettle的时候表输出有时候会报一个错误 关闭的连接在网上查了半天都没有找到解决办法 现在记录一下解决过程以备后用。软件环境-Oracle 1...
  • zhaizhisheng
  • zhaizhisheng
  • 2016年01月25日 15:11
  • 4379

Webservice接口数据抽取_kettel<一>

kettel
  • a275838263
  • a275838263
  • 2016年05月03日 10:23
  • 7291

kettle调用webservice

当我们往数据库迁移数据时,如果对有些数据有特定的生成规则要求我们可以先写webservice再用kettle调用webservice去生成相应的数据。 首先我们需要一个表输入控件和一个webser...
  • weixin_39937329
  • weixin_39937329
  • 2017年12月04日 15:25
  • 183

在ETL工具Spoon中调用WebService的方法

在ETL工具Spoon中调用WebService的方法: Spoon是开源kettle的pentaho工具中data integration工具。 1. 新建转换,添加SOAP请求的"Mo...
  • mylitboy
  • mylitboy
  • 2012年09月20日 21:59
  • 7356

kettle+java代码调用Webservice

kettle中的Webservice服务查询控件功能挺强大的,可以调用大多数的Webservice服务。但是最近遇到一个问题:如果传参是XML时,XML中的  这样的符号kettle会识别不了,导致调...
  • a275838263
  • a275838263
  • 2016年07月28日 16:01
  • 3924

Webservice接口数据抽取_Kettel<二>

java
  • a275838263
  • a275838263
  • 2016年05月03日 10:25
  • 2552

Kettle通过Webservice获取天气信息

需求: 通过kettle工具,通过webservice获取天气信息,写成xml格式文件。     思路: Kettle可通过两种选择获...
  • JIESA
  • JIESA
  • 2015年11月29日 20:07
  • 2232
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Kettle WebService组件无法传参问题解决
举报原因:
原因补充:

(最多只允许输入30个字)