2.3.3. doTry、doCatch 和 lastly
概述
要在路由内部处理异常,您可以使用 doTry
、doCatch
和 doFinally
子句的组合,该子句以类似于 Java 的 尝试
、捕获
和 最终
块的方式处理异常。
doCatch 和 Java 捕获之间的相似性
通常,路由定义中的 doCatch ()
子句的行为与 Java 代码中的 catch ()
语句类似。特别是,doCatch ()
子句支持以下功能:
在单一
do Try
块中可以有多个doCatch
子句,其中有多个 doCatch 子句。doCatch
子句按照它们显示的顺序进行测试,就像 Javacatch ()
语句一样。Apache Camel 执行与引发异常匹配的第一个doCatch
子句。注意这个算法与
Exception 子句计算机上计算机上使用
的异常匹配算法不同,请参阅 第 2.3.1 节 “onException Clause” 了解详细信息。-
使用 结构(请参阅 “在 doCatch 中增加异常”一节)在
doCatch
子句中重新增加例外情况。
doCatch 的特殊功能
但是,doCatch ()
子句有一些特殊功能,但在 Java catch ()
语句中没有模拟。以下功能专用于 doCatch ()
:
-
在
doCatch
子句中附加一个onWhen
sub-clause (请参阅 “使用 onWhen 捕获条件异常”一节)来有条件捕获 异常。
Example
以下示例演示了如何在 Java DSL 中编写 doTry
块,其中将执行 doCatch ()
子句(如果 IOException
异常或 IllegalStateException
异常被引发),并且 始终执行 doFinally ()
子句,在引发异常时是否引发异常。
from("direct:start") .doTry() .process(new ProcessorFail()) .to("mock:result") .doCatch(IOException.class, IllegalStateException.class) .to("mock:catch") .doFinally() .to("mock:finally") .end();
在 Spring XML 中,或等效于 Spring XML:
<route> <from uri="direct:start"/> <!-- here the try starts. its a try .. catch .. finally just as regular java code --> <doTry> <process ref="processorFail"/> <to uri="mock:result"/> <doCatch> <!-- catch multiple exceptions --> <exception>java.io.IOException</exception> <exception>java.lang.IllegalStateException</exception> <to uri="mock:catch"/> </doCatch> <doFinally> <to uri="mock:finally"/> </doFinally> </doTry> </route>
在 doCatch 中增加异常
可以使用构造在 doCatch ()
子句中重新增加异常,如下所示:
from("direct:start") .doTry() .process(new ProcessorFail()) .to("mock:result") .doCatch(IOException.class) .to("mock:io") // Rethrow the exception using a construct instead ofhandled(false)
which is deprecated in adoTry/doCatch
clause. .throwException(new IllegalArgumentException("Forced")) .doCatch(Exception.class) // Catch all other exceptions. .to("mock:error") .end();
您还可以使用在 doTry/doCatch
子句中弃用的处理器 (false)
来重新增加异常:
.process(exchange -> {throw exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);})
在前面的示例中,如果 doCatch ()
捕获了 IOException
,则当前交换将发送到 mock:io
端点,然后 IOException
正在重新浏览。这为消费者端点在路由开始时(在 from ()
命令中)是一个处理异常的机会。
以下示例演示了如何在 Spring XML 中定义相同的路由:
<route> <from uri="direct:start"/> <doTry> <process ref="processorFail"/> <to uri="mock:result"/> <doCatch> <to uri="mock:io"/> <throwException message="Forced" exceptionType="java.lang.IllegalArgumentException"/> </doCatch> <doCatch> <!-- Catch all other exceptions. --> <exception>java.lang.Exception</exception> <to uri="mock:error"/> </doCatch> </doTry> </route>
使用 onWhen 捕获条件异常
Apache Camel doCatch ()
子句的一个特殊功能是您可以根据运行时评估的表达式对异常进行破坏。换句话说,如果您使用表格的子句捕获异常,那么 doCatch (ExceptionList).doWhen ( Expression )
只会在运行时捕获异常(如果 predicate 表达式,表达式 )评估为 true
。
例如,只有异常消息中包含该异常时,以下 doTry
块会捕获异常 IOException
和 IllegalStateException
:
from("direct:start")
.doTry()
.process(new ProcessorFail())
.to("mock:result")
.doCatch(IOException.class, IllegalStateException.class)
.onWhen(exceptionMessage().contains("Severe"))
.to("mock:catch")
.doCatch(CamelExchangeException.class)
.to("mock:catchCamel")
.doFinally()
.to("mock:finally")
.end();
在 Spring XML 中,或等效于 Spring XML:
<route> <from uri="direct:start"/> <doTry> <process ref="processorFail"/> <to uri="mock:result"/> <doCatch> <exception>java.io.IOException</exception> <exception>java.lang.IllegalStateException</exception> <onWhen> <simple>${exception.message} contains 'Severe'</simple> </onWhen> <to uri="mock:catch"/> </doCatch> <doCatch> <exception>org.apache.camel.CamelExchangeException</exception> <to uri="mock:catchCamel"/> </doCatch> <doFinally> <to uri="mock:finally"/> </doFinally> </doTry> </route>
doTry 中的嵌套条件
有不同的选项可用于将 Camel 异常处理添加到 JavaDSL 路由中。dotry ()
为处理异常创建尝试或捕获块,对于路由特定的错误处理非常有用。
如果要捕获 ChoiceDefinition
内的异常,您可以使用以下 doTry
块:
from("direct:wayne-get-token").setExchangePattern(ExchangePattern.InOut) .doTry() .to("https4://wayne-token-service") .choice() .when().simple("${header.CamelHttpResponseCode} == '200'") .convertBodyTo(String.class) .setHeader("wayne-token").groovy("body.replaceAll('\"','')") .log(">> Wayne Token : ${header.wayne-token}") .endChoice() .doCatch(java.lang.Class (java.lang.Exception>) .log(">> Exception") .endDoTry(); from("direct:wayne-get-token").setExchangePattern(ExchangePattern.InOut) .doTry() .to("https4://wayne-token-service") .doCatch(Exception.class) .log(">> Exception") .endDoTry();