gpt4 book ai didi

java - Camel 交换体内的原始消息丢失

转载 作者:行者123 更新时间:2023-12-02 06:05:03 24 4
gpt4 key购买 nike

我有一条 Camel 路线,已交易如下。

 from("jms:queue:start")
.transacted()
.bean(new FirstDummyBean(), "setBodyToHello")
.bean(new SecondDummyBean(), "setBodyToWorld")
.to("jms:queue:end")

顾名思义,bean 方法将主体分别设置为“Hello”和“World”。

我还有一个 onException 子句设置,如下所示:

onException(Exception.class)
.useOriginalMessage()
.handled(true)
.to("jms:queue:deadletter")
.markRollbackOnlyLast();

假设,我在队列“start”上放置一条消息,其正文为“测试消息”。在 FirstDummyBean 中成功处理后,我在 SecondDummyBean 中抛出 RuntimeException。我期望看到实际的消息或(原始消息内容完整,即“测试消息”)发送到我的死信队列。

但是死信队列上的消息内容是“Hello”。

为什么会发生这种情况?...

我使用的是 apache Camel 2.10.0。

任何人都可以提供有关如何同时使用 errorhandler 和 oneException 子句的更多信息。该文件说:

If you have marked a route as transacted using the transacted DSL then Camel will automatic use a TransactionErrorHandler. It will try to lookup the global/per route configured error handler and use it if its a TransactionErrorHandlerBuilder
instance. If not Camel will automatic create a temporary TransactionErrorHandler that overrules the default error handler. This is convention over configuration.

如何将 transactionerrorhandler 与 JavaDSL 一起使用的示例会很棒。

最佳答案

我在非事务示例中看到了这一点,并且 useOriginalMessage() 确实使用了原始交换,但是如果您修改了此引用的任何对象,那么您仍然会获得修改。 useOriginalMessage 似乎并没有返回队列来获取原始数据。

显示问题的示例代码

下面的代码包含一组演示该问题的路线。定时路由将包含 String “Test message”ArrayList 发送到由第二个路由读取的队列。第二条路由将消息传递给 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可以保持不变。

做一个通用的解决方案是很尴尬的,因为复制机制将取决于您正在运行的对象。您可能会发现可以扩展 RouteBuilder 类来为自己提供一些复制对象的自定义 DSL。

关于java - Camel 交换体内的原始消息丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22361531/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com