我看到这个问题已被多次询问,但没有一个帖子有帮助或有一个确凿的解决方案。我正在拆分消息,然后使用Aggregator2聚合它。代码抛出异常,因为oldExchange始终为null。所以要测试我设计了一个小代码。
我读了一个命令,xml文件看起来像这样
<Orders xmlns="http://some/schema/Order">
<Order>
<orderNum>1</orderNum>
</Order>
<Order>
<orderNum>2</orderNum>
</Order>
<Order>
<orderNum>3</orderNum>
</Order>
<Order>
<orderNum>5</orderNum>
</Order>
<Order>
<orderNum>6</orderNum>
</Order>
我的骆驼语境看起来像这样
<camel:route>
<camel:from uri="file:src/data/catask/test?noop=true"/>
<camel:log message="${body}"></camel:log>
<camel:split>
<camel:xpath>//te:Orders/*</camel:xpath>
<camel:to uri="direct:logQueries"/>
<camel:to uri="direct:aggegateQueries"/>
</camel:split>
</camel:route>
<camel:route>
<camel:from uri="direct:logQueries"/>
<camel:log message="After the call : \n ${body}"></camel:log>
</camel:route>
<camel:route>
<camel:from uri="direct:aggegateQueries"/>
<camel:aggregate strategyRef="aggrTask" completionInterval="8000" >
<camel:correlationExpression>
<camel:xpath>//te:Order</camel:xpath>
</camel:correlationExpression>
<camel:to uri="file:src/data/catask/output?fileName=output.xml"/>
</camel:aggregate>
</camel:route>
My Aggregation Strategy类看起来像这样
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
if (oldExchange == null) {
System.out.println("Returning new exchange");
return newExchange;
}
String oldBody = oldExchange.getIn().getBody(String.class);
String newBody = newExchange.getIn().getBody(String.class);
oldExchange.getIn().setBody(oldBody + "+" + newBody);
return oldExchange;
}
问题是当聚合结果保存在output.xml文件中时,它只包含从Orders.xml读取的最后一条记录。
即。
<Order xmlns="http://some/schema/Order">
<orderNum>6</orderNum>
</Order>
我进一步研究并发现这种情况正在发生,因为在第一次调用oldExchange之后应该有一些值,但事实证明它总是为空。我认为,因为它是从单个文件中读取所有内容并将其拆分,所以只有交换。
&GT;有什么建议??
更新1:每个克劳斯我只能使用Splitter来解决这个问题。我这样做了,并且能够成功加入所有消息。但是我仍在寻找使用Aggregator2的方法。这里我是如何使用Splitter的。
camel:route>
<camel:from uri="file:src/data/catask/test?noop=true"/>
<camel:log message="${body}"></camel:log>
<camel:split strategyRef="aggrTask">
<camel:xpath>//te:Orders/*</camel:xpath>
<camel:to uri="direct:logQueries"/>
<
</camel:split>
</camel:route>
<camel:route>
<camel:from uri="direct:logQueries"/>
<camel:log message="After the call : \n ${body}"></camel:log>
</camel:route>
答案 0 :(得分:1)
我想我已经弄明白了如何使用Aggregator聚合消息。我添加了一个名为id的headerName,并将其用作我的相关ID。
<camel:route>
<camel:from uri="file:src/data/catask/test?noop=true"/>
<camel:log message="${body}"></camel:log>
<camel:split>
<camel:xpath>//te:Orders/*</camel:xpath>
<camel:to uri="direct:addHeaders"/>
<camel:to uri="direct:aggegateQueries"/>
</camel:split>
</camel:route>
<camel:route>
<camel:from uri="direct:addHeaders"/>
<camel:setHeader headerName="id">
<camel:constant>order</camel:constant>
</camel:setHeader>
</camel:route>
<camel:route>
<camel:from uri="direct:aggegateQueries"/>
<camel:aggregate strategyRef="aggrTask" completionInterval="8000" >
<camel:correlationExpression>
<simple>header.id</simple>
</camel:correlationExpression>
<camel:to uri="file:src/data/catask/output?fileName=output.xml"/>
<camel:log message="MERGED:: /n ${body}"></camel:log>
</camel:aggregate>
</camel:route>
这会聚合我的消息。但是我仍然不确定尽管使用了正确的XPATH,为什么Camel认为它是不同类型的消息?
从骆驼论坛复制克劳斯的解释: “看起来像你的相关表达式是一个新的组 每条消息,例如每个xpath结果都不同。 如果要拆分并加入相同的消息,请参阅此eip http://camel.apache.org/composed-message-processor.html 并且仅使用拆分器查看示例。这样做要容易得多。 “
我使用Xpath Evaluator工具测试了Xpath表达式,并打印出了coorelation表达式结果,所有带有// Order的消息都是相同的。前 -
Group 1:
<Order>
<orderNum>1</orderNum>
</Order>
Group 2:
<Order>
<orderNum>2</orderNum>
</Order>