1

xPath を使用して、REST ペイロードのコンテンツによって決定されるルートを作成しようとしています。メッセージ ヘッダーに基づくルーティングの使用に成功しました。

<when>
   <simple>${headers.operationName} == 'createContainerOutput'</simple>
   <bean ref="containerOutputProcessor"/>
</when>

これは、containerOutputProcessor を適切に呼び出します...

ただし、この xPath ルートの場合:

<when>
    <xpath>/*[local-name()='order-request']/@type='TrayOutput'</xpath>
    <bean ref="containerOutputProcessor"/>
</when>

私は例外を取得します:

org.apache.camel.NoTypeConversionAvailableException: タイプ org.apache.cxf.message.MessageContentsList から必要なタイプ: org.w3c.dom.Document 値 [com.mmi.ws.ContainerOutputOrderRequest@6290dc] に変換できるタイプ コンバーターがありません]

このペイロードの

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<order-request type="TrayOutput">
    <parameter name="orderName">Example Tray Output Order</parameter>
    <parameter name="enableScan">true</parameter>
    <parameter name="autoStart">false</parameter>
    <parameter name="priority">3</parameter>
    <item barcode="23990001"/>
    <item barcode="23990002"/>
</order-request>

このタイプのルーティングは良い考えですか? 送信されている注文リクエストのタイプに基づいてルーティングするより良い方法はありますか?

あなたが私のために持っているかもしれないどんな助け/指導にも感謝します!


ここに完全なコンテキストがあります

<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:jaxrs="http://cxf.apache.org/jaxrs"
    xmlns:cxf="http://camel.apache.org/schema/cxf"
    xsi:schemaLocation="
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
     http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
     http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
     http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd">

  <!-- enable Spring @Component scan -->
  <context:component-scan base-package="com.mmi.ws"/>

    <!--  web service beans -->
  <bean id="containerOutputWS" class="com.mmi.ws.service.impl.ContainerOutputWSImpl" />
  <bean id="containerTypesWS" class="com.mmi.ws.service.impl.ContainerTypesWSImpl" />


  <!-- processor beans -->
  <bean id="containerOutputProcessor" class="com.mmi.ws.service.ContainerOutputProcessor" />
  <bean id="containerTypesProcessor" class="com.mmi.ws.service.ContainerTypesProcessor" />
  <bean id="unsupportedPathProcessor" class="com.mmi.ws.service.UnsupportedPathProcessor" />


  <!-- Define the real JAXRS back end service  -->
  <jaxrs:server id="restService"
                address="http://localhost:9998/sc" 
                staticSubresourceResolution="true">
    <jaxrs:serviceBeans>
      <ref bean="containerOutputWS"/>
      <ref bean="containerTypesWS"/>
    </jaxrs:serviceBeans>       
  </jaxrs:server>

  <!--  define the restful server and client endpoints -->
  <cxf:rsServer id="rsServer" address="http://localhost:9999/sc" loggingFeatureEnabled="true" loggingSizeLimit="20">
    <cxf:serviceBeans >
      <ref bean="containerOutputWS"/>
      <ref bean="containerTypesWS"/>
    </cxf:serviceBeans>
  </cxf:rsServer>

  <cxf:rsServer id="rsClient" address="http://localhost:9998/sc" loggingFeatureEnabled="true" loggingSizeLimit="20">
    <cxf:serviceBeans >
      <ref bean="containerOutputWS"/>
      <ref bean="containerTypesWS"/>
    </cxf:serviceBeans>
  </cxf:rsServer>


  <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
    <!-- 
       any classes in the below 'packageScan'packages that extends RouteBuilder
       will be added as a camel route.  At least one route is required to start the cxf web service
    -->
    <packageScan>
        <package>com.mmi.ws</package>
    </packageScan>

    <dataFormats>
     <xstream id="xstream-utf8" encoding="UTF-8"/>
     <xstream id="xstream-default"/>
    </dataFormats>

    <!-- route starts from the cxf webservice  -->
    <route streamCache="true">
       <from uri="cxfrs://bean://rsServer"/>
        <log message="XML payload to send to REST WS:${body}" />        
        <setHeader headerName="CamelCxfRsUsingHttpAPI"><constant>True</constant> </setHeader>
        <choice>
            <when>
                <simple>${headers.operationName} == 'getContainers'</simple>
                <bean ref="containerTypesProcessor"/>
            </when>
            <when>
                <xpath>/*[local-name()='order-request']/@type='TrayOutput'</xpath>
                <bean ref="containerOutputProcessor"/>
            </when>
            <otherwise>
                <bean ref="unsupportedPathProcessor"/>
                <to uri="cxfrs://bean://rsClient"/>
            </otherwise>
        </choice>
    </route>    
  </camelContext>
</beans>

および Web サービス クラス:

@Path("/container/output/")
public class ContainerOutputWSImpl 
{
    @POST
    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
    public ContainerOutputView createContainerOutput(ContainerOutputOrderRequest containerOutput) {
        // TODO Auto-generated method stub
        return new ContainerOutputView();
    }
}

最後に、xml ペイロードとエラー スタック:

Address: http://localhost:9999/sc/container/output/
Encoding: ISO-8859-1
Http-Method: POST
Content-Type: application/xml
Headers: {accept-encoding=[gzip,deflate], connection=[keep-alive], Content-Length=[384], content-type=[application/xml], Host=[localhost:9999], User-Agent=[Apache-HttpClient/4.1.1 (java 1.5)]}
Payload: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<order-request type="TrayOutput">
    <parameter name="orderName">Example Tray Output Order</parameter>
    <parameter name="enableScan">true</parameter>
    <parameter name="autoStart">false</parameter>
    <parameter name="priority">3</parameter>
    <item barcode="23990001"/>
    <item barcode="23990002"/>
</order-request>

--------------------------------------
[ERROR] 2013-02-07  17:53:37.059  [qtp27633254-28: DefaultErrorHandler] Failed delivery for (MessageId: ID-PWY-EHANSEN-3070-1360288389778-0-2 on ExchangeId: ID-PWY-EHANSEN-3070-1360288389778-0-1). Exhausted after delivery attempt: 1 caught: org.apache.camel.RuntimeCamelException: 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 [com.mmi.ws.ContainerOutputOrderRequest@9fbbe5]
org.apache.camel.RuntimeCamelException: 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 [com.mmi.ws.ContainerOutputOrderRequest@9fbbe5]
    at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1271)
    at org.apache.camel.builder.xml.XPathBuilder.getDocument(XPathBuilder.java:1027)
    at org.apache.camel.builder.xml.XPathBuilder.doInEvaluateAs(XPathBuilder.java:850)
    at org.apache.camel.builder.xml.XPathBuilder.evaluateAs(XPathBuilder.java:757)
    at org.apache.camel.builder.xml.XPathBuilder.matches(XPathBuilder.java:145)
    at org.apache.camel.processor.ChoiceProcessor.process(ChoiceProcessor.java:66)
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
    at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99)
    at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:73)
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
    at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99)
    at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
    at org.apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.java:91)
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
    at org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:334)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:220)
    at org.apache.camel.processor.interceptor.StreamCachingInterceptor.process(StreamCachingInterceptor.java:52)
    at org.apache.camel.processor.RouteContextProcessor.processNext(RouteContextProcessor.java:45)
    at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
    at org.apache.camel.processor.interceptor.DefaultChannel.process(DefaultChannel.java:303)
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:117)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
    at org.apache.camel.processor.RouteContextProcessor.processNext(RouteContextProcessor.java:45)
    at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
    at org.apache.camel.processor.UnitOfWorkProcessor.processAsync(UnitOfWorkProcessor.java:150)
    at org.apache.camel.processor.UnitOfWorkProcessor.process(UnitOfWorkProcessor.java:117)
    at org.apache.camel.processor.RouteInflightRepositoryProcessor.processNext(RouteInflightRepositoryProcessor.java:48)
    at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
    at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99)
    at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:73)
    at org.apache.camel.component.cxf.jaxrs.CxfRsInvoker.asyncInvoke(CxfRsInvoker.java:87)
    at org.apache.camel.component.cxf.jaxrs.CxfRsInvoker.performInvocation(CxfRsInvoker.java:57)
    at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:201)
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:102)
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:94)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:355)
    at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:319)
    at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:72)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1074)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1010)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
    at org.eclipse.jetty.server.Server.handle(Server.java:365)
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:485)
    at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:937)
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:998)
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:856)
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:627)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:51)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
    at java.lang.Thread.run(Thread.java:722)
4

1 に答える 1

5

コンテンツ ベース ルーターの前に、メッセージを変換して、内部 CXF リストからペイロードを取り出すことができます。リストから最初のインデックスを取得する単純な言語にはトリックがあります。

<transform>
   <simple>${body[0]}</simple>
</transform>
<choice>
   ...

クラスパスに camel-jaxb がありますか。もしそうなら、そのトリックなしですぐに使えるかもしれません。ただし、CXF は少し特殊なのでわかりません。また、使用している Camel / CXF のバージョンによっても異なります。質問するときは、これについて本当に言及する必要があります。

于 2013-02-09T08:33:21.900 に答える