当前位置: 首页 > 知识库问答 >
问题:

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

扶誉
2023-03-14

我正在尝试使用apache camel(版本2.14.1)和cxf(版本3.0.3)进行一个简单的(SOAP)webservice调用。

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

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

我在一位生产工人的帮助下设法把它叫来了。这很好用<现在我想像调用对象的方法一样调用它。为此,我使用的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);

(从这里得到提示:Camel:Bean代理到CXFendpoint)
如果我这样调用该方法:

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].

如果我的方法返回一个字符串,则一切正常
我读到BeaninJournal中的值必须是可序列化的
这就是问题所在(返回基元类型)<此外,如果服务提供两种方法(第一种返回字符串,第二种返回浮点),它会尝试将浮点转换为字符串
我尝试了不同的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));
        }
    }
});  

这并没有解决第二个问题:

此外,如果服务提供两个方法(第一个返回字符串,第二个返回浮点),它会尝试将浮点转换为字符串。

发生以下异常:

线程"main"rocessor.java:120中的异常:org.apache.camel.management.Float无法转换为rocessor.java:72WrapperClassOutInterceptor.handle消息(WrapperClassOutInterceptor.java:117)org.apache.cxf.phase.PhaseInterceptorCorg.apache.camel.processor.拦截(PhaseInterceptorCrocessor.process)rocessor.java:191ClientIorg.apache.camel.processor.调用(ClientIipeline.process)在ipeline.java:118ClientImpl.invoke(ClientImpl.java:418)在org.apache.camel.component.cxf.CxfProducer.process(CxfProducer.java:112)在org.apache.camel.processor.SendProcessor.process(SendPorg.apache.cxf.interceptor.)在java.lang.InstrumentationPjava.lang.(InstrumentationPorg.apache.cxf.jaxws.interceptors.)在hain.doCamelInternalPhain.java:307(CamelInternalPorg.apache.cxf.endpoint.)在mpl.doPmpl.java:516(Porg.apache.cxf.endpoint.)在org. apache. camel. Procor. CamelInternalProcessor(CamelInternalProcessor. java: 80)在org. apache. camel.soapTest. client上的$Proxy6. getVolume(未知来源)。TestServiceClientCXF. main(TestServiceClientCXF. java: 49)由:java. lang引起。ClassCastException:java. lang。浮点数无法转换为java. lang。soapTest. service上的字符串。GetName_WrapperTypeHelper1. createWrapperObject(未知来源)在org. apache. cxf. jaxws.拦截器。WrapperClassOutInterceptor. handleMessage(WrapperClassOutInterceptor. java: 101)...21更多

共有1个答案

徐杰
2023-03-14

最后,我找到了答案<错误是使用了组织。阿帕奇。骆驼建设者ProxyBuilder
它与cxf不完全兼容
取而代之的是组织。阿帕奇。cxf。常见的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));
        }
    }
});
 类似资料:
  • 我正在尝试编写一个SOAP Web服务: 接受一种请求类型 A 将请求 A 映射到另一个出站请求类型 B 将请求 B 发送到外部 SOAP 服务 将响应 B 映射回响应 A 对象(并返回它) 当endpoint(B)静态配置时,我有这个工作。 但我希望能够使用不同的请求/响应类型来访问各种服务。这些可能通过属性文件进行配置。 有没有可能以某种通用/动态的方式做到这一点? 这是我的Spring骆驼X

  • 下面是我正在使用的代码:

  • 我正在使用Camel,并使用CXF从WSDL生成代码。我生成了一个客户端存根,实现如下所示: 如您所见,端口接受两个参数并返回响应,我想将其委托回我的骆驼路由。在 Camel 中实现这一点的最佳方法是什么?我已经定义了我的 CXF Enpoint,我只是在努力解决其中的 DSL 路由部分。我应该添加像此链接中那样的处理器吗?Apache Camel和Web服务 谢谢

  • 我是Apache Camel的新手,我使用Red Hat Code准备工作室12.16.0.GA.我想调用肥皂网络服务。我用过这个例子https://tomd.xyz/camel-consume-soap-service/ 这是我的camel上下文文件 这是我的输入bean 围绕它有许多问题。首先,我不能将输入参数传入主体。我试着像这样设置身体 但没有得到响应或只是没有记录。我已经尝试使用bean

  • 我正在尝试将Apache CXF与Apache Camel集成。骆驼的配置: 现在,为了调用web服务上的特定操作,我使用以下方法: 但是在包含上述配置后,我得到< code > WARN servlet controller:149-在服务器控制台上找不到对http://localhost:8080/cxf service/services/cxfAuth的Observer的请求,并且在浏览器上

  • 我使用camel和cxf组件从Web服务中获取一些数据。在某些情况下,Web服务返回标准的soap:fault。我有下一个步骤: 阅读cxf和camel邮件列表中的类似问题,我理解cxfendpoint应该抛出异常,如果有soap foalt,org.apache.cxf.binding.soap.soapfault类型的异常,但我不能得到它。onException子句的目标是处理soap错误异常