Java 调用子路由后的意外行为
我有一个包装路由(包装路由),它可以调用不同的子路由。 我的问题是,根据子路由中的异常处理,包装器路由在调用后的处理方式不同 当子路由没有错误(NOERROUTE)、没有异常处理(ErrorRouteUnhandled)或在try catch块中处理异常(ErrorRouteTryCatch)时,包装器路由正常工作。这意味着WrapperRoute工作到结束并写入最后一个日志 当子路由具有OneException定义(ErrorRouteHandled)时,将仅执行来自WrapperRoute的finally块。将不显示路由中的最后一个日志 为什么在try-catch块之后停止包装器路由 这是我测试这种行为的完整代码。在每个测试用例中,我都编写了日志 在测试用例中,handledTest是包装器路由中丢失的最后一个日志。Java 调用子路由后的意外行为,java,apache-camel,Java,Apache Camel,我有一个包装路由(包装路由),它可以调用不同的子路由。 我的问题是,根据子路由中的异常处理,包装器路由在调用后的处理方式不同 当子路由没有错误(NOERROUTE)、没有异常处理(ErrorRouteUnhandled)或在try catch块中处理异常(ErrorRouteTryCatch)时,包装器路由正常工作。这意味着WrapperRoute工作到结束并写入最后一个日志 当子路由具有OneException定义(ErrorRouteHandled)时,将仅执行来自WrapperRoute的
package test;
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.junit.Test;
import at.mic.edis.test.TemplateCamelTest;
public class ExcepionHandlingTest extends TemplateCamelTest{
@Test
public void noErrorTest() throws Exception {
template.sendBodyAndHeader("direct:WRAPPER", "BODY", "SUBROUTE", "direct:NO-ERROR");
// 2014-11-20 10:35:23,335 [main] INFO route1 - WRAPPER-Start
// 2014-11-20 10:35:23,350 [main] INFO route2 - NO-ERROR-ROUTE: run without exception
// 2014-11-20 10:35:23,353 [main] INFO route1 - WRAPPER: Finally
// 2014-11-20 10:35:23,353 [main] INFO route1 - WRAPPER: End of wrapper route
}
@Test
public void unhandledTest() throws Exception {
template.sendBodyAndHeader("direct:WRAPPER", "BODY", "SUBROUTE", "direct:UNHANDLED");
// 2014-11-20 10:36:34,932 [main] INFO route1 - WRAPPER-Start
// 2014-11-20 10:36:34,948 [main] INFO route3 - UNHANDLED: throw exception
// 2014-11-20 10:36:34,952 [main] INFO route1 - WRAPPER: Catch exception
// 2014-11-20 10:36:34,953 [main] INFO route1 - WRAPPER: Finally
// 2014-11-20 10:36:34,953 [main] INFO route1 - WRAPPER: End of wrapper route
}
@Test
public void handledTest() throws Exception {
template.sendBodyAndHeader("direct:WRAPPER", "BODY", "SUBROUTE", "direct:HANDLED");
// 2014-11-20 10:37:47,898 [main] INFO route1 - WRAPPER-Start
// 2014-11-20 10:37:47,913 [main] INFO route4 - HANDLED: throw exception
// 2014-11-20 10:37:47,916 [main] INFO route4 - HANDLED: Exception handled
// 2014-11-20 10:37:47,919 [main] INFO route1 - WRAPPER: Finally
}
@Test
public void tryCatchTest() throws Exception {
template.sendBodyAndHeader("direct:WRAPPER", "BODY", "SUBROUTE", "direct:TRY-CATCH");
// 2014-11-20 10:38:55,871 [main] INFO route1 - WRAPPER-Start
// 2014-11-20 10:38:55,887 [main] INFO route5 - TRY-CATCH: throw exception
// 2014-11-20 10:38:55,889 [main] INFO route5 - TRY-CATCH: exception caught
// 2014-11-20 10:38:55,890 [main] INFO route5 - TRY-CATCH: finish
// 2014-11-20 10:38:55,891 [main] INFO route1 - WRAPPER: Finally
// 2014-11-20 10:38:55,892 [main] INFO route1 - WRAPPER: End of wrapper route
}
@Override
public RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
WrapperRoute wrapper = new WrapperRoute();
NoErrorRoute noError = new NoErrorRoute();
ErrorRouteUnhandled unhandled = new ErrorRouteUnhandled();
ErrorRouteHandled handled = new ErrorRouteHandled();
ErrorRouteTryCatch tryCatch = new ErrorRouteTryCatch();
CamelContext context = getContext();
context.addRoutes(wrapper);
context.addRoutes(noError);
context.addRoutes(unhandled);
context.addRoutes(handled);
context.addRoutes(tryCatch);
}
};
}
}
包装路线:
package test;
import org.apache.camel.builder.RouteBuilder;
import at.mic.edis.all.scheduler.processor.WrappedRoutingSlipBean;
public class WrapperRoute extends RouteBuilder{
@Override
public void configure() throws Exception {
onException(Exception.class)
.handled(true)
.log("WRAPPER: exception handler");
from("direct:WRAPPER")
.log("WRAPPER-Start")
.doTry()
.recipientList().method(WrappedEndpoint.class.getName())
.end()
.doCatch(Exception.class)
.log("WRAPPER: Catch exception")
.doFinally()
.log("WRAPPER: Finally")
.end()
.log("WRAPPER: End of wrapper route");
}
}
包装器端点:
package test;
import org.apache.camel.Exchange;
import org.apache.camel.Handler;
public class WrappedEndpoint {
@Handler
public Object process(Exchange exchange) throws Exception {
//Reads the direct endpoint for the subroute from the header
String endpoint = (String) exchange.getIn().getHeader("SUBROUTE");
return endpoint;
}
}
无错误:
package test;
import org.apache.camel.builder.RouteBuilder;
public class NoErrorRoute extends RouteBuilder {
@Override
public void configure() throws Exception {
from("direct:NO-ERROR")
.log("NO-ERROR-ROUTE: run without exception");
}
}
ErrorRouteUnhandled:
package test;
import org.apache.camel.builder.RouteBuilder;
public class ErrorRouteUnhandled extends RouteBuilder{
@Override
public void configure() throws Exception {
from("direct:UNHANDLED")
.log("UNHANDLED: throw exception")
.throwException(new Exception("Exception"));
}
}
错误路由处理:
package test;
import org.apache.camel.builder.RouteBuilder;
public class ErrorRouteHandled extends RouteBuilder{
@Override
public void configure() throws Exception {
onException(Exception.class)
.handled(true)
.log("HANDLED: Exception handled");
from("direct:HANDLED")
.log("HANDLED: throw exception")
.throwException(new Exception("Exception"));
}
}
ErrorRouteTrack:
package test;
import org.apache.camel.builder.RouteBuilder;
public class ErrorRouteTryCatch extends RouteBuilder{
@Override
public void configure() throws Exception {
from("direct:TRY-CATCH")
.log("TRY-CATCH: throw exception")
.doTry()
.throwException(new Exception("Exception"))
.doCatch(Exception.class)
.log("TRY-CATCH: exception caught")
.end()
.log("TRY-CATCH: finish");
}
}
编辑:
可以将属性Exchange.ERRORHANDLER\u HANDLED(=CamelErrorHandlerHandled)设置为false。这与未定义错误处理或在OneException块中设置.handled(false)时属性的外观相同
我从WrapperRoute中修改了doFinally()-块,现在一切正常:
...
.doFinally()
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
// Print all properties
for (Entry<String, Object> entry: exchange.getProperties().entrySet()){
System.out.println(entry.getKey() + " | " + entry.getValue());
}
if (exchange.getProperty(Exchange.ERRORHANDLER_HANDLED)!=null){
System.out.println("Set error handler property to false");
exchange.setProperty(Exchange.ERRORHANDLER_HANDLED, false);
}
}
})
.log("WRAPPER: Finally")
.end()
...
。。。
.doFinally()
.进程(新处理器(){
@凌驾
公共作废进程(Exchange)引发异常{
//打印所有属性
对于(条目:exchange.getProperties().entrySet()){
System.out.println(entry.getKey()+“|”+entry.getValue());
}
if(exchange.getProperty(exchange.ERRORHANDLER_HANDLED)!=null){
System.out.println(“将错误处理程序属性设置为false”);
exchange.setProperty(exchange.ERRORHANDLER\u HANDLED,false);
}
}
})
.log(“包装器:Finally”)
(完)
...
在错误路由处理
中将处理
从真
(=没有故障返回到客户端)设置为假
,最后一个日志条目再次显示:
onException(Exception.class)
.handled(false) // changed from true to false
.log("HANDLED: Exception handled");
如果设置为true
则只处理doFinally()
零件中的一个步骤
事实上,我不知道这是一个bug还是按照设计工作 谢谢你的提示,但我不想更改我所有路线的所有OneException区块,因为它们超过200个。可以从WrapperRoute在doFinally块中设置属性(请参见我的编辑)。这也会导致一种行为,即可以处理多个步骤。@lahu89如果不这样使用,则不应将
handled
设置为true。设置Exchange.ERRORHANDLER\u HANDLED
可能是一种解决方案。但这看起来很神奇,应该避免。handled(true)
适用于我的所有其他路线。WrapperRoute只是我的程序中的一个新功能,它可以从外部动态调用其他路由并监视结果。我知道这看起来很神奇,应该避免,但我目前没有其他意见,这是我找到的第一个解决方案。