You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)返回。

解决方案

  1. 定位问题依赖:执行Gradle命令./gradlew dependencies分析依赖树,找到引入该全局异常处理类的依赖。
  2. 针对性处理:
    • 若该依赖非必要,直接从项目依赖中排除;
    • 若必须保留依赖,可在项目中自定义高优先级的@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 18:05:17