Apache Camel REST路由(含处理器)配置问题及错误响应码实现咨询
Hey there! Let's break down what's going wrong with your Camel REST route and how to fix it, plus cover how to handle error responses like validation failures.
你的当前路由核心问题
First off, the main reason your route isn't working is tied to how GET requests handle parameters:
- GET request parameters are query parameters, not part of the request body. So when you use
exchange.getIn().getBody()to check for a String, you'll always getnullhere—your filter condition will never pass, meaning the processor and response code logic never run. - You also haven't handled the scenario where the filter fails, so the request will either hang or return an empty, uninformative response.
修正后的路由代码示例
Here's a adjusted version of your code that fixes the parameter retrieval and adds basic validation handling:
public class RestRoute extends RouteBuilder { public static final String DIRECT_HELLO = "direct:hello"; private final UpperCaseProcessor upperCaseProcessor; public RestRoute(UpperCaseProcessor upperCaseProcessor) { this.upperCaseProcessor = upperCaseProcessor; } @Override public void configure() throws Exception { // 配置REST端点,明确参数类型(显式声明更清晰) rest("/myapp") .get("/hello") .param() .dataType("string") .name("name") .type(RestParamType.query) // 标记为查询参数(默认也是,但显式更直观) .required(true) // 如果name是必填参数,加上这个强制校验 .endParam() .to(DIRECT_HELLO); from(DIRECT_HELLO) .tracing() // 用choice分支处理参数验证和正常逻辑 .choice() // 检查name参数是否存在且为字符串类型 .when(simple("${header.name} is not null && ${header.name} is instanceof java.lang.String")) // 把查询参数放到Body里,方便处理器处理 .process(exchange -> { String name = exchange.getIn().getHeader("name", String.class); exchange.getIn().setBody(name); }) .process(upperCaseProcessor) .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(200)) .setHeader(Exchange.CONTENT_TYPE, constant("text/plain")) // 明确响应类型 // 参数不合法时返回400错误 .otherwise() .setBody(constant("Error: Missing or invalid 'name' parameter")) .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(400)) .setHeader(Exchange.CONTENT_TYPE, constant("text/plain")); } }
实现错误响应码的几种常用方式
1. 路由内分支判断(适合单个端点的简单验证)
像上面的代码一样,用choice()+when()来检查参数合法性、数据格式等,直接在路由里分支返回对应错误码和提示信息,适合针对性的简单校验。
2. 全局异常捕获(适合统一处理业务/系统异常)
如果你的处理器或路由逻辑会抛出自定义异常,可以用onException()全局配置异常处理规则,避免重复代码:
// 在configure方法开头添加全局异常处理 onException(ValidationFailedException.class) .handled(true) // 标记异常已处理,不会继续向上传播 .setBody(constant("Request validation failed: please check your input")) .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(400)) .setHeader(Exchange.CONTENT_TYPE, constant("text/plain")); onException(ProcessingException.class) .handled(true) .setBody(constant("Internal processing error, please try again later")) .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(500)) .setHeader(Exchange.CONTENT_TYPE, constant("text/plain"));
然后在你的处理器中,当验证失败时抛出ValidationFailedException,处理出错时抛出ProcessingException即可,Camel会自动触发对应的错误响应。
3. 专用验证组件(适合复杂校验场景)
如果需要更复杂的验证(比如JSON Schema校验、Bean Validation注解校验),可以使用Camel的REST Validation组件,它能自动帮你完成请求校验,并返回标准化的错误响应。
小提示
- 对于GET请求,所有参数都会被Camel放到Exchange的Header中,用
${header.参数名}或exchange.getIn().getHeader("参数名")获取即可;POST/PUT请求的请求体才会在getBody()里。 - 设置响应时,记得指定
Exchange.CONTENT_TYPE头,让客户端明确响应的数据类型。
备注:内容来源于stack exchange,提问作者Kiran K

