【问题标题】:How to pass header string to service in Camel如何将标头字符串传递给骆驼中的服务
【发布时间】:2017-04-03 08:46:11
【问题描述】:

我们正在构建一个基于 Apache Camel 的消息路由器,并决定为多种格式使用通用流。我们通过一个通用的 rest 端点输入我们的消息,并有条件地将这个调用的主体映射到多种特定消息格式中的一种。我们从不同的 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 中的选择组件,还是仍然可以使用此专用服务?

【问题讨论】:

    标签: java apache-camel


    【解决方案1】:

    您始终可以实现自己的“复合数据格式”,例如通过实现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");
    

    【讨论】:

    • 感谢您快速且非常有用的回复!我还没有实现我自己的 DataFormat。这完全符合我们的需求!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多