我正在为jboss / camel项目构建一个异常处理程序。使用onException
子句捕获异常是有效的,我可以从bean访问捕获的异常,但这只能直接在异常处理程序中工作。由于我需要在多个不同的项目中使用此处理程序,因此我希望从处理程序指向不同的路径(在不同的上下文中),并集中处理异常。但是在路由之后,捕获的异常不再可访问。为什么会这样,我该如何解决这个问题。我不想在我的所有项目中添加另一个EJB。
<camelContext id="project1Context" xmlns="http://camel.apache.org/schema/spring">
<onException>
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
<bean ref="projectSpecificBean" method="peekException" />
<to uri="activemq:queue:centralExceptionHandling" />
</onException>
[... the routes of the context, where the exception happens ...]
</camelContext>
在豆子里:
public void peekException(Exchange camelExchange) {
Exception e = camelExchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
log.warn("Caught general Exception", e);
}
这使我可以访问bean中的Exception。但是,当我从<bean ref="projectSpecificBean" method="peekException" />
子句中删除onException
并将相同的东西添加到activemq:queue:centralExceptionHandling
的路径(对于那个项目的本地bean,在不同的camelContext中)时,我不能在交易所的任何地方找到例外。
答案 0 :(得分:1)
为了能够在ActiveMQ队列的客户端上接收异常,您需要使用camel jms组件选项“transferExchange”。必须在双方都启用此选项(在发送到ActiveMQ队列并从中接收时)。在这种情况下,不仅将发送消息正文/标题,而且将转移整个交换。请参阅http://camel.apache.org/jms.html(transferExchange选项)。通常,它看起来在异常路由和异常处理程序路由之间没有队列。以下是文档中的一些细节:
您可以通过电线而不仅仅是身体和标题来转移交换。传输以下字段:正文,Out正文,Fault主体,In标题,Out标题,Fault标题,exchange属性,exchange异常。这要求对象是可序列化的。 Camel将排除任何不可序列化的对象并将其记录在WARN级别。您必须在生产者和消费者端都启用此选项,因此Camel知道有效负载是Exchange而不是常规负载。
代码示例:
<camelContext id="project1Context" xmlns="http://camel.apache.org/schema/spring">
<onException>
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
<bean ref="projectSpecificBean" method="peekException" />
<to uri="activemq:queue:centralExceptionHandling?transferExchange=true" />
</onException>
[... the routes of the context, where the exception happens ...]
</camelContext>
// Somewhere in the central exception handler.
<camelContext id="exceptionHandlerContext" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="activemq:queue:centralExceptionHandling?transferExchange=true" />
<!-- Here you will have almost completely the same exchange as it was before it was sent to ActiveMq -->
</route>
</camelContext>