我正在尝试构建一个具有多个camel路由的应用程序,这些路由在内部重用了许多常用路由。 因此,我试图在几个不同的Route Builder类中隔离路由,然后在需要的地方连接路由。
例如,与发送电子邮件相关的所有路由都进入EmailRouteBuilder类,处理特定JMS队列的所有路由都进入MyQueueRouteBuilder类。 我认为这应该没问题,因为Camel不区分类,只查找路由定义。
此外,我还将几个异常处理路由分组到一个单独的ExceptionHandlingRouteBuilder中。
我也通过在Spring中定义驼峰上下文来连接所有不同的类 -
<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
<propertyPlaceholder id="properties" location="classpath:${env}/autoimport.properties"/>
<!-- Common Routes -->
<routeBuilder ref="emailRouteBuilder" />
<routeBuilder ref="myQueueRouteBuilder" />
<routeBuilder ref="httpRouteBuilder" />
<routeBuilder ref="exceptionsRouteBuilder" />
<routeBuilder ref="customer1RouteBuilder" />
<routeBuilder ref="customer2RouteBuilder" />
</camelContext>
我的例外路由器包含许多例外条款,如 -
onException(ConnectException.class)
.routeId("connectExceptionEP")
.handled(true)
.log("Caught Exception: ")
.to("direct:gracefulExit");
..
..
..
但是,看起来在另一个类中定义的异常存在问题,或者就此而言,在主路由定义中单独定义。
我通过查找正在引导的路由(通过routeId)并在检查何时抛出异常时在日志中验证了这一点。
此外,为了进一步确认,我采用了http Connect异常处理路由并将其直接放在httpRouteBuilder中并且... ..! ,异常处理现在可以解决这个异常......
我在这里遗漏了一些东西,以便在其自己的类中很好地定义所有异常。 ?
我正在使用Apache Camel 2.9.0,但我在2.8.3中也验证了相同的行为。
谢谢, 阿南德
答案 0 :(得分:11)
正确,onException()子句仅适用于当前的RouteBuilder的路由定义......
说,您可以通过让所有RouteBuilders扩展ExceptionRouteBuilder并调用super.configure()来重用这些定义......就像这样
public class MyRouteBuilder extends ExceptionRouteBuilder {
@Override
public void configure() throws Exception {
super.configure();
from("direct:start").throwException(new Exception("error"));
}
}
...
public class ExceptionRouteBuilder implements RouteBuilder {
@Override
public void configure() throws Exception {
onException(Exception.class).handled(true).to("mock:error");
}
}
甚至只是在ExceptionBuilder类中使用静态方法来设置给定RouteBuilder实例的子句
public class MyRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
ExceptionBuilder.setup(this);
from("direct:start").throwException(new Exception("error"));
}
}
...
public class ExceptionBuilder {
public static void setup(RouteBuilder routeBuilder) {
routeBuilder.onException(Exception.class).handled(true).to("mock:error");
}
}
答案 1 :(得分:0)
根据接受的答案,我找到了一种更简洁的方法来实现异常处理,因此您不必在每个路由中调用super.configure()。只需调用一个在基类的构造函数中处理onException的方法。
//Base class that does exception handling
public abstracExceptionRouteBuildert class BaseAbstractRoute extends RouteBuilder {
protected BaseAbstractRoute() {
handleException();
}
private void handleException() {
onException(Exception.class).handled(true).to("mock:error");
}
}
//Extend the base class
public class MyRouteBuilder extends BaseAbstractRoute {
@Override
public void configure() throws Exception {
from("direct:start").throwException(new Exception("error"));
}
}