我有一个多播到2个地方的路由。如果在调用该位置的1时发生异常,我将无法保留聚合结果。在onException的处理器内部,我在聚合过程中创建的Map不在那里。我用的是骆驼2.25。
onException(RuntimeException.class)
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
Map<String, String> results = exchange.getProperty(SimpleAggregationStrategy.RESULTS, Map.class);
System.out.println(results);
}
});
from(DIRECT_FIRST)
.log("First route")
.setBody(constant("FIRST TEXT"));
from(DIRECT_SECOND)
.log("Second route")
.setBody(constant("SECOND TEXT"))
.throwException(new RuntimeException("Dummy Exception"));
from(DIRECT_ENTRY)
.multicast().stopOnException().aggregationStrategy(new AggregationStrategy() {
public static final String RESULTS = "RESULTS";
@Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
System.out.println("INSIDE SimpleAggregationStrategy !!!!!!!!!!!!!!!!");
Map<String, String> results;
if (oldExchange != null) {
results = oldExchange.getProperty(RESULTS, Map.class);
} else {
results = new HashMap<>();
}
results.put(newExchange.getIn().getBody(String.class), newExchange.getIn().getBody(String.class));
return newExchange;
}
})
.to(DIRECT_FIRST, DIRECT_SECOND);
我假设聚合器由于stopOnException()
而中止处理,因此不会返回(不完整(结果。
您可以尝试将聚合策略放入上下文管理的bean中,并使Map成为可通过getter方法访问的实例变量。
如果出现异常,您可以尝试从bean中获取不完整的Map。但我不知道它是仍然保存数据,还是在处理中止时被清空。
解决方案比我想象的要简单。我们只需要在多播步骤之前创建一个exchangeProperty。然后,即使在进行多播时出现异常的情况下,交换属性也可以存储聚合结果
onException(RuntimeException.class)
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
Map<String, String> results = exchange.getProperty("RESULTS", Map.class);
System.out.println(results);
}
});
from(DIRECT_FIRST)
.log("First route")
.setBody(constant("FIRST TEXT"));
from(DIRECT_SECOND)
.log("Second route")
.setBody(constant("SECOND TEXT"))
.throwException(new RuntimeException("Dummy Exception"));
from(DIRECT_ENTRY)
.process(exch -> {
exch.setProperty("RESULTS", new HashMap<String, String>())
})
.multicast().stopOnException().aggregationStrategy(new AggregationStrategy() {
public static final String RESULTS = "RESULTS";
@Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
Map<String, String> results;
if (oldExchange != null) {
results = oldExchange.getProperty(RESULTS, Map.class);
} else {
results = new HashMap<>();
}
results.put(newExchange.getIn().getBody(String.class), newExchange.getIn().getBody(String.class));
return newExchange;
}
})
.to(DIRECT_FIRST, DIRECT_SECOND);