繁体   English   中英

使用Camel,CXF和ProxyBuilder / ProxyHelper调用SOAP-WS

[英]Calling SOAP-WS with Camel, CXF and ProxyBuilder/ProxyHelper

我正在尝试使用apache camel(2.14.1版)和cxf(3.0.3版)进行简单的(SOAP)Web服务调用。

我要调用的远程方法需要一个float并返回一个float:

public float getVolume(float vol) {
    float f = vol * vol;
    return f;
}

我设法在ProducerTemplate的帮助下调用了它。 这工作正常。
现在,我想像对象方法那样调用它。 为此,我正在使用像这样的ProxyBuilder

TestService service = new ProxyBuilder(context).endpoint(endpoint).build(TestService.class);  

作为ProxyBuilder的替代,可以使用ProxyHelper ,这没有什么区别。
我的路线:

String cxfUri = "cxf:http://localhost/9202/testService?serviceClass=" + TestService.class.getName();
from("direct:start").log("${body}").process(new Processor() {

    @Override
    public void process(Exchange e) throws Exception {
        final BeanInvocation bi = e.getIn().getBody(BeanInvocation.class);
        e.getIn().setBody(bi.getArgs());
    }
}).to(cxfUri);

(从这里得到提示: 骆驼:CXF端点的Bean代理
如果我这样调用方法:

System.out.println("Volume: " + service.getVolume(42f));

出现以下异常:

org.apache.camel.InvalidPayloadException: No body available of type: float but has value: [1764.0] of type: org.apache.cxf.message.MessageContentsList on: Message: [1764.0]. Caused by: No type converter available to convert from type: org.apache.cxf.message.MessageContentsList to the required type: float with value [1764.0].

如果我的方法返回String,则一切正常。
我读到BeanInvocation中的值必须是可序列化的。
这是问题所在(返回原始类型)吗?
另外,如果服务提供了两种方法(第一种返回字符串,第二种返回浮点数),则它将尝试将浮点数转换为String。
我尝试了不同的cxf版本(2.7.14),不同的路由并在路由定义中使用了一些选项,例如定义WSDL位置,将模式设置为有效负载,定义默认操作。

我还在互联网上搜索了几个小时,但没有找到有效的提示。

有人能告诉我我做错了什么吗?

编辑:
通过向路由添加第二个处理器来解决第一个问题:

from("direct:start").process(new Processor() {

    @Override
    public void process(Exchange e) throws Exception {
        BeanInvocation bi = e.getIn().getBody(BeanInvocation.class);
        e.getIn().setBody(bi.getArgs());
    }
}).to(cxfUri).process(new Processor() {

    @Override
    public void process(Exchange e) throws Exception {
        MessageContentsList list = e.getIn().getBody(MessageContentsList.class);
        if (list.size() > 0) {
            e.getIn().setBody(list.get(0));
        }
    }
});  

这没有解决第二个问题:

另外,如果服务提供了两种方法(第一种返回字符串,第二种返回浮点数),则它将尝试将浮点数转换为String。

发生以下异常:

线程“主”中的异常org.apache.cxf.interceptor.Fault:无法将org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor.handleMessage(WrapperClassOutInterceptor.java:117上的java.lang.Float强制转换为java.lang.String )位于org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516)位于org.apache.cxf.endpoint.ClientImpl。的org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307) org.org.apache.camel.component.cxf.CxfProducer.process(CxfProducer.java:112)的org.apache.camel.processor.SendProcessor.process(SendProcessor.java:120)的invoke(ClientImpl.java:418) org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:416)上的.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)在org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor .java:191),位于org.apache.camel.processor.Pipeline.proces(Pipeline.java:118),位于org.apache.camel.processor.Pipeline.proces 在org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)在org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:105)处的s(Pipeline.java:80) org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:40)的.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:87)org.apache.camel.component.bean.AbstractCamelInvocationHandler $ 1。在org.apache上的org.apache.camel.component.bean.AbstractCamelInvocationHandler.invokeWithBody(AbstractCamelInvocationHandler.java:128)上的java.util.concurrent.FutureTask.run(FutureTask.java:262)上调用(AbstractCamelInvocationHandler.java:110) org.apache.camel.component.bean.Abstract.CamelIncomponentHandler.invoke(AbstractCamelInvocationHandler.java:82)中的.camel.component.bean.CamelInvocationHandler.doInvokeProxy(CamelInvocationHandler.java:45)在com.sun.proxy。$ Proxy6.getVolume(来源:soapTest.client.TestServiceClientCXF.main(TestServiceClie) ntCXF.java:49)原因:java.lang.ClassCastException:java.lang.Float无法在org.apache.cxf.jaxws的soapTest.service.GetName_WrapperTypeHelper1.createWrapperObject(Unknown Source)处转换为java.lang.String。 Interceptor.WrapperClassOutInterceptor.handleMessage(WrapperClassOutInterceptor.java:101)...另外21个

最后,我找到了答案。
错误是使用org.apache.camel.builder.ProxyBuilder
它与cxf不完全兼容。
相反,必须将org.apache.cxf.common.util.ProxyHelper与自己的调用处理程序一起使用:

final ProducerTemplate template = context.createProducerTemplate();
final Endpoint endpoint = context.getEndpoint("direct:start");

ClassLoader classLoader = context.getApplicationContextClassLoader();
InvocationHandler invocationHandler = new InvocationHandler() {

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return template.requestBodyAndHeader(endpoint, args, "operationName", method.getName(), method.getReturnType());
    }
};

TestService service = (TestService) ProxyHelper.getProxy(classLoader, new Class[] {TestService.class}, invocationHandler);    

路由也需要一个处理器(不返回简单类型将不起作用):

from("direct:start").to(cxfUri).process(new Processor() {

    @Override
    public void process(Exchange exchange) throws Exception {
        MessageContentsList list = exchange.getIn().getBody(MessageContentsList.class);
        if (list.size() > 0) {
            exchange.getIn().setBody(list.get(0));
        }
    }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM