Apache Camel路由始终返回404,异常处理逻辑未生效
Apache Camel路由始终返回404,异常处理逻辑未生效
我帮你分析下问题所在:你已经用onException捕获了HttpOperationFailedException并标记为handled(true),但路由还是直接返回404,没走到后续的choice逻辑,大概率是没有重置Exchange中的HTTP响应状态码,导致Camel仍然把原始的404状态返回给客户端,后续逻辑被跳过了。另外也需要确认direct:getSomeDataAndReturn404路由是否真的把异常传播了出来。
给你几个针对性的解决方案:
方案1:在异常处理器中重置HTTP响应状态码
这是最可能解决问题的方式,在处理404异常时,手动把HTTP响应状态码改成200(或者你需要的其他状态码),让Camel继续执行后续路由逻辑:
from("direct:putExample") .onException(HttpOperationFailedException.class) .handled(true) .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { HttpOperationFailedException exception = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, HttpOperationFailedException.class); if (exception.getStatusCode() == 404) { // 日志记录+设置默认响应体 exchange.getIn().setBody("Default response for 404"); // 关键:重置HTTP响应状态码,避免直接返回404 exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 200); } exchange.getIn().setHeader("404Handled", true); } }) .end() .setHeader(Constants.HEADER_EMAIL, simple("${body[email]}")) .to("direct:getSomeDataAndReturn404") .choice() .when(header("404Handled")) .log("Handled a 404 error. Continuing with custom logic.") .process(exchange -> { System.out.println("Test"); }) .otherwise() .log("No 404 error. Continuing normal route.") .process(exchange -> { System.out.println("Test"); }) .endChoice();
方案2:检查direct路由是否传播异常
如果direct:getSomeDataAndReturn404里调用了HTTP端点,且设置了throwExceptionOnFailure=false(这个参数默认是true,非2xx响应会抛出异常),那它不会抛出异常,而是直接返回404响应,你的onException自然捕获不到。这种情况要改成检查响应状态码来分支处理:
from("direct:putExample") .setHeader(Constants.HEADER_EMAIL, simple("${body[email]}")) .to("direct:getSomeDataAndReturn404") .choice() // 直接检查HTTP响应状态码 .when(header(Exchange.HTTP_RESPONSE_CODE).isEqualTo(404)) .log("Received 404 response. Continuing with custom logic.") .process(exchange -> { System.out.println("Test for 404"); exchange.getIn().setBody("Default response for 404"); // 按需重置状态码 exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 200); }) .otherwise() .log("No 404 response. Continuing normal route.") .process(exchange -> { System.out.println("Test for normal"); }) .endChoice();
方案3:调整onException的作用域
如果你的路由构建器里有多个路由,也可以把onException定义在所有路由之外(顶层),让它对所有路由生效,确保异常能被正确捕获:
// 顶层异常处理,对所有路由生效 onException(HttpOperationFailedException.class) .handled(true) .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { HttpOperationFailedException exception = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, HttpOperationFailedException.class); if (exception.getStatusCode() == 404) { exchange.getIn().setBody("Default response for 404"); exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 200); } exchange.getIn().setHeader("404Handled", true); } }); // 你的putExample路由 from("direct:putExample") .setHeader(Constants.HEADER_EMAIL, simple("${body[email]}")) .to("direct:getSomeDataAndReturn404") .choice() .when(header("404Handled")) .log("Handled a 404 error. Continuing with custom logic.") .process(exchange -> { System.out.println("Test"); }) .otherwise() .log("No 404 error. Continuing normal route.") .process(exchange -> { System.out.println("Test"); }) .endChoice();
备注:内容来源于stack exchange,提问作者PastorPL
相关产品推荐
相关产品推荐

