spring 中 HttpStatus 与 ResponseEntity

spring 中 HttpStatus 与 ResponseEntity

在Spring框架(尤其是Spring Web模块)中,org.springframework.http.HttpStatusorg.springframework.http.ResponseEntity是处理HTTP响应的核心类,二者配合使用可灵活控制HTTP响应的状态、头部和体内容。以下是详细解析:

一、HttpStatus:HTTP状态码的枚举封装

1. 定义与作用

HttpStatus是一个枚举类,封装了所有标准的HTTP状态码(如200、404、500等),每个枚举常量对应一个具体的HTTP状态,包含状态码的数字值、原因短语(Reason Phrase)等信息。

其核心作用是:提供标准化的HTTP状态码定义 ,避免硬编码数字(如200),提高代码的可读性、可维护性和规范性。

2. 核心属性与方法

每个HttpStatus枚举常量都包含以下关键信息(可通过方法获取):

  • 状态码数值 :如200404等,通过int value()方法获取。
  • 原因短语 :状态码的文字描述(如OKNot Found),通过String getReasonPhrase()方法获取。
  • 状态码系列 :HTTP状态码分为5类(1xx~5xx),通过Series series()方法获取所属系列(SeriesHttpStatus的内部枚举,包含INFORMATIONAL(1xx)、SUCCESSFUL(2xx)、REDIRECTION(3xx)、CLIENT_ERROR(4xx)、SERVER_ERROR(5xx))。

3. 常用枚举常量

  • 2xx成功类

    • OK:200,请求成功(常用)。
    • CREATED:201,资源创建成功(如POST新增资源)。
    • NO_CONTENT:204,请求成功但无响应体(如DELETE删除资源)。
  • 4xx客户端错误类

    • BAD_REQUEST:400,请求参数错误。
    • UNAUTHORIZED:401,未认证(如未登录)。
    • FORBIDDEN:403,权限不足。
    • NOT_FOUND:404,资源不存在。
  • 5xx服务器错误类

    • INTERNAL_SERVER_ERROR:500,服务器内部错误。
    • SERVICE_UNAVAILABLE:503,服务不可用。

4. 实用方法

  • 系列判断:如is2xxSuccessful()(是否为2xx成功状态)、is4xxClientError()(是否为4xx客户端错误)等,简化状态码类型的判断。

    java 复制代码
    boolean isSuccess = HttpStatus.OK.is2xxSuccessful(); // true
  • 状态码匹配:matches(int statusCode)判断当前枚举是否匹配指定的数字状态码。

    java 复制代码
    boolean isOk = HttpStatus.OK.matches(200); // true

5. 枚举常量详解

以下是HTTP状态码的作用和应用场景说明,按状态码类别整理为表格:

状态码 名称 作用 应用场景
1xx 信息性状态码 表示服务器已接收请求,正在处理或等待进一步操作
100 Continue 服务器已接收请求头,允许客户端继续发送请求体 客户端发送大文件前,先确认服务器是否愿意接收(如上传大文件)
101 Switching Protocols 服务器同意切换到客户端请求的协议 WebSocket连接建立时,从HTTP协议升级到WebSocket协议
102 Processing 服务器正在处理请求,尚未完成 处理耗时请求(如复杂查询)时,告知客户端请求仍在处理中
103 Early Hints 服务器提前返回部分响应头,帮助客户端预加载资源 大型页面加载时,提前告知客户端缓存策略或预连接资源
103 Checkpoint(已废弃) 原用于断点续传标记 已被103 Early Hints替代,不再推荐使用
2xx 成功状态码 表示请求已成功被服务器接收、理解并处理
200 OK 请求成功,返回预期响应内容 绝大多数成功的GET、POST等请求(如获取数据、提交表单成功)
201 Created 请求成功且创建了新资源 POST请求创建资源(如新建用户、订单)时返回
202 Accepted 请求已被接受,但尚未处理完成 异步处理请求(如后台任务提交后,返回任务受理状态)
203 Non-Authoritative Information 请求成功,但响应元数据来自第三方 代理服务器返回原始服务器的资源,但部分元数据被代理修改
204 No Content 请求成功,但无返回内容 DELETE请求删除资源成功,或不需要返回内容的操作
205 Reset Content 请求成功,客户端应重置视图 表单提交后,告知客户端重置表单输入状态
206 Partial Content 部分请求成功,返回指定范围的资源 断点续传(如大文件下载时,客户端通过Range头请求部分内容)
207 Multi-Status 多状态响应,包含多个资源的处理结果 WebDAV协议中,批量操作多个资源时返回各资源的状态
208 Already Reported 资源已在其他请求中报告过 WebDAV绑定操作中,避免重复报告同一资源状态
226 IM Used 服务器已执行GET请求,响应是对资源的修改 基于HTTP的增量更新(如版本控制系统返回资源修改部分)
3xx 重定向状态码 表示客户端需要进一步操作才能完成请求
300 Multiple Choices 请求有多个可能的响应,需用户选择 资源有多个版本(如不同语言、格式)时,提供选择列表
301 Moved Permanently 资源已永久移动到新URL 网站域名变更,旧URL永久重定向到新URL(客户端应更新书签)
302 Found 资源临时移动到新URL 临时跳转(如维护页面临时重定向到通知页,客户端下次仍用原URL)
302 Moved Temporarily(已废弃) 同302 Found,旧称 已被302 Found替代,语义一致
303 See Other 请求完成后,需用GET方法访问新URL POST表单提交成功后,重定向到结果页(避免刷新重复提交)
304 Not Modified 资源未修改,客户端可使用缓存 客户端带ETag/Last-Modified头请求,服务器确认资源未变时返回
305 Use Proxy(已废弃) 资源必须通过指定代理访问 因安全问题已不推荐使用,现代浏览器多不支持
307 Temporary Redirect 临时重定向,保持原请求方法 POST请求临时重定向时,仍用POST方法访问新URL(如临时服务器迁移)
308 Permanent Redirect 永久重定向,保持原请求方法 PUT请求永久重定向时,仍用PUT方法访问新URL(如API域名永久变更)
4xx 客户端错误状态码 表示请求存在错误,服务器无法处理
400 Bad Request 请求语法错误或参数无效 提交的表单数据格式错误、JSON参数缺失等
401 Unauthorized 请求需要身份验证 未登录用户访问需授权的接口,或令牌过期/无效
402 Payment Required 预留状态码,需付费才能访问 极少使用,理论上用于付费内容访问(如订阅服务)
403 Forbidden 服务器拒绝请求(已认证但无权限) 登录用户访问无权限的资源(如普通用户访问管理员页面)
404 Not Found 请求的资源不存在 访问不存在的URL(如拼写错误的页面、已删除的资源)
405 Method Not Allowed 请求方法不被允许 用POST访问只支持GET的接口,或用DELETE访问只读资源
406 Not Acceptable 服务器无法提供客户端接受的格式 客户端通过Accept头要求JSON格式,但服务器只支持XML
407 Proxy Authentication Required 需要代理服务器认证 客户端通过代理访问时,未通过代理的身份验证
408 Request Timeout 客户端请求超时 客户端发送请求过慢,服务器等待超时
409 Conflict 请求与服务器当前状态冲突 并发修改资源(如两人同时编辑文档,后提交者冲突)
410 Gone 资源已永久删除,不再可用 原URL对应的资源被彻底删除,且无替代地址
411 Length Required 服务器要求Content-Length头,客户端未提供 客户端发送带请求体的请求(如POST)但未指定内容长度
412 Precondition Failed 请求头的前置条件不满足 客户端用If-Match验证资源版本,服务器发现版本不匹配
413 Payload Too Large 请求体过大,服务器拒绝处理 客户端上传超大文件,超过服务器限制
413 Request Entity Too Large(已废弃) 同413 Payload Too Large,旧称 已被413 Payload Too Large替代
414 URI Too Long 请求URI过长,服务器无法处理 客户端请求的URL包含过多参数或过长路径
414 Request-URI Too Long(已废弃) 同414 URI Too Long,旧称 已被414 URI Too Long替代
415 Unsupported Media Type 请求体的媒体类型不被支持 客户端发送application/xml数据,但服务器只支持application/json
416 Requested Range Not Satisfiable Range请求的范围无效 客户端请求文件的第1000-2000字节,但文件仅500字节
417 Expectation Failed 服务器无法满足Expect请求头 客户端用Expect: 100-continue,但服务器不支持
418 I'm a teapot 服务器是茶壶,不能煮咖啡(玩笑性质) 愚人节玩笑,多用于测试或彩蛋(如某些API的趣味响应)
419 Insufficient Space On Resource(已废弃) 资源存储空间不足 旧版WebDAV使用,已被507 Insufficient Storage替代
420 Method Failure(已废弃) 请求方法执行失败 曾用于Spring框架,已弃用,建议用422或500替代
421 Destination Locked(已废弃) 目标资源被锁定 旧版WebDAV使用,已被423 Locked替代
422 Unprocessable Entity 请求语法正确,但语义错误 表单验证失败(如邮箱格式正确但已被注册)
423 Locked 资源被锁定,无法操作 WebDAV中,资源被其他用户锁定编辑时
424 Failed Dependency 因前置请求失败,当前请求无法完成 WebDAV批量操作中,某资源处理失败导致后续请求依赖失败
425 Too Early 服务器不愿处理可能重复的请求 防止重放攻击(如客户端重复发送同一请求)
426 Upgrade Required 客户端需升级协议 服务器仅支持HTTPS,客户端用HTTP访问时,要求升级
428 Precondition Required 服务器要求请求包含前置条件 服务器为防止并发修改,要求请求带If-Match等头
429 Too Many Requests 客户端请求过于频繁,触发限流 API调用超过速率限制(如1分钟内请求超过100次)
431 Request Header Fields Too Large 请求头过大,服务器拒绝处理 客户端发送的Cookie或其他头信息超过服务器限制
451 Unavailable For Legal Reasons 资源因法律原因不可用 资源被法院要求屏蔽(如版权侵权、违法内容)
5xx 服务器错误状态码 表示服务器处理请求时发生错误
500 Internal Server Error 服务器内部通用错误 服务器代码异常(如NullPointerException)
501 Not Implemented 服务器不支持请求的方法 客户端使用服务器未实现的HTTP方法(如PROPFIND)
502 Bad Gateway 网关/代理收到无效响应 反向代理服务器从上游服务器收到错误响应
503 Service Unavailable 服务器暂时不可用 服务器维护、过载时,返回此状态(可带Retry-After头)
504 Gateway Timeout 网关/代理等待上游响应超时 反向代理服务器等待后端服务响应超时
505 HTTP Version Not Supported 服务器不支持请求的HTTP版本 客户端用HTTP/3请求,服务器仅支持HTTP/1.1
506 Variant Also Negotiates 内容协商过程出错(循环引用) 服务器配置错误,导致协商过程无限循环
507 Insufficient Storage 服务器存储不足 WebDAV中,服务器无法存储上传的资源
508 Loop Detected 服务器检测到无限循环 WebDAV中,处理请求时发现资源引用循环
509 Bandwidth Limit Exceeded 服务器带宽超限 非标准状态码,部分服务器用于表示带宽用尽
510 Not Extended 请求需要扩展,但服务器不支持 客户端请求的扩展功能未被服务器实现
511 Network Authentication Required 需要网络认证 公共WiFi中,用户未登录前访问互联网(跳转登录页)

二、ResponseEntity:HTTP响应的完整封装

1. 定义与作用

ResponseEntity<T>是一个泛型类 ,用于封装HTTP响应的完整信息,包括:

  • 响应状态码(通过HttpStatus指定);
  • 响应头(HttpHeaders);
  • 响应体(泛型T,即返回给客户端的数据)。

其核心作用是:在Spring MVC/WebFlux控制器中,作为方法返回值,精细化控制HTTP响应的各个部分 (相比@ResponseBody仅能控制响应体,ResponseEntity更灵活)。

2. 核心结构

ResponseEntity的核心组成:

  • private final T body:响应体(可为null,如204状态无体);
  • private final HttpHeaders headers:响应头(如Content-TypeAuthorization等);
  • private final HttpStatus statusCode:响应状态码(HttpStatus枚举)。

3. 常用创建方式

ResponseEntity提供了多种静态工厂方法和构造器,简化创建过程:

  • 直接指定状态码和响应体

    java 复制代码
    // 返回200 OK + 响应体
    return ResponseEntity.ok(user); // 等价于 ResponseEntity.status(HttpStatus.OK).body(user)
    
    // 返回201 Created + 响应体
    return ResponseEntity.status(HttpStatus.CREATED).body(newUser);
  • 带响应头的响应

    java 复制代码
    HttpHeaders headers = new HttpHeaders();
    headers.add("Location", "/users/123"); // 新增资源的URL
    return new ResponseEntity<>(user, headers, HttpStatus.CREATED);
  • 无响应体的响应

    java 复制代码
    // 返回204 No Content(无响应体)
    return ResponseEntity.noContent().build();
    
    // 返回404 Not Found(无响应体)
    return ResponseEntity.notFound().build();
  • 自定义响应头和状态

    java 复制代码
    return ResponseEntity.status(HttpStatus.FORBIDDEN)
                         .header("X-Error", "Permission denied")
                         .body("无权访问");

4. 核心方法

  • T getBody():获取响应体(可能为null);
  • HttpHeaders getHeaders():获取响应头;
  • HttpStatus getStatusCode():获取响应状态码(HttpStatus枚举);
  • int getStatusCodeValue():获取状态码的数字值(如200)。

三、二者的关系与使用场景

1. 配合关系

HttpStatusResponseEntity的"状态码工具":ResponseEntity通过HttpStatus枚举来指定响应的状态码,避免直接使用数字,保证规范性。

2. 典型使用场景

在Spring控制器中,当需要:

  • 不仅返回数据(响应体),还需指定状态码(如创建资源返回201);
  • 自定义响应头(如设置Cache-ControlLocation);
  • 返回无响应体的状态(如204、404);

此时必须使用ResponseEntity,并结合HttpStatus指定状态。

示例:

java 复制代码
@RestController
@RequestMapping("/users")
public class UserController {

    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User savedUser = userService.save(user); // 保存用户
        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(URI.create("/users/" + savedUser.getId())); // 资源位置
        // 返回201状态 + 响应体 + 自定义头
        return new ResponseEntity<>(savedUser, headers, HttpStatus.CREATED);
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        return userService.findById(id)
                .map(ResponseEntity::ok) // 存在则返回200 + 数据
                .orElseGet(() -> ResponseEntity.notFound().build()); // 不存在返回404
    }
}

总结

  • HttpStatus:标准化HTTP状态码的枚举,提供状态码、原因短语及系列判断,避免硬编码。
  • ResponseEntity:封装HTTP响应的完整信息(状态码、头、体),是Spring控制器中精细化控制响应的核心类。

二者配合使用,可优雅地处理各种HTTP响应场景,是Spring Web开发的基础工具。

相关推荐
编程爱好者熊浪4 小时前
测试需要使用HTTPS,怎么申请一个免费的测试域名
网络协议·http·https
间彧4 小时前
Java 堆、栈、方法区详解与项目实战
后端
间彧4 小时前
Java内存区域详解与项目实战
后端
SimonKing4 小时前
【开发者必备】Spring Boot 2.7.x:WebMvcConfigurer配置手册来了(三)!
java·后端·程序员
ArabySide4 小时前
【Spring Boot】深入浅出Spring Boot中的控制反转与依赖注入
java·spring boot·后端
shepherd1114 小时前
破局延时任务(上):为什么选择Spring Boot + DelayQueue来自研分布式延时队列组件?
java·spring boot·后端
limuyang25 小时前
【http3/quic】cronet 已经原生集成在Android内啦!还不快来开开眼!
android·http·google
非凡ghost5 小时前
EaseUS Fixo(易我视频照片修复)
前端·javascript·后端
非凡ghost5 小时前
Avast Cleanup安卓版(手机清理优化)
前端·javascript·后端