欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用dubbo直接调用webservice

程序员文章站 2022-05-11 15:14:46
...

       场景:他人的服务端暴露的webservice接口,我这边客户端集成了dubbo,所以想用dubbo直接去调用webservice。因为dubbo的官方文档上说dubbo有提供这些功能。

      dubbo版本2.3.0以上版本支持。需要在pom里添加依赖,它是基于CXF的frontend-simpletransports-http实现。maven依赖:

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-simple</artifactId>
    <version>2.6.1</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>2.6.1</version>
</dependency>

 具体做法是:

如果webservice的接口是:http://172.16.123.xxx:8880/xxx/webservice/com.xxx.riviews.webservice.ITongdunService?wsdl

则在dubbo的xml配置里添加

<dubbo:reference id="tongdunServicePortType" interface="com.hylandtec.riviews.webservice.ITongdunService" url="webservice://172.16.123.xxx:8880/xxx/webservice/com.xxx.riviews.webservice.ITongdunService?wsdl"/>

 即把url中的http改成webservice,作为dubbo配置中的url,形成点对点的访问。

实际的接口ITongdunService,注意包的路径:

package com.xxxx.riviews.webservice;

/**
 * 同盾接口
 * Created by cd_huang on 2017/4/19.
 */
public interface ITongdunService {
	/**
     *
     * @param arg0
     * @param arg1
     * @return
     */
    String query(String arg0,String arg1);
}

 接口的方法和参数对应webservice声明的方法和参数。

使用的时候在调用的类里加上

@Autowired
	private ITongdunService tongdunServicePortType;

 

String result = tongdunServicePortType.query(arg0, arg1);

 即可完成webservice的调用。

      这样子调用有个很麻烦的地方,那就是,我接口所在的包路径被定死掉了。然后我就想着能不能用dubbo的泛化调用,即客户端不需要拥有服务端对应的api也能访问的方式。

      在

<dubbo:reference id="tongdunServicePortType" interface="com.hylandtec.riviews.webservice.ITongdunService" url="webservice://172.16.123.xxx:8880/xxx/webservice/com.xxx.riviews.webservice.ITongdunService?wsdl"/>
 中加入generic="true"配置。
@Autowired
	private GenericService tongdunServicePortType;
 调用则为
String result =tongdunServicePortType.$invoke("query", new String[]{"java.lang.String","java.lang.String"}, new Object[] {arg0,arg1}).toString();
 完成一个泛化调用。
然后是运行结果:
com.alibaba.dubbo.rpc.RpcException: Failed to invoke remote service: interface com.alibaba.dubbo.rpc.service.GenericService, method: $invoke, cause: Error reading XMLStreamReader.

	at com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol.getRpcException(AbstractProxyProtocol.java:118)
	at com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol$2.doInvoke(AbstractProxyProtocol.java:98)
	at com.alibaba.dubbo.rpc.protocol.AbstractInvoker.invoke(AbstractInvoker.java:144)
	at com.alibaba.dubbo.rpc.listener.ListenerInvokerWrapper.invoke(ListenerInvokerWrapper.java:74)
	at com.onlyou.olyfinance.remote.filter.RemoteTestFilter.invoke(RemoteTestFilter.java:22)
	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
	at com.alibaba.dubbo.rpc.filter.GenericImplFilter.invoke(GenericImplFilter.java:138)
	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
	at com.alibaba.dubbo.rpc.protocol.dubbo.filter.FutureFilter.invoke(FutureFilter.java:53)
	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
	at com.alibaba.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:75)
	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
	at com.alibaba.dubbo.rpc.filter.ConsumerContextFilter.invoke(ConsumerContextFilter.java:48)
	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
	at com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:52)
	at com.alibaba.dubbo.common.bytecode.proxy3.$invoke(proxy3.java)
	at com.onlyou.olyfinance.remote.DemoTestRemote.tongdunTest(DemoTestRemote.java:83)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: org.apache.cxf.binding.soap.SoapFault: Error reading XMLStreamReader.
	at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:84)
	at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:51)
	at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:40)
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
	at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:113)
	at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
	at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
	at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:811)
	at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1590)
	at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1486)
	at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1305)
	at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
	at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:623)
	at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
	at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:541)
	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474)
	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377)
	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330)
	at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
	at org.apache.cxf.frontend.ClientProxy.invoke(ClientProxy.java:81)
	at com.sun.proxy.$Proxy30.$invoke(Unknown Source)
	at com.alibaba.dubbo.common.bytecode.Wrapper3.invokeMethod(Wrapper3.java)
	at com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:46)
	at com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:72)
	at com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol$2.doInvoke(AbstractProxyProtocol.java:93)
	... 47 more
 报错了。debug后发现,泛化调用并不会直接在客户端把$invoke方法改成调用query方法,所以在进入cxf的代码里时,去调用的还是$invoke方法,和webservice声明的query方法不符合,导致webservice解析SOAP的xml协议报错了。看来泛化调用只能在调用的两端都是dubbo的情况下来使用,这是dubbo预留的机制,有点类似Rest调用。