Spring 5.3中ResponseStatusException返回500而非BAD_REQUEST的问题
ResponseStatusException抛出后返回500而非指定400状态码的排查与解决
问题描述
原本使用@ControllerAdvice统一处理异常,切换为Spring 5引入的ResponseStatusException后,抛出该异常时并未返回构造方法指定的BAD_REQUEST(400)状态码,反而返回500,但响应消息中包含400的状态信息。使用的spring-web版本为5.3.9。
示例代码
@RestController @RequestMapping(V_1) public class SpringController { @PostMapping(value = "/bids", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<Object> postBids(@Valid @RequestBody BidRequest bidRequest) throws JsonProcessingException { if (!validateBidRequest(bidRequest)) { throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Bid request fails validation"); } return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(response); } private boolean validateBidRequest(BidRequest bidRequest) { return bidRequest.getApplication() != null; } }
异常响应示例
{ "timestamp": "2023-11-21T22:25:41.507509Z", "id": "13f34470-842c-4a53-8c9d-57186446e301", "status": 500, "name": "org.springframework.web.server.ResponseStatusException", "message": "400 BAD_REQUEST \"Bid request fails validation\"" }
排查结论
初步排查发现ResponseStatusException未被Spring自带的ResponseStatusExceptionHandler处理。最终定位原因:某个Gradle依赖引入了一个带@ControllerAdvice注解的全局异常处理类,该类捕获所有异常,但其switch case逻辑中未匹配ResponseStatusException类型,默认将其归类为INTERNAL_SERVICE_ERROR(500)返回。
解决方案
- 定位问题依赖:执行Gradle命令
./gradlew dependencies分析依赖树,找到引入该全局异常处理类的依赖。 - 针对性处理:
- 若该依赖非必要,直接从项目依赖中排除;
- 若必须保留依赖,可在项目中自定义高优先级的
@ControllerAdvice类,显式处理ResponseStatusException:@ControllerAdvice @Order(Ordered.HIGHEST_PRECEDENCE) public class CustomResponseStatusExceptionHandler { @ExceptionHandler(ResponseStatusException.class) public ResponseEntity<Object> handleResponseStatusException(ResponseStatusException ex) { return ResponseEntity.status(ex.getStatus()) .body(ex.getReason()); } } - 或协调依赖提供方修改全局异常处理逻辑,在switch case中添加
ResponseStatusException分支,提取其携带的状态码返回。
内容的提问来源于stack exchange,提问作者thurmc
相关产品推荐
相关产品推荐

