如何在Camel

时间:2017-04-03 08:46:11

标签: java apache-camel

我们正在构建一个基于Apache Camel的消息路由器,并决定使用多种格式的通用流程。我们通过通用休息端点输入我们的消息,并有条件地将此调用的主体映射到多种特定消息格式之一。我们从不同的XSD生成了我们的特定数据格式。

映射发生在处理器中,该处理器依赖于消息的内容使用不同的映射器。该处理器将特定的Java模型放在交换的主体中。

在下一步中,我们希望将主体编组并验证为XML。这是一个“通用”步骤,因为所有消息都必须编组为XML。在此之后,他们再次根据消息内容发送到动态端点。

要编组XML,我们使用以下路由:

from("direct:marshal-xml")
 .marshal(jaxbDataFormat)
 .to("direct:validate-and-send");

根据名为“messageType”的头属性,我们希望使用不同的jaxbDataFormat对象来编组XML。我们可以通过路由本身的选择来做到这一点,但我们想使用一个专用服务,它接受一个字符串输入,即messageType,并返回正确的jaxbDataFormat。

现在的问题是如何将标题属性“messageType”作为参数传递给服务。我们想使用类似的东西:

from("direct:marshal-xml")
 .marshal(jaxbDataFormatService.getDataFormat(getHeader("messageType")))
 .to("direct:validate-and-send");

但我似乎无法从标头中获取messageType作为字符串。 routebuilder(用于“模拟”路径)和运行时路径(从此模型生成)之间似乎存在差异。

我尝试使用简单的表达式,但似乎无法在没有交换的情况下评估它们:

simple("${header.messageType}").evaluate(exchange, String.class);

如何解决这个问题?我是否必须在routebuilder中使用choice组件,或者是否可以使用此专用服务?

1 个答案:

答案 0 :(得分:2)

您始终可以实现自己的“复合数据格式”,例如通过实现org.apache.camel.spi.DataFormat,该public class MyCompositeFormat implements DataFormat, CamelContextAware { public MyCompositeFormat(DataFormat... formats) { // store them to local variable } public CamelContext getCamelContext() { return camelContext; } public void setCamelContext(CamelContext camelContext) { this.camelContext = camelContext; } public void marshal(Exchange exchange, Object graph, OutputStream stream) throws Exception { if (exchange.getIn().getHeader("SomeHeader",String.class).equals("whatever") { return someFormatYouStored.marshal(exchange,graph,stream); } else { return anotherFormat.marshal(exchange,graph,stream); } } public Object unmarshal(Exchange exchange, InputStream stream) throws Exception { // similar approach to marshal } } 将了解您要使用的所有数据格式并使用您想要的数据格式。

这样的东西,只是为了给你一个想法:

MyCompositeFormat myCompositeFormat = new MyCompositeFormat(otherFormats);
from("direct:marshal-xml")
 .marshal(myCustomFormat)
 .to("direct:validate-and-send");

在你的路线中:

def alphabetical(word):
    return list(word) == sorted(word)