camel splitter - 在特定异常时停止循环

问题描述 投票:0回答:4

我们如何在特定异常情况下停止在 camel splitter 上循环? “stopOnException()”正在为每个异常停止循环,但我只想在某些特定异常时停止循环。如果异常是“HttpOperationFailedException”,我想根据响应代码停止循环。 例如,如果响应代码是“500”,则停止执行,如果响应代码是 404,则继续执行。

可能吗?

原始问题

from("timer:categoryRouter?delay=0")
                    .process(new Processor() {
                        @Override
                        public void process(Exchange exchange) throws Exception {
                            exchange.getIn().setBody("A,F,B,D,C");
                        }
                    })
                // tell Splitter to use the aggregation strategy which handles and ignores exceptions
                .split(body(), new MyIgnoreFailureAggregationStrategy())
                    .stopOnException()
                    // log each splitted message
                    .log("Split line ${body}")
                    // and have them translated into a quote
                    .bean(WordTranslateBean.class)
                    // and send it to a mock
                    .to("mock:split")
                .end()
                // log the outgoing aggregated message
                .log("Aggregated ${body}")
                // and send it to a mock as well
                .to("mock:result");

抛出异常的Bean:

public class WordTranslateBean {

private Map<String, String> words = new HashMap<String, String>();

public WordTranslateBean() {
    words.put("A", "Camel rocks");
    words.put("B", "Hi mom");
    words.put("C", "Yes it works");
}

public String translate(String key) throws HttpOperationFailedException {
    if (!words.containsKey(key)) {
        HttpOperationFailedException httpOperationFailedException = null;
        if(key.equals("F")) {
            httpOperationFailedException = new HttpOperationFailedException("uri",500,"Internal Server Error","location",null,"Key not a known word " + key);
        }
        else {
            httpOperationFailedException = new HttpOperationFailedException("uri",404,"Resource Not Found","location",null,"Operation not supported on word " + key);
        }
        throw httpOperationFailedException;
    }
    return words.get(key);
}

}

工作解决方案:

from("timer:categoryRouter?delay=0")
                    .process(new Processor() {
                        @Override
                        public void process(Exchange exchange) throws Exception {
                            exchange.getIn().setBody("A,F,B,D,C");
                        }
                    })
                // tell Splitter to use the aggregation strategy which handles and ignores exceptions
                .split(body(), new MyIgnoreFailureAggregationStrategy())
                    .stopOnException()
                    // log each splitted message
                    .log("Split line ${body}")
                    // and have them translated into a quote
                    .doTry()
                        .bean(WordTranslateBean.class)
                        // and send it to a mock
                        .to("mock:split")
                    .doCatch(HttpOperationFailedException.class)
                        .process(new Processor() {
                            @Override
                            public void process(Exchange exchange) throws Exception {
                                HttpOperationFailedException e = (HttpOperationFailedException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
                                if(e.getStatusCode()!=404){
                                    throw e;
                                }
                            }
                        })
                    .end()
                .end()
                // log the outgoing aggregated message
                .log("Aggregated ${body}")
                // and send it to a mock as well
                .to("mock:result");
apache-camel
4个回答
1
投票

为什么不根据响应代码抛出自定义异常?那是一种选择。基本上你可以捕获原始的 http 异常,检查响应代码,抛出你的自定义异常。你可以发布你的路线吗?这种方式很容易实现,只是想看看你是如何组织你的路线的。


1
投票

基本上我们仍然需要在发生异常时使用“stopOnException”来停止拆分器。但是要控制拆分器应该中断哪个异常,您可以使用“doTry..doCatch”块并在相应的 catch 块中再次抛出异常。

from("timer:categoryRouter?delay=0")
                    .process(new Processor() {
                        @Override
                        public void process(Exchange exchange) throws Exception {
                            exchange.getIn().setBody("A,F,B,D,C");
                        }
                    })
                // tell Splitter to use the aggregation strategy which handles and ignores exceptions
                .split(body(), new MyIgnoreFailureAggregationStrategy())
                    // log each splitted message
                    .log("Split line ${body}")
                    // and have them translated into a quote
                    .doTry()
                        .bean(WordTranslateBean.class)
                        // and send it to a mock
                        .to("mock:split")
                    .doCatch(HttpOperationFailedException.class)
                        .log("Ignore Exception")
                    .doCatch(IOException.class)
                        .throwException(new IOException())
                    .doCatch(UnsupportedOperationException.class)
                        .log("Ignore Exception")
                    .end()
                .end()
                // log the outgoing aggregated message
                .log("Aggregated ${body}")
                // and send it to a mock as well
                .to("mock:result");

如果异常与 http 相关,并且想检查响应代码以采取相应的行动,那么您可以提出我的问题,该问题具有有效的解决方案。


0
投票

您可以捕获异常并决定如何处理它们。分离器内部:

<doTry>
    <!-- Your Splitter logic here -->
    <doCatch>
        <exception>java.lang.IllegalStateException</exception>
        <log message="This exception happened here, but not a problem.."/>
    </doCatch>
    <doCatch>
        <exception>java.io.IOException</exception>
        <log message="Big problem here. STOPPING.."/>
        <stop/>
    </doCatch>
    <doFinally>
        <to uri="mock:finally"/>
    </doFinally>
</doTry>

0
投票

您可以在 aggregateStrategy 中检查异常:

public class MyIgnoreFailureAggregationStrategy implements AggregationStrategy {

 @Override
 public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {

 if (newExchange.getException() != null) {
    // Set exception to trigger stopOnException function, otherwise ignore the exception
    if (newExchange.getException() instanceof HttpOperationFailedException) {
       oldExchange.setException(newExchange.getException());
    }
    return oldExchange;
 }

 if (oldExchange == null) {
   return newExchange;
 }

 String body = newExchange.getIn().getBody(String.class);
 String existing = oldExchange.getIn().getBody(String.class);
 oldExchange.getIn().setBody(existing + "+" + body);
 return oldExchange;
 }
}
© www.soinside.com 2019 - 2024. All rights reserved.