如果在单独的类中定义了异常子句,则Camel异常处理不起作用

时间:2012-02-14 20:39:42

标签: exception routes apache-camel

我正在尝试构建一个具有多个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中也验证了相同的行为。

谢谢, 阿南德

2 个答案:

答案 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"));
  }
}