骆驼分裂器 - 停止循环特定异常

时间:2016-04-08 20:10:27

标签: apache-camel

如何在特定异常上停止对骆驼分离器进行循环? " 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");

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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>

答案 2 :(得分:0)

基本上我们仍然需要使用“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有关并且想要检查响应代码以便采取相应的行动,那么您可以提出具有可行解决方案的问题。