Camel使用JsonPath拆分无结果时路由异常的排查与解决
解决Apache Camel拆分缺失JSON元素时触发错误的问题
我之前也碰到过一模一样的情况:在Camel路由里想用JsonPath拆分$._attachments字段发送到指定端点,正常场景下运行没问题,但碰到不含这个字段的JSON对象时,本以为会让CamelSplitSize变成0,结果直接触发了DefaultErrorHandler,导致路由无法正常完成。
先看看我最开始写的有问题的路由代码:
public class DiscoverAttachmentsFromCouchResponseRoute extends RouteBuilder { @Override public void configure() throws Exception { JsonPathExpression jsonPathExpression = new JsonPathExpression("$._attachments"); Predicate no_attachments = header("CamelSplitSize").isEqualTo("0"); errorHandler( deadLetterChannel("broker1:queue:dlq.jsonobject.queue") .maximumRedeliveries(3) ); from("broker1:queue:input.jsonobject.queue") .routeId("DiscoverAttachmentsFromCouchResponseRoute") .threads(2) .split(jsonPathExpression) .marshal().json(JsonLibrary.Jackson,true) .to("broker1:queue:with.attachments.queue") .choice() .when(no_attachments) .log("No attachments found.") .to("broker1:queue:no.attachments.queue") .otherwise() .log("A grand total of '${header.CamelSplitSize}' attachments were found.") .endChoice(); } }
问题核心出在**split(jsonPathExpression)**这里:当JSON里没有_attachments字段时,这个JsonPathExpression不会返回空集合,而是直接抛出异常,根本到不了后续判断CamelSplitSize的步骤,自然就触发了死信队列的错误处理逻辑。
后来我换了个思路:先判断字段是否存在,再分流处理,而不是直接拆分。修改后的核心路由逻辑是这样的:
.choice() .when().jsonpath("$._attachments", true) .to("vm://withattach") .otherwise() .to("vm://withoutattach") .endChoice();
之后只需要为这两个VM端点分别创建独立的消费者路由:
- 针对
vm://withattach的路由里,再执行拆分、序列化、发送到with.attachments.queue的逻辑 - 针对
vm://withoutattach的路由里,直接处理无附件的场景,比如打日志、发送到no.attachments.queue
这么做的关键原因是:jsonpath("$._attachments", true)这个判断会优雅地检查目标路径是否存在,不存在时不会抛出异常,而是直接走otherwise分支,完美避开了拆分时的异常问题。而原来用JsonPathExpression配合split()的方式,没有这种容错机制,一旦字段缺失就会触发错误。
内容的提问来源于stack exchange,提问作者Michiel
相关产品推荐
相关产品推荐

