我们正在构建一个基于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组件,或者是否可以使用此专用服务?
答案 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)