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

Spring Boot REST API如何选择正确的HTTP响应码?

遵循REST规范:优先使用标准HTTP状态码,自定义码作为补充

你的当前实现虽然能正常工作,但不符合REST API的设计规范,更推荐结合标准HTTP状态码+自定义业务状态码的方式,原因如下:

为什么全返回200不合理?

  • 违背HTTP协议语义:HTTP状态码是协议的核心组成部分,本身就承载了请求结果的语义(比如201表示资源已创建、401表示未授权、409表示资源冲突)。全返回200会让这些语义丢失,客户端必须解析响应体才能判断请求结果,增加了客户端的处理复杂度。
  • 工具链兼容性差:API网关、监控系统、调试工具(比如Postman)都是基于HTTP状态码做请求过滤、告警、统计的。全200会导致这些工具无法识别错误请求,比如监控无法及时告警5xx级别的服务器错误。
  • 语义模糊:自定义状态码需要客户端开发者额外查阅文档对应含义,而标准HTTP状态码是行业通用的,开发者一看就懂,降低了沟通成本。

合理的实现方式:标准HTTP状态码为主,自定义业务码为辅

你可以保留自定义状态码来区分更细的业务场景,但必须用标准HTTP状态码来标识请求的整体结果:

1. 成功场景的状态码选择

  • 创建资源(比如/new-user):使用HttpStatus.CREATED(201),符合“资源已成功创建”的语义。
  • 查询/更新资源:使用HttpStatus.OK(200)。
  • 删除资源:可以使用HttpStatus.NO_CONTENT(204)表示无返回内容的成功。

修改后的创建用户示例:

@PostMapping("/new-user")
public ResponseEntity<SuccessResponse<UserDto>> createUser(
        @Valid @RequestBody UserDto userDto) {
    UserDto createdUserDto = this.userService.createUser(userDto);
    SuccessResponse<UserDto> successResponse = new SuccessResponse<>(
            AppConstants.SUCCESS_CODE,
            AppConstants.SUCCESS_MESSAGE,
            createdUserDto
    );
    return new ResponseEntity<>(successResponse, HttpStatus.CREATED); // 用201替代200
}

2. 异常场景的状态码选择

根据异常类型匹配对应的HTTP状态码:

  • 重复资源(比如重复注册):HttpStatus.CONFLICT(409)
  • 令牌过期/未授权:HttpStatus.UNAUTHORIZED(401)
  • 参数校验失败:HttpStatus.BAD_REQUEST(400)
  • 资源未找到:HttpStatus.NOT_FOUND(404)
  • 服务器内部错误:HttpStatus.INTERNAL_SERVER_ERROR(500)

修改后的异常处理示例:

@ExceptionHandler(DuplicateResourceException.class)
public ResponseEntity<ApiResponse> duplicateResourceFoundException(DuplicateResourceException ex) {
    ApiResponse apiResponse = new ApiResponse(
            ex.getMessage(),
            "2002", // 自定义业务码
            AppConstants.ERROR_MESSAGE
    );
    return new ResponseEntity<>(apiResponse, HttpStatus.CONFLICT); // 用409替代200
}

@ExceptionHandler(TokenExpiredException.class)
public ResponseEntity<ApiResponse> tokenExpiredException(TokenExpiredException ex) {
    ApiResponse apiResponse = new ApiResponse(
            "Token is expired",
            "2001", // 自定义业务码
            AppConstants.ERROR_MESSAGE
    );
    return new ResponseEntity<>(apiResponse, HttpStatus.UNAUTHORIZED); // 用401替代200
}

3. 自定义状态码的作用

自定义状态码用来在同一个HTTP状态码下区分更细的业务场景,比如:

  • 同样是400(参数错误),自定义码可以区分“必填项缺失”“格式错误”“长度超限”等
  • 同样是401(未授权),可以区分“令牌过期”“令牌无效”“未登录”等

这种方式既遵循了REST规范,又保留了业务细节,对客户端开发(可以用HTTP状态码做通用逻辑,比如401跳登录)和服务端运维(可以用状态码监控错误)都更友好。

内容的提问来源于stack exchange,提问作者ayush

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 02:50:07