java - 拆分EIP中的Camel异常路由

标签 java exception apache-camel

我正在将 CSV 文件输入与更大的系统集成,并且我想将其设置为不解析 CSV 的各个行(由 split 分割)正确的被发送到医院队列,所有其他工作线被转换成一个对象并聚合成一个列表。但是,我无法将 split 中抛出的异常消息路由到其他地方,并且不会出现在拆分结束时的聚合器中。为了简化它,我编写了一个在拆分中抛出异常的单元测试,并且我尝试让它工作。我将字符串 1\n2\n3\n 拆分为三个消息,对其中一个消息抛出异常,并在末尾连接剩余的字符串。

public void configure() throws Exception {

    onException(Exception.class)
        .handled(true)
        .to("log:dead?level=ERROR");

    from("direct:test")
        .split(body().tokenize("\n"), new MyAggregationStrategy())
            .process(new ThrowMyException())
        .end()
        .to("mock:out");
}

@Test
public void test() throws InterruptedException {

    MockEndpoint out = getMockEndpoint("mock:out");
    out.expectedMessageCount(1);

    template.sendBody("direct:test", "1\n2\n3\n");

    assertMockEndpointsSatisfied();
}

ThrowMyException Controller :仅抛出异常

@Override
public void process(Exchange exchange) throws Exception {
    System.out.println("[" + exchange.getIn().getBody() + "]");
    if (exchange.getIn().getBody(String.class).trim().contentEquals("2")) {
        System.out.println("Throwing exception");
        throw new Exception();
    }
}

MyAggregationStrategy:仅连接字符串

@Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
    if (oldExchange == null) {
        return newExchange;
    }
    oldExchange.getIn().setBody(
            oldExchange.getIn().getBody(String.class) + 
            newExchange.getIn().getBody(String.class));
    System.out.println(oldExchange.getIn().getBody());
    return oldExchange;
}

我期望的是 onException 处理程序,正如我所指出的那样,它是为了处理异常 (handled(true)),它将消耗抛出的异常当 Controller 收到消息“2”时,我将得到聚合器打印出的结果13。我确实得到了 onException 处理程序打印出的行:

ERROR dead - Exchange[ExchangePattern: InOnly, BodyType: String, Body: 2]

但是聚合器随后返回“123”而不是“13”。

我也尝试过使用 deadLetterChannel

errorHandler(deadLetterChannel("log:dead?level=ERROR")

我还尝试在 onException 处理程序中指定 continued(false),但没有成功。

我意识到我可以通过查看 exchange.getProperty(Exchange.EXCEPTION_CAUGHT) 来查找聚合器中的异常,然后不聚合它。所以我确实有一个解决方案。但如果有一种方法可以在我的 route 使用 onExceptionerrorHandler 来完成此操作,我会更喜欢这样做。

最佳答案

Camel Documentation对于 stopOnException Splitter 选项说

Whether or not to stop continue processing immediately when an exception occurred. If disable, then Camel continue splitting and process the sub-messages regardless if one of them failed. You can deal with exceptions in the AggregationStrategy class where you have full control how to handle that.

这与 Camel In Action 一起表明两个拆分器异常处理选项是处理聚合器中的异常,或者使用 stopOnException(),这将停止整个拆分器迭代器不再继续。

您可以使用 exchange.getException() 方法或 exchange.isFailed() 来测试聚合器中的异常和错误。如果您在 onException 方法上使用了 handled(true),则必须使用 exchange.getProperty(Exchange.EXCEPTION_CAUGHT)

关于java - 拆分EIP中的Camel异常路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34339744/

相关文章:

Java - ArrayList 默认初始值

java - 简单的 Spring EL 表达式不起作用;出现错误 TypeMismatchException

java - Eclipse,突出显示所有抛出异常的方法

java - 如何在 Camel 中实现事件驱动的消费者

apache-camel - Apache Camel MQXAQueueConnectionFactory

java - 获取 Accumulo 实例名称

java - Servlet 使用 getParameter 获取 json 数组

java - 客户端在 Java 的套接字应用程序中无法正常工作

php - 单元测试 : Simulate a timeout with Guzzle 5

apache-camel - 如何在 Apache Camel 中通过 JMS 队列传递 POJO