Spring Boot HTTP状态码详解

发布于:2025-09-07 ⋅ 阅读:(20) ⋅ 点赞:(0)

Spring Boot HTTP状态码完全指南:从入门到精通

前言

在RESTful API开发中,HTTP状态码是与客户端通信的重要桥梁。Spring Boot通过HttpStatus枚举提供了完整的HTTP状态码支持。本文将深入解析这些状态码的含义、使用场景以及在Spring Boot中的最佳实践。

1. 信息响应 (100-199) - 请求处理中

1.1 CONTINUE (100)

  • 含义:客户端应继续发送请求的剩余部分
  • 使用场景:当客户端发送Expect: 100-continue头时,服务器确认可以接收请求体
  • Spring Boot示例:大文件上传时的预检确认

1.2 SWITCHING_PROTOCOLS (101)

  • 含义:服务器同意客户端请求,切换协议
  • 使用场景:WebSocket连接升级、HTTP/2协议切换

1.3 PROCESSING (102)

  • 含义:服务器已收到请求,正在处理但尚未完成
  • 使用场景:长时间运行的操作,如大数据处理

1.4 EARLY_HINTS (103)

  • 含义:用于在最终响应之前发送一些HTTP头
  • 使用场景:预加载资源,优化页面加载性能

2. 成功响应 (200-299) - 请求成功处理

2.1 OK (200) ✅

  • 含义:请求成功
  • 使用场景:GET请求成功返回数据
  • Spring Boot示例
@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
    User user = userService.findById(id);
    return ResponseEntity.ok(user); // 返回200状态码
}

2.2 CREATED (201) 🆕

  • 含义:资源创建成功
  • 使用场景:POST请求创建新资源
  • 最佳实践:应在响应头中包含新资源的Location
@PostMapping("/users")
public ResponseEntity<User> createUser(@RequestBody User user) {
    User savedUser = userService.save(user);
    return ResponseEntity
        .created(URI.create("/users/" + savedUser.getId()))
        .body(savedUser);
}

2.3 ACCEPTED (202) ⏳

  • 含义:请求已接受,但处理尚未完成
  • 使用场景:异步操作,如批量处理、邮件发送

2.4 NO_CONTENT (204) 🚫

  • 含义:请求成功,但无内容返回
  • 使用场景:DELETE操作成功、UPDATE操作无需返回数据
@DeleteMapping("/users/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
    userService.deleteById(id);
    return ResponseEntity.noContent().build(); // 返回204
}

2.5 PARTIAL_CONTENT (206) 📦

  • 含义:部分内容请求成功
  • 使用场景:分片下载、断点续传

3. 重定向响应 (300-399) - 需要进一步操作

3.1 MOVED_PERMANENTLY (301) 🔄

  • 含义:资源已永久移动到新位置
  • 使用场景:网站改版、API版本迁移

3.2 FOUND (302) 🔍

  • 含义:资源临时移动到其他位置
  • 使用场景:临时重定向,如登录后跳转

3.3 SEE_OTHER (303) 👀

  • 含义:查看其他URI获取响应
  • 使用场景:POST成功后重定向到GET请求

3.4 NOT_MODIFIED (304) 📄

  • 含义:资源未修改,可使用缓存版本
  • 使用场景:配合If-Modified-Since或ETag使用

4. 客户端错误 (400-499) - 客户端请求有问题

4.1 BAD_REQUEST (400) ❌

  • 含义:请求语法错误或参数无效
  • 使用场景:参数验证失败、JSON格式错误
  • Spring Boot验证示例
@PostMapping("/users")
public ResponseEntity<?> createUser(
    @Valid @RequestBody UserCreateRequest request) {
    // 自动验证,失败返回400
    userService.create(request);
    return ResponseEntity.ok().build();
}

4.2 UNAUTHORIZED (401) 🔐

  • 含义:需要身份验证
  • 使用场景:未提供认证信息或认证失败

4.3 FORBIDDEN (403) ⚠️

  • 含义:服务器理解请求但拒绝执行
  • 使用场景:权限不足、IP限制

4.4 NOT_FOUND (404) 🔍

  • 含义:请求的资源不存在
  • 使用场景:访问不存在的URL或资源ID
@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
    return userService.findById(id)
        .map(ResponseEntity::ok)
        .orElse(ResponseEntity.notFound().build()); // 返回404
}

4.5 METHOD_NOT_ALLOWED (405) 🚷

  • 含义:请求方法不被允许
  • 使用场景:对只读资源执行POST操作

4.6 UNPROCESSABLE_ENTITY (422) 📝

  • 含义:请求格式正确但语义错误
  • 使用场景:业务规则验证失败,如邮箱已注册

4.7 TOO_MANY_REQUESTS (429) 🚦

  • 含义:请求频率过高
  • 使用场景:API限流、防刷机制

5. 服务器错误 (500-599) - 服务器处理失败

5.1 INTERNAL_SERVER_ERROR (500) 💥

  • 含义:服务器内部错误
  • 使用场景:未捕获的异常、数据库连接失败
  • Spring Boot异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ApiResponse<?>> handleException(Exception e) {
        log.error("服务器异常", e);
        return ResponseEntity
            .status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body(ApiResponse.error(500, "系统繁忙,请稍后重试"));
    }
}

5.2 NOT_IMPLEMENTED (501) 🔧

  • 含义:服务器不支持请求的功能
  • 使用场景:未实现的API端点

5.3 BAD_GATEWAY (502) 🌐

  • 含义:网关或代理服务器从上游服务器收到无效响应
  • 使用场景:微服务调用失败

5.4 SERVICE_UNAVAILABLE (503) ⚡

  • 含义:服务暂时不可用
  • 使用场景:系统维护、过载保护

5.5 GATEWAY_TIMEOUT (504) ⏰

  • 含义:网关超时
  • 使用场景:上游服务响应超时

6. Spring Boot中的最佳实践

6.1 使用ResponseEntity精确控制状态码

@GetMapping("/custom")
public ResponseEntity<String> customResponse() {
    if (someCondition) {
        return ResponseEntity.status(HttpStatus.CREATED).body("Created");
    } else {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Not Found");
    }
}

6.2 统一的错误响应格式

@Data
public class ErrorResponse {
    private int status;
    private String error;
    private String message;
    private String path;
    private LocalDateTime timestamp;
    
    public ErrorResponse(HttpStatus status, String message, String path) {
        this.status = status.value();
        this.error = status.getReasonPhrase();
        this.message = message;
        this.path = path;
        this.timestamp = LocalDateTime.now();
    }
}

6.3 状态码选择指南

操作类型 成功状态码 失败状态码
查询(GET) 200 OK 404 Not Found
创建(POST) 201 Created 400 Bad Request
更新(PUT) 200 OK 404 Not Found
删除(DELETE) 204 No Content 404 Not Found
部分更新(PATCH) 200 OK 400 Bad Request

7. 常见问题解答

Q: 什么时候使用200 vs 204?

A: 当需要返回数据时用200,不需要返回数据时用204。

Q: 401和403的区别?

A: 401表示未认证(需要登录),403表示已认证但权限不足。

Q: 400和422的区别?

A: 400表示请求语法错误,422表示语法正确但业务逻辑错误。

8. 总结

正确地使用HTTP状态码是构建高质量RESTful API的关键。Spring Boot的HttpStatus枚举为我们提供了完整的支持:

  1. 信息类状态码用于通信协商
  2. 成功类状态码表示操作成功
  3. 重定向类状态码处理资源位置变更
  4. 客户端错误类状态码帮助客户端纠正请求
  5. 服务器错误类状态码表示服务端问题

通过合理选择状态码并提供清晰的错误信息,可以大大提升API的可用性和开发者体验。

9. 完整HTTP状态码参考表格

以下是Spring Boot中HttpStatus枚举包含的所有状态码的完整参考表格:

状态码 枚举常量 状态系列 含义描述 使用场景
100 CONTINUE INFORMATIONAL 继续 客户端应继续发送请求的剩余部分
101 SWITCHING_PROTOCOLS INFORMATIONAL 切换协议 WebSocket连接升级、HTTP/2协议切换
102 PROCESSING INFORMATIONAL 处理中 长时间运行的操作,如大数据处理
103 EARLY_HINTS INFORMATIONAL 早期提示 预加载资源,优化页面加载性能
103 CHECKPOINT INFORMATIONAL 检查点(已弃用) 已弃用,使用EARLY_HINTS替代
200 OK SUCCESSFUL 成功 GET请求成功返回数据
201 CREATED SUCCESSFUL 已创建 POST请求创建新资源
202 ACCEPTED SUCCESSFUL 已接受 异步操作,如批量处理
203 NON_AUTHORITATIVE_INFORMATION SUCCESSFUL 非权威信息 代理服务器修改了响应
204 NO_CONTENT SUCCESSFUL 无内容 DELETE操作成功、UPDATE操作无需返回数据
205 RESET_CONTENT SUCCESSFUL 重置内容 客户端需要重置文档视图
206 PARTIAL_CONTENT SUCCESSFUL 部分内容 分片下载、断点续传
207 MULTI_STATUS SUCCESSFUL 多状态 WebDAV扩展,多个操作状态
208 ALREADY_REPORTED SUCCESSFUL 已报告 WebDAV,成员已在之前报告中
226 IM_USED SUCCESSFUL IM已使用 服务器已对请求进行了实例操作
300 MULTIPLE_CHOICES REDIRECTION 多种选择 请求的资源有多个表示形式
301 MOVED_PERMANENTLY REDIRECTION 永久移动 资源已永久移动到新位置
302 FOUND REDIRECTION 临时移动 资源临时移动到其他位置
302 MOVED_TEMPORARILY REDIRECTION 临时移动(已弃用) 已弃用,使用FOUND替代
303 SEE_OTHER REDIRECTION 查看其他 POST成功后重定向到GET请求
304 NOT_MODIFIED REDIRECTION 未修改 资源未修改,可使用缓存版本
305 USE_PROXY REDIRECTION 使用代理(已弃用) 已弃用
307 TEMPORARY_REDIRECT REDIRECTION 临时重定向 请求应使用另一个URI重复
308 PERMANENT_REDIRECT REDIRECTION 永久重定向 请求和所有未来请求应使用另一个URI
400 BAD_REQUEST CLIENT_ERROR 错误请求 请求语法错误或参数无效
401 UNAUTHORIZED CLIENT_ERROR 未授权 需要身份验证
402 PAYMENT_REQUIRED CLIENT_ERROR 需要付款 保留用于未来支付系统
403 FORBIDDEN CLIENT_ERROR 禁止访问 权限不足、IP限制
404 NOT_FOUND CLIENT_ERROR 未找到 请求的资源不存在
405 METHOD_NOT_ALLOWED CLIENT_ERROR 方法不允许 请求方法不被允许
406 NOT_ACCEPTABLE CLIENT_ERROR 不可接受 服务器无法生成客户端接受的内容
407 PROXY_AUTHENTICATION_REQUIRED CLIENT_ERROR 需要代理认证 代理服务器需要认证
408 REQUEST_TIMEOUT CLIENT_ERROR 请求超时 服务器等待请求超时
409 CONFLICT CLIENT_ERROR 冲突 请求与当前资源状态冲突
410 GONE CLIENT_ERROR 已删除 资源已永久删除
411 LENGTH_REQUIRED CLIENT_ERROR 需要长度 需要Content-Length头
412 PRECONDITION_FAILED CLIENT_ERROR 前提条件失败 请求头中前提条件失败
413 PAYLOAD_TOO_LARGE CLIENT_ERROR 负载过大 请求实体过大
413 REQUEST_ENTITY_TOO_LARGE CLIENT_ERROR 请求实体过大(已弃用) 已弃用,使用PAYLOAD_TOO_LARGE
414 URI_TOO_LONG CLIENT_ERROR URI过长 请求URI过长
414 REQUEST_URI_TOO_LONG CLIENT_ERROR 请求URI过长(已弃用) 已弃用,使用URI_TOO_LONG
415 UNSUPPORTED_MEDIA_TYPE CLIENT_ERROR 不支持的媒体类型 不支持的媒体格式
416 REQUESTED_RANGE_NOT_SATISFIABLE CLIENT_ERROR 请求范围不可满足 无法满足请求的范围
417 EXPECTATION_FAILED CLIENT_ERROR 期望失败 无法满足Expect请求头
418 I_AM_A_TEAPOT CLIENT_ERROR 我是茶壶 HTTP愚人节笑话,实际不使用
419 INSUFFICIENT_SPACE_ON_RESOURCE CLIENT_ERROR 资源空间不足(已弃用) 已弃用
420 METHOD_FAILURE CLIENT_ERROR 方法失败(已弃用) 已弃用
421 DESTINATION_LOCKED CLIENT_ERROR 目标锁定(已弃用) 已弃用
422 UNPROCESSABLE_ENTITY CLIENT_ERROR 不可处理的实体 请求格式正确但语义错误
423 LOCKED CLIENT_ERROR 已锁定 资源被锁定
424 FAILED_DEPENDENCY CLIENT_ERROR 依赖失败 WebDAV,依赖的操作失败
425 TOO_EARLY CLIENT_ERROR 太早 服务器不愿意处理可能重放的请求
426 UPGRADE_REQUIRED CLIENT_ERROR 需要升级 客户端应切换到不同的协议
428 PRECONDITION_REQUIRED CLIENT_ERROR 需要前提条件 需要条件性请求
429 TOO_MANY_REQUESTS CLIENT_ERROR 请求过多 API限流、防刷机制
431 REQUEST_HEADER_FIELDS_TOO_LARGE CLIENT_ERROR 请求头字段过大 请求头字段太大
451 UNAVAILABLE_FOR_LEGAL_REASONS CLIENT_ERROR 因法律原因不可用 因法律要求无法提供
500 INTERNAL_SERVER_ERROR SERVER_ERROR 内部服务器错误 服务器内部错误
501 NOT_IMPLEMENTED SERVER_ERROR 未实现 服务器不支持请求的功能
502 BAD_GATEWAY SERVER_ERROR 错误网关 网关或代理服务器收到无效响应
503 SERVICE_UNAVAILABLE SERVER_ERROR 服务不可用 系统维护、过载保护
504 GATEWAY_TIMEOUT SERVER_ERROR 网关超时 上游服务响应超时
505 HTTP_VERSION_NOT_SUPPORTED SERVER_ERROR HTTP版本不支持 不支持的HTTP协议版本
506 VARIANT_ALSO_NEGOTIATES SERVER_ERROR 变体也可协商 透明内容协商中的循环引用
507 INSUFFICIENT_STORAGE SERVER_ERROR 存储空间不足 WebDAV,存储空间不足
508 LOOP_DETECTED SERVER_ERROR 检测到循环 WebDAV,检测到无限循环
509 BANDWIDTH_LIMIT_EXCEEDED SERVER_ERROR 带宽限制超出 带宽使用超出限制
510 NOT_EXTENDED SERVER_ERROR 未扩展 需要进一步扩展才能完成请求
511 NETWORK_AUTHENTICATION_REQUIRED SERVER_ERROR 需要网络认证 需要网络认证才能访问

表格说明:

  1. 状态码系列说明:

    • INFORMATIONAL (100-199): 信息响应,请求处理中
    • SUCCESSFUL (200-299): 成功响应,请求成功处理
    • REDIRECTION (300-399): 重定向响应,需要进一步操作
    • CLIENT_ERROR (400-499): 客户端错误,客户端请求有问题
    • SERVER_ERROR (500-599): 服务器错误,服务器处理失败
  2. 已弃用状态码: 表格中标记为"已弃用"的状态码不建议在新项目中使用

  3. 常用状态码: 在实际开发中,最常用的状态码包括:200, 201, 204, 400, 401, 403, 404, 500


希望本文能帮助您更好地理解和使用Spring Boot中的HTTP状态码。如有疑问,欢迎留言讨论!


网站公告

今日签到

点亮在社区的每一天
去签到