当前位置: 首页 > 知识库问答 >
问题:

骆驼体内的原始信息交换丢失

谭泉
2023-03-14

我有一条骆驼路线,如下所示。

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

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

我还设置了onException子句,如下所示:

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

假设,我将一条消息放在队列“开始”上,正文为“测试消息”。在第一个杜米豆中成功处理后,我在第二个杜米豆中抛出一个运行时异常。我希望看到实际的消息或(原始消息内容完好无损,即“测试消息”)被发送到我的死信队列。

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

为什么会这样?..

我使用的是apache camel 2.10.0。

还有谁能提供更多关于如何一起使用errorhandler和onexception子句的信息。文件上写着:

如果您已使用事务处理的DSL将路由标记为事务处理,则Camel将自动使用TransactionErrorHandler。它将尝试查找全局/每个路由配置的错误处理程序,如果它是 TransactionErrorHandlerBuilder 实例,则使用它
。如果没有,Camel将自动创建一个临时的TransactionErrorHandler,该处理程序会否决默认的错误处理程序。这是配置重于约定。

如何在JavaDSL中使用Transactionerror Handler的示例会很棒。

共有1个答案

邓建柏
2023-03-14

我在非事务示例中见过这种情况,似乎< code > useOriginalMessage()确实使用了原始交换,但是如果您修改了它引用的任何对象,您仍然会得到修改。< code>useOriginalMessage似乎没有返回队列以获取原始数据。

下面的代码包括一组演示问题的路线。定时路由将包含String“测试消息”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;
    }
}

通过将正文更改为新列表,可以不修改原始交换

做一个通用的解决方案是困难的,因为复制的机制将依赖于你正在运行的对象。您可能会发现,您可以扩展< code>RouteBuilder类,为自己提供一些复制对象自定义DSL。

 类似资料:
  • 我已经创建了一个服务代理。 代理(请求类型为)和实际服务(请求类型。)之间有一个处理器。 进入< code > process(Exchange Exchange)方法的交换体属于< code>TypeA。 我能够使用下面的代码行访问数据 现在,我想将此信息更改为。 我使用下面的代码添加主体。 我得到了 现在,我想使用调用真正的服务,它来自。 我尝试进入处理器,但出现以下异常 真正的Web服务没有

  • 脚本: CSV文件被发送到我的endpoint,Pojo将java数据和消息转换为我的一条路由,比如(“direct:consume”)路由,然后处理器处理该文件,处理消息并创建新的输出 问题: 文件只包含代码中断的一行 文件包含多行代码工作 尝试: 试图找到一种方法来确定交易记录的数量。getIn()。getBody() 阅读stackoverflow 阅读有关exchange的文档 在不知道记

  • 我有一个简单的路线,看起来像这样: CXF 配置也非常简单: 此简单路由失败,出现以下异常 这是消息历史记录,表明它在

  • 希望你有时间回答我的问题。在过去的几天里,我一直在阅读关于Camel的文章,并设法将一切都设置好并运行起来。现在,我碰到了一个棘手的部分:)。基本上,我在运行时使用Java定义一个路由,并将路由配置放在DB中。路线是可行的,信息从一边流向另一边。但是,当异常发生时,我想知道异常发生在哪里(在哪个路由endpoint之间),在DB中存储当前的交换主体(对进一步处理有用的进行中的消息),由用户更新消息

  • 我通过以下代码以编程方式创建JMS路由: 我有课: 我想在上述路由和endpoint之间交换一些信息/参数。根据我想要的参数值,选择要在这个消息侦听器容器中设置的连接工厂。 请让我知道我是否能够解释我的问题陈述。 还有其他方法可以实现这一点吗?我想在运行时构建连接工厂,路由也是如此。JmsEndpoint 中是否有任何方法可以用来了解路由 id?

  • 这里是Java 8和Camel 2.19.x。我有以下骆驼路线: 和处理器: