假设我有以下消息正文:
<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;
}
我认为最好的选择是使用 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>