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

问题描述 投票:0回答:1

假设我有以下消息正文:

<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>

我希望每个循环的最终结果能够通过将 customName 映射到名称并将 customDescription 映射到当前循环项的描述来丰富我的初始消息。 我是否通过在丰富节点中使用某种 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;
}
apache-camel
1个回答
0
投票

我认为最好的选择是使用 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
}

如果您仍然需要在骆驼路由末尾有一条 xml 消息,则只需在“丰富”步骤之后编组您的对象:

<from uri="direct:input"/>
<unmarshal><custom ref="xmlDataFormat"/></unmarshal>
<enrich strategyRef="someAggregationStrategy">
   <constant>direct:getItemInfoById</constant>
</enrich>
<marshall><custom ref="xmlDataFormat"/></marshal>
© www.soinside.com 2019 - 2024. All rights reserved.