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