从 cxfrs 到 activemq 队列问题的 Apache 骆驼路线
Apache camel route from cxfrs to activemq queue issue
我在 spring+cxf:rsServer 的帮助下实现了 restful 网络服务。
<cxf:rsServer id="cxfContainer" address="/">
<cxf:serviceBeans>
<ref bean="restService"/>
</cxf:serviceBeans>
<cxf:extensionMappings>
<entry key="json" value="application/json" /> <!-- use .json to get data in JSON format -->
<entry key="xml" value="application/xml" /> <!-- use .xml to get data in XML format -->
</cxf:extensionMappings>
<cxf:providers>
<ref bean="jsonProvider" />
<ref bean="jaxbXmlProvider" />
</cxf:providers>
</cxf:rsServer>
现在我想将 Web 服务上的 xml/json 输入路由到 activemq。
所以我添加了
这样的 camelContext
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring" trace="true">
<route>
<from uri="cxfrs:bean:cxfContainer"/>
<choice>
<when>
<camel:xpath>/PlayerType/playerId= '007'</camel:xpath>
<inOnly uri="activemq:queue:RESTFULL.queue"/>
</when>
<otherwise>
<inOnly uri="activemq:queue:DefaultQueue"/>
</otherwise>
</choice>
</route>
</camelContext>
XML 输入文件
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PlayerType xmlns="http://benchresources.in/cdm/Player">
<playerId>007</playerId>
<name>abcd</name>
<age>30</age>
<matches>70</matches>
</PlayerType>
它抛出以下错误。
unwinding now
org.apache.cxf.interceptor.Fault: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: org.apache.cxf.message.MessageContentsList
to the required type: org.w3c.dom.Document with value [in.benchresources.cdm.player.PlayerType@d792a03] while invoking public java.lang.String com.apache.cxf.xml.json.service.Playe
rServiceImpl.createOrSaveNewPLayerInfo(in.benchresources.cdm.player.PlayerType) with params [in.benchresources.cdm.player.PlayerType@d792a03].
at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:167)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:141)
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:211)
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:99)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.run(ServiceInvokerInterceptor.java:59)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:243)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:223)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:197)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:149)
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:206)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2476)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2465)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: org.apache.camel.RuntimeCamelException: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: org.apache.cxf.message.Mes
sageContentsList to the required type: org.w3c.dom.Document with value [in.benchresources.cdm.player.PlayerType@d792a03]
在处理 Camel 的 CXF 端点时,我 运行 多次遇到这个问题。本质上,当您从 cxfrs bean 获得响应时,cxf 响应被封装在 MessageContentsList(本质上是一个数组列表)中。你得到的错误是因为你试图将 MessageContentsList 对象放入 org.w3c.dom.Document 中,这会引发此错误。
您可以通过在 cxfrs bean 之后添加一个处理器来解决这个问题,该处理器从 MessageContentsList 中提取响应并将其设置为消息的主体。像这样:
process(Exchange e){
MessageContentsList list = (MyObject) e.getIn().getBody();
MyObject obj = list.get(0);
e.getIn().setBody(obj);
}
我在 spring+cxf:rsServer 的帮助下实现了 restful 网络服务。
<cxf:rsServer id="cxfContainer" address="/">
<cxf:serviceBeans>
<ref bean="restService"/>
</cxf:serviceBeans>
<cxf:extensionMappings>
<entry key="json" value="application/json" /> <!-- use .json to get data in JSON format -->
<entry key="xml" value="application/xml" /> <!-- use .xml to get data in XML format -->
</cxf:extensionMappings>
<cxf:providers>
<ref bean="jsonProvider" />
<ref bean="jaxbXmlProvider" />
</cxf:providers>
</cxf:rsServer>
现在我想将 Web 服务上的 xml/json 输入路由到 activemq。 所以我添加了
这样的 camelContext <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring" trace="true">
<route>
<from uri="cxfrs:bean:cxfContainer"/>
<choice>
<when>
<camel:xpath>/PlayerType/playerId= '007'</camel:xpath>
<inOnly uri="activemq:queue:RESTFULL.queue"/>
</when>
<otherwise>
<inOnly uri="activemq:queue:DefaultQueue"/>
</otherwise>
</choice>
</route>
</camelContext>
XML 输入文件
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PlayerType xmlns="http://benchresources.in/cdm/Player">
<playerId>007</playerId>
<name>abcd</name>
<age>30</age>
<matches>70</matches>
</PlayerType>
它抛出以下错误。
unwinding now
org.apache.cxf.interceptor.Fault: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: org.apache.cxf.message.MessageContentsList
to the required type: org.w3c.dom.Document with value [in.benchresources.cdm.player.PlayerType@d792a03] while invoking public java.lang.String com.apache.cxf.xml.json.service.Playe
rServiceImpl.createOrSaveNewPLayerInfo(in.benchresources.cdm.player.PlayerType) with params [in.benchresources.cdm.player.PlayerType@d792a03].
at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:167)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:141)
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:211)
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:99)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.run(ServiceInvokerInterceptor.java:59)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:243)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:223)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:197)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:149)
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:206)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2476)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2465)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: org.apache.camel.RuntimeCamelException: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: org.apache.cxf.message.Mes
sageContentsList to the required type: org.w3c.dom.Document with value [in.benchresources.cdm.player.PlayerType@d792a03]
在处理 Camel 的 CXF 端点时,我 运行 多次遇到这个问题。本质上,当您从 cxfrs bean 获得响应时,cxf 响应被封装在 MessageContentsList(本质上是一个数组列表)中。你得到的错误是因为你试图将 MessageContentsList 对象放入 org.w3c.dom.Document 中,这会引发此错误。
您可以通过在 cxfrs bean 之后添加一个处理器来解决这个问题,该处理器从 MessageContentsList 中提取响应并将其设置为消息的主体。像这样:
process(Exchange e){
MessageContentsList list = (MyObject) e.getIn().getBody();
MyObject obj = list.get(0);
e.getIn().setBody(obj);
}