Quarkus接口传入非法参数返回404而非400问题求助
Quarkus接口参数校验返回状态码异常问题
接口代码
@GET @Produces(MediaType.APPLICATION_JSON) @Path("/greeting/{name}") public Uni<String> greeting(String name, @QueryParam("limit") int limit) { return service.greeting(name.toString()); }
测试场景
localhost:8080/greeting/someName?limit=454—— 正常返回200,符合预期localhost:8080/greeting/someName?limit=dfg—— 返回404而非预期的400
问题描述
Quarkus应用中该接口在传入无法转换为整数的limit参数时,返回404错误状态码,但相同场景下Spring Boot非响应式应用可正常返回400(参数错误)。
问题原因
这是Quarkus基于JAX-RS规范的默认行为:当请求参数无法完成类型转换时,JAX-RS会判定该请求不匹配任何已定义的资源方法,因此返回404。而Spring Boot的参数校验逻辑是在请求匹配到对应接口后,再对参数进行校验,所以会返回400。
解决方案
有两种常见方式让Quarkus返回400状态码:
- 手动处理参数转换与异常
将参数类型改为String,自行处理转换逻辑,捕获转换失败的异常并抛出400错误:
@GET @Produces(MediaType.APPLICATION_JSON) @Path("/greeting/{name}") public Uni<String> greeting(String name, @QueryParam("limit") String limitStr) { int limit; try { limit = Integer.parseInt(limitStr); } catch (NumberFormatException e) { throw new WebApplicationException("limit参数必须是整数", Response.Status.BAD_REQUEST); } return service.greeting(name.toString()); }
- 使用Quarkus参数校验扩展
添加quarkus-hibernate-validator依赖,配合异常处理器捕获参数转换错误:
- 先添加Maven依赖:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-hibernate-validator</artifactId> </dependency>
- 修改接口并添加全局异常处理器:
@GET @Produces(MediaType.APPLICATION_JSON) @Path("/greeting/{name}") public Uni<String> greeting(String name, @QueryParam("limit") @NotNull int limit) { return service.greeting(name.toString()); }
@Provider public class ParameterExceptionMapper implements ExceptionMapper<ConstraintViolationException> { @Override public Response toResponse(ConstraintViolationException exception) { return Response.status(Response.Status.BAD_REQUEST) .entity("请求参数无效") .type(MediaType.APPLICATION_JSON) .build(); } @Provider public static class NumberFormatExceptionMapper implements ExceptionMapper<NumberFormatException> { @Override public Response toResponse(NumberFormatException exception) { return Response.status(Response.Status.BAD_REQUEST) .entity("limit参数必须是有效的整数") .type(MediaType.APPLICATION_JSON) .build(); } } }
这样当参数无法转换为int时,会触发对应的异常处理器,返回400状态码。
内容的提问来源于stack exchange,提问作者Tigran Harutyunyan
相关产品推荐
相关产品推荐

