Kettle WebService组件无法传参问题解决
2016-05-30 14:00
363 查看
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,暂时不考虑修复,如果你有好的修复方式,也请联系下我,愿意请教请教。
相关文章推荐
- ASP.NET WebService中使用ASP.NET_SessionId的问题说明
- ASP.NET中基于soaphead的webservice安全机制
- ASP调用WebService转化成JSON数据,附json.min.asp
- js调用webservice构造SOAP进行身份验证
- ajax跨域调用webservice的实现代码
- ASP.NET调用WebService服务的方法详解
- php的webservice的wsdl的XML无法显示问题的解决方法
- PHP调用Webservice实例代码
- 在PHP中利用wsdl创建标准webservice的实现代码
- JQuery调webservice实现邮箱验证(检测是否可用)
- WebService出现"因 URL 意外地以 结束,请求格式无法识别"的解决方法
- 用JavaScript调用WebService的示例
- jQuery调用WebService返回JSON数据及参数设置注意问题
- 同步调用和异步调用WebService
- C#调用WebService实例开发
- 动态webservice调用接口并读取解析返回结果
- WebService 的简单封装接口调用方法
- ASP.NET实现基于Forms认证的WebService应用实例
- C#使用WebService结合jQuery实现无刷新翻页的方法
- C#调用和实现WebService,纯手工打造!