从简单的语言表达式执行bean方法的转换错误

Convertation error in bean method execution from simple language expression

我想在 XML DSL 中将交换 header 设置为执行 bean 方法的结果。我在这个问题的评论中找到了解决方案 - Camel - Passing specific parameters from routes to a generic bean method,我的代码是

XML DSL:

<setHeader headerName="dateInterval">
    <simple>${bean:tableRequestRouteUtil?method=getIntervalForTable(${in.body})}</simple>
</setHeader>

此时的 body 类型是我的 domain-specific POJO (class webbanking.dto.W4MMsg)。 body的初始类型是XMLString,然后转换为POJO(JAXB注解):

<dataFormats>
    <jaxb id="xml" prettyPrint="true"
          contextPath="dto"/>
</dataFormats>

在蓝图中xml 和

<unmarshal ref="xml" id="xml.unmarshall"/> 

骆驼路线

tableRequestRouteUtil bean 的 getIntervalForTable 方法的参数类型为 webbanking.dto.W4MMsg(我的 pojo),return 类型为 String。这工作正常,直到输入 xml 没有出现右括号。输入字符串中的右括号导致以下异常(我省略了请求的 body,它相当大):

org.apache.camel.language.bean.RuntimeBeanExpressionException: Failed to invoke method: getIntervalForTable('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w4MMsg scheme="WAY4Doc" msg_type="Doc" direction="Rq" version="2.0">...') on tableRequestRouteUtil due to: org.apache.camel.language.bean.RuntimeBeanExpressionException: Failed to invoke method: getIntervalForTable('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w4MMsg scheme="WAY4Doc" msg_type="Doc" direction="Rq" version="2.0">...') on tableRequestRouteUtil due to: org.apache.camel.component.bean.ParameterBindingException: Error during parameter binding on method: public router.domain.HistoryInterval router.TableRequestRouteUtil.getIntervalForTable(webbanking.dto.W4MMsg) at parameter #0 with type: class webbanking.dto.W4MMsg with value type: class java.lang.String and value: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w4MMsg scheme="WAY4Doc" msg_type="Doc" direction="Rq" version="2.0">...
    at org.apache.camel.language.bean.BeanExpression.evaluate(BeanExpression.java:117)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.language.bean.BeanExpression.evaluate(BeanExpression.java:132)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.builder.ExpressionBuilder.evaluate(ExpressionBuilder.java:1541)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.support.ExpressionAdapter.evaluate(ExpressionAdapter.java:36)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.language.simple.ast.SimpleFunctionStart.evaluate(SimpleFunctionStart.java:101)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.builder.SimpleBuilder.evaluate(SimpleBuilder.java:83)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.builder.ProcessorBuilder.process(ProcessorBuilder.java:103)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.ChoiceProcessor.process(ChoiceProcessor.java:111)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:51)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:110)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.ChoiceProcessor.process(ChoiceProcessor.java:111)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.component.jetty.CamelContinuationServlet.service(CamelContinuationServlet.java:151)[234:org.apache.camel.camel-jetty:2.12.0.redhat-610379]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)[91:org.apache.geronimo.specs.geronimo-servlet_3.0_spec:1.0]
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1496)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.servlets.MultiPartFilter.doFilter(MultiPartFilter.java:136)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.apache.camel.component.jetty.CamelFilterWrapper.doFilter(CamelFilterWrapper.java:44)[234:org.apache.camel.camel-jetty:2.12.0.redhat-610379]
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1467)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:499)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:428)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.server.Server.handle(Server.java:370)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:667)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:52)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:543)[92:org.eclipse.jetty.aggregate.jetty-all-server:8.1.14.v20131031]
    at java.lang.Thread.run(Thread.java:724)[:1.7.0_25]
Caused by: org.apache.camel.language.bean.RuntimeBeanExpressionException: Failed to invoke method: getIntervalForTable('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w4MMsg scheme="WAY4Doc" msg_type="Doc" direction="Rq" version="2.0">...') on tableRequestRouteUtil due to: org.apache.camel.component.bean.ParameterBindingException: Error during parameter binding on method: public router.domain.HistoryInterval router.TableRequestRouteUtil.getIntervalForTable(webbanking.dto.W4MMsg) at parameter #0 with type: class webbanking.dto.W4MMsg with value type: class java.lang.String and value: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w4MMsg scheme="WAY4Doc" msg_type="Doc" direction="Rq" version="2.0">...
    at org.apache.camel.language.bean.BeanExpression$OgnlInvokeProcessor.process(BeanExpression.java:285)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.language.bean.BeanExpression.evaluate(BeanExpression.java:114)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    ... 56 more
Caused by: org.apache.camel.component.bean.ParameterBindingException: Error during parameter binding on method: public router.domain.HistoryInterval router.TableRequestRouteUtil.getIntervalForTable(webbanking.dto.W4MMsg) at parameter #0 with type: class webbanking.dto.W4MMsg with value type: class java.lang.String and value: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w4MMsg scheme="WAY4Doc" msg_type="Doc" direction="Rq" version="2.0">...
    at org.apache.camel.component.bean.MethodInfo.evaluateParameterValue(MethodInfo.java:572)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.component.bean.MethodInfo.evaluate(MethodInfo.java:472)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.component.bean.MethodInfo.createMethodInvocation(MethodInfo.java:239)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.component.bean.BeanInfo.createInvocation(BeanInfo.java:278)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.component.bean.BeanInfo.createInvocation(BeanInfo.java:180)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:148)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:105)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:67)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.language.bean.BeanExpression$InvokeProcessor.process(BeanExpression.java:189)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.language.bean.BeanExpression$OgnlInvokeProcessor.process(BeanExpression.java:281)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    ... 57 more
Caused by: org.apache.camel.TypeConversionException: Error during type conversion from type: java.lang.String to the required type: webbanking.dto.W4MMsg with value <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w4MMsg scheme="WAY4Doc" msg_type="Doc" direction="Rq" version="2.0">...
    at org.apache.camel.converter.jaxb.FallbackTypeConverter.convertTo(FallbackTypeConverter.java:103)[231:org.apache.camel.camel-jaxb:2.12.0.redhat-610379]
    at org.apache.camel.impl.converter.BaseTypeConverterRegistry.doConvertTo(BaseTypeConverterRegistry.java:315)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.impl.converter.BaseTypeConverterRegistry.mandatoryConvertTo(BaseTypeConverterRegistry.java:164)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.core.osgi.OsgiTypeConverter.mandatoryConvertTo(OsgiTypeConverter.java:116)[150:org.apache.camel.camel-blueprint:2.12.0.redhat-610379]
    at org.apache.camel.component.bean.MethodInfo.evaluateParameterValue(MethodInfo.java:564)[142:org.apache.camel.camel-core:2.12.0.redhat-610379]
    ... 66 more
Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[com.ctc.wstx.exc.WstxEOFException: Unexpected EOF; was expecting a close tag for element <Value>
 at [row,col {unknown-source}]: [186,77]]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:426)[128:org.apache.servicemix.bundles.jaxb-impl:2.2.1.1_2]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:362)[128:org.apache.servicemix.bundles.jaxb-impl:2.2.1.1_2]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:332)[128:org.apache.servicemix.bundles.jaxb-impl:2.2.1.1_2]
    at org.apache.camel.converter.jaxb.FallbackTypeConverter.unmarshal(FallbackTypeConverter.java:276)[231:org.apache.camel.camel-jaxb:2.12.0.redhat-610379]
    at org.apache.camel.converter.jaxb.FallbackTypeConverter.unmarshall(FallbackTypeConverter.java:181)[231:org.apache.camel.camel-jaxb:2.12.0.redhat-610379]
    at org.apache.camel.converter.jaxb.FallbackTypeConverter.convertTo(FallbackTypeConverter.java:95)[231:org.apache.camel.camel-jaxb:2.12.0.redhat-610379]
    ... 70 more
Caused by: com.ctc.wstx.exc.WstxEOFException: Unexpected EOF; was expecting a close tag for element <Value>
 at [row,col {unknown-source}]: [186,77]
    at com.ctc.wstx.sr.StreamScanner.throwUnexpectedEOF(StreamScanner.java:677)[156:woodstox-core-asl:4.2.0]
    at com.ctc.wstx.sr.BasicStreamReader.throwUnexpectedEOF(BasicStreamReader.java:5532)[156:woodstox-core-asl:4.2.0]
    at com.ctc.wstx.sr.BasicStreamReader.nextFromTree(BasicStreamReader.java:2720)[156:woodstox-core-asl:4.2.0]
    at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1072)[156:woodstox-core-asl:4.2.0]
    at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:192)[128:org.apache.servicemix.bundles.jaxb-impl:2.2.1.1_2]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:360)[128:org.apache.servicemix.bundles.jaxb-impl:2.2.1.1_2]
    ... 74 more

我认为这是因为简单的语言表达式执行bean方法的方式是将消息转换为字符串,用这个字符串替换占位符${in.body},然后执行方法,将这个字符串转换回POJO使用转换器框架。此字符串中存在右括号会中断 body 消息,因为它被解释为方法参数的右括号。这是真的?有什么办法可以解决这个问题?从 bean 的执行设置 header 的正确方法应该是什么?

尝试不使用主体,因为 Camel 会自动绑定到参数,而主体是默认绑定的

method=getIntervalForTable

然后不要使用(),这样你只告诉Camel方法名,它可以使用有参数的方法。

我还认为我们已经在即将推出的 Camel 2.15.1 中用 bean 语言修复了 () iusse