我有一条骆驼路线,如下所示,是交易。
from("jms:queue:start")
.transacted()
.bean(new FirstDummyBean(), "setBodyToHello")
.bean(new SecondDummyBean(), "setBodyToWorld")
.to("jms:queue:end")
正如其名称所示的bean方法,将body设置为" Hello"和"世界"分别
我还有一个onException子句设置以及如下:
onException(Exception.class)
.useOriginalMessage()
.handled(true)
.to("jms:queue:deadletter")
.markRollbackOnlyLast();
假设,我在队列中删除了一条消息" start"身体为"测试信息"。在FirstDummyBean中成功处理之后,我在SecondDummyBean中抛出一个RuntimeException。 我期待看到实际的消息或(原始消息内容完整,即#34;测试消息")被发送到我的死信队列。
然而,deadletter queue上的消息内容是" Hello"。
为什么会这样?
我正在使用apache camel 2.10.0。
也可以有人提供有关如何同时使用errorhandler和onexception子句的更多信息。 该文件说:
如果您使用交易的DSL标记了一条路线,那么Camel 将自动使用TransactionErrorHandler。它将尝试查找global / per 路由配置错误处理程序并使用它,如果它是TransactionErrorHandlerBuilder
实例。如果没有,Camel会自动创建一个临时的TransactionErrorHandler 否决了默认的错误处理程序。这是约定优于配置。
如何在JavaDSL中使用transactionerrorhandler的例子很棒。
答案 0 :(得分:1)
我在非交易示例中看到了这一点,看来useOriginalMessage()
确实使用了原始交换,但是如果您修改了这个引用的任何对象,那么您仍然可以进行修改。 useOriginalMessage
似乎没有返回队列来获取原始数据。
以下代码包含一组演示问题的路线。定时路由将包含ArrayList
String
的{{1}}发送到第二条路由读取的队列。第二条路由将消息传递给"Test message"
,这会更改列表的内容。接下来,消息将转到ModifyBody
,并抛出TriggerException
。这由RuntimeException
路由处理,尽管使用了onException
,但仍会传递更新的正文。
useOriginalMessage
如果使用下面的代码替换import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.camel.spring.SpringRouteBuilder;
import org.springframework.stereotype.Component;
@Component
public class TimedRoute extends SpringRouteBuilder {
private static final String QUEUE = "jms:a.queue";
private static final String QUEUE2 = "jms:another.queue";
// The message that will be sent on the route
private static final ArrayList<String> payLoad = new ArrayList<String>(
Arrays.asList("test message"));
public static class ModifyBody {
public List<String> modify(final List<String> list) {
final List<String> returnList = list;
returnList.clear();
returnList.add("Hello");
return returnList;
}
}
public static class TriggerException {
public List<String> trigger(final List<String> list) {
throw new RuntimeException("Deliberate");
}
}
@Override
public void configure() throws Exception {
//@formatter:off
onException(Exception.class)
.useOriginalMessage()
.log("Exception: ${body}")
.handled(true)
.setHeader("exception", constant("exception"))
.to(QUEUE2);
// Timed route to send the original message
from("timer://foo?period=60000")
.setBody().constant(payLoad)
.to(QUEUE);
// Initial processing route - this modifies the body.
from(QUEUE)
.log("queue ${body}")
.bean(new ModifyBody())
.log("after firstDummyBean: ${body}")
.bean(new TriggerException())
.stop();
// Messages are send here by the exception handler.
from(QUEUE2)
.log("queue2: ${body}")
.stop();
//@formatter:on
}
}
,则会在异常处理路径中看到原始消息。
ModifyBody
通过将正文更改为新列表,原始public static class ModifyBody {
public List<String> modify(final List<String> list) {
final List<String> returnList = new ArrayList<String>(list);
returnList.clear();
returnList.add("Hello");
return returnList;
}
}
可以保持不变。
执行一般解决方案很尴尬,因为复制机制将取决于您在飞行中的对象。您可能会发现可以扩展Exchange
类,为自己提供一些复制对象的自定义DSL。