如何正确合并到apache camel中的项目列表中

o2gm4chl  于 11个月前  发布在  Apache
关注(0)|答案(1)|浏览(125)

假设我有以下消息体:

<itemsList>
  <item>
    <id>1</id>
    <name></name>
    <description></description>
  </item>
  <item>
    <id>2</id>
    <name></name>
    <description></description>
  </item>
</itemsList>

字符串
首先,我将通过执行以下操作来遍历itemsList:

<setProperty propertyName="itemsListSize">
      <xpath saxon="true" resultType="java.lang.Integer">count(//*[local-name()='itemsList'])</xpath>
    </setProperty>
    <loop>
      <simple>${exchangeProperty.itemsListSize}</simple>
      <setProperty propertyName="currentId">
        <xpath saxon="true" resultType="java.lang.String">
           //*[local-name()='itemsList'][function:simple('${exchangeProperty.CamelLoopIndex}')+1]/*[local-name()='id']/text()
        </xpath>
      </setProperty>
      <enrich strategyRef="someAggregationStrategy">
        <constant>direct:getItemInfoById</constant>
      </enrich>
    </loop>


在上面的例子中,“getItemInfoById”将是一个使用currentId属性的路由,并调用一个服务,该服务将返回类似于:

<customItem>
  <customId>1</customId>
  <customName>John</customName>
  <customDescription>Human</customDescription>
</customItem>


我希望每个循环的最终结果通过将customNameMap到name,并将customDescriptionMap到当前循环项的描述来丰富我的初始消息。我是否可以通过在enriched节点中使用某种AggregationStrategy来实现这一点?如果可以,那会是什么样子?
以下是我目前的聚合策略:

public Exchange aggregate(Exchange original, Exchange resource) {

        for (Entry<String, Object> e : resource.getProperties().entrySet()) {
            String k = e.getKey();
            Object v = e.getValue();
            original.setProperty(k, v);
        }

        original.getOut().setBody(original.getIn().getBody());
        return original;
}

vwkv1x7d

vwkv1x7d1#

我认为你最好的选择是使用JacksonXml数据格式将消息体编组到一个java对象:

<dataFormats>
    <jacksonXml id="xmlDataFormat" unmarshalType="foo.bar.ItemsList"/>
</dataFormats>

字符串
而不是循环逻辑,你只需要这样做:

<from uri="direct:input"/>
<unmarshal><custom ref="xmlDataFormat"/></unmarshal>
<enrich strategyRef="someAggregationStrategy">
   <constant>direct:getItemInfoById</constant>
</enrich>


“direct:getItemInfoById”路由将返回CustomItem列表。
您的聚合策略将更简单:

public Exchange aggregate(Exchange original, Exchange resource) {

        var customItems = resource.getMessage().getBody(CustomItems.class);

        var itemsList = original.getMessage().getBody(ItemsList.class);

        // Here, your code to merge each element in itemsList with its matching item in customItems
}


如果你需要在camel路由的末尾仍然有一个xml消息,你只需要在“enrich”步骤之后马歇尔你的对象:

<from uri="direct:input"/>
<unmarshal><custom ref="xmlDataFormat"/></unmarshal>
<enrich strategyRef="someAggregationStrategy">
   <constant>direct:getItemInfoById</constant>
</enrich>
<marshall><custom ref="xmlDataFormat"/></marshal>

相关问题