spring boot 3 responseentity 完全使用教程
在springboot3 | 统一返回类设计:从问题到实现一文中,我们通过自定义设计实现了标准化响应封装类,该方案有效确保了restful接口响应数据结构的统一性。值得关注的是,spring boot框架本身也提供了类似的标准化响应机制实现方案。
responseentity 是 spring boot 中控制 http 响应的核心工具——它能让你精准定义响应状态码、响应头、响应体,相比直接返回实体类或字符串,灵活性和规范性提升一个量级。接下来我会用最易懂的方式,结合宠物(pet)管理的实际场景,带你掌握 responseentity 的所有核心用法。
前置准备
1. 项目基础依赖(maven)
首先确保你的 spring boot 3 项目引入了核心依赖(以 3.2.x 版本为例):
<dependencies>
<!-- spring boot web 核心 -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<!-- lombok 简化实体类代码 -->
<dependency>
<groupid>org.projectlombok</groupid>
<artifactid>lombok</artifactid>
<optional>true</optional>
</dependency>
<!-- 参数校验(用于后续异常场景) -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-validation</artifactid>
</dependency>
</dependencies>2. 核心实体类 pet
补全 pet 类(添加 lombok 注解简化 getter/setter,参数校验注解用于后续案例):
import jakarta.validation.constraints.min;
import jakarta.validation.constraints.notblank;
import lombok.data;
@data // 自动生成getter、setter、tostring等方法
public class pet {
private long id; // 宠物id(唯一标识)
@notblank(message = "宠物名称不能为空")
private string name; // 宠物名称
@notblank(message = "宠物品种不能为空")
private string breed; // 宠物品种(如"金毛"、"布偶猫")
@min(value = 0, message = "宠物年龄不能为负数")
private integer age; // 宠物年龄(单位:岁)
}3. 模拟数据层(简化案例,无需数据库)
创建一个简单的 petservice 模拟内存数据操作,避免引入数据库复杂度:
import org.springframework.stereotype.service;
import java.util.hashmap;
import java.util.map;
@service
public class petservice {
// 模拟数据库存储宠物数据
private static final map<long, pet> pet_map = new hashmap<>();
// 初始化测试数据
static {
pet_map.put(1l, new pet(1l, "旺财", "金毛", 3));
pet_map.put(2l, new pet(2l, "咪宝", "布偶猫", 2));
}
// 根据id查询宠物
public pet getpetbyid(long id) {
return pet_map.get(id);
}
// 新增宠物
public pet addpet(pet pet) {
long newid = pet_map.size() + 1;
pet.setid(newid);
pet_map.put(newid, pet);
return pet;
}
// 删除宠物
public boolean deletepet(long id) {
return pet_map.remove(id) != null;
}
}核心场景案例(结合apipost测试)
接下来的所有案例,都基于 petcontroller 实现,每个场景对应一个真实的 http 业务场景,同时给出 apipost 测试步骤。
场景1:查询单个宠物(成功返回200)
业务需求:根据宠物id查询详情,存在则返回 200 ok + 宠物数据。
controller 代码:
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.http.responseentity;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.pathvariable;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;
@restcontroller
@requestmapping("/pets")
public class petcontroller {
@autowired
private petservice petservice;
// 场景1:查询单个宠物(成功返回200)
@getmapping("/{id}")
public responseentity<pet> getpet(@pathvariable long id) {
pet pet = petservice.getpetbyid(id);
// responseentity.ok() 等价于 responseentity.status(200).body(pet)
return responseentity.ok(pet);
}
}apipost 测试步骤:
- 新建请求,请求方式选择
get,url 填写http://localhost:8080/pets/1; - 点击「发送」,查看响应:
- 状态码:200 ok;
- 响应体:
{
"id": 1,
"name": "旺财",
"breed": "金毛",
"age": 3
}场景2:新增宠物(成功返回201 + 自定义响应头)
业务需求:新增宠物成功后,返回 201 created(符合 rest 规范),并在响应头中添加 location(指向新增宠物的查询地址)。
controller 新增代码:
// 场景2:新增宠物(返回201 + 自定义响应头)
@postmapping
public responseentity<pet> addpet(@valid @requestbody pet pet) {
pet newpet = petservice.addpet(pet);
// 构建响应:状态码201 + location响应头 + 新增宠物数据
return responseentity
.status(201) // 等价于 responseentity.created(uri.create("/pets/" + newpet.getid()))
.header("location", "/pets/" + newpet.getid())
.body(newpet);
}apipost 测试步骤:
- 新建请求,请求方式选择
post,url 填写http://localhost:8080/pets; - 切换到「body」标签,选择「json」格式,输入请求体:
{
"name": "小白",
"breed": "萨摩耶",
"age": 1
}- 点击「发送」,查看响应:
- 状态码:201 created;
- 响应头:包含
location: /pets/3; - 响应体:
{
"id": 3,
"name": "小白",
"breed": "萨摩耶",
"age": 1
}场景3:删除宠物(成功返回204 无响应体)
业务需求:删除宠物成功后,返回 204 no content(无响应体,符合 rest 规范);删除失败则返回 404。
controller 新增代码:
// 场景3:删除宠物(成功204,失败404)
@deletemapping("/{id}")
public responseentity<void> deletepet(@pathvariable long id) {
boolean isdeleted = petservice.deletepet(id);
if (isdeleted) {
// 204 无响应体,使用 responseentity.nocontent().build()
return responseentity.nocontent().build();
} else {
// 404 未找到
return responseentity.notfound().build();
}
}apipost 测试步骤:
- 新建请求,请求方式选择
delete,url 填写http://localhost:8080/pets/3; - 点击「发送」,查看响应:
- 状态码:204 no content;
- 响应体:为空(符合规范);
- 测试删除不存在的宠物(url 改为
http://localhost:8080/pets/99):- 状态码:404 not found。
场景4:查询宠物不存在(返回404 + 错误信息)
业务需求:查询不存在的宠物时,返回 404 not found + 自定义错误提示(而非空响应)。
改造场景1的查询接口:
// 场景4:改造查询接口,不存在则返回404 + 错误信息
@getmapping("/{id}")
public responseentity<object> getpet(@pathvariable long id) {
pet pet = petservice.getpetbyid(id);
if (pet != null) {
return responseentity.ok(pet);
} else {
// 构建自定义错误响应体,状态码404
map<string, string> error = new hashmap<>();
error.put("code", "pet_not_found");
error.put("message", "宠物id:" + id + " 不存在");
return responseentity.status(404).body(error);
}
}apipost 测试步骤:
- get 请求 url 填写
http://localhost:8080/pets/99; - 点击「发送」,查看响应:
- 状态码:404 not found;
- 响应体:
{
"code": "pet_not_found",
"message": "宠物id:99 不存在"
}场景5:参数校验失败(返回400 + 错误信息)
业务需求:新增/修改宠物时,参数不符合规则(如年龄负数、名称为空),返回 400 bad request + 详细错误提示。
新增全局异常处理器(统一处理参数校验异常):
import org.springframework.http.httpstatus;
import org.springframework.http.responseentity;
import org.springframework.validation.fielderror;
import org.springframework.web.bind.methodargumentnotvalidexception;
import org.springframework.web.bind.annotation.exceptionhandler;
import org.springframework.web.bind.annotation.restcontrolleradvice;
import java.util.hashmap;
import java.util.map;
@restcontrolleradvice // 全局异常处理
public class globalexceptionhandler {
// 处理参数校验异常
@exceptionhandler(methodargumentnotvalidexception.class)
public responseentity<map<string, string>> handlevalidationexceptions(methodargumentnotvalidexception ex) {
map<string, string> errors = new hashmap<>();
// 遍历所有校验失败的字段,收集错误信息
ex.getbindingresult().getallerrors().foreach((error) -> {
string fieldname = ((fielderror) error).getfield();
string errormessage = error.getdefaultmessage();
errors.put(fieldname, errormessage);
});
// 返回400 + 错误信息
return responseentity.status(httpstatus.bad_request).body(errors);
}
}apipost 测试步骤:
- post 请求新增宠物,请求体传入非法参数:
{
"name": "",
"breed": "哈士奇",
"age": -1
}- 点击「发送」,查看响应:
- 状态码:400 bad request;
- 响应体:
{
"name": "宠物名称不能为空",
"age": "宠物年龄不能为负数"
}前端测试
以下是极简版的 axios 请求案例,仅聚焦「前端处理 responseentity 返回内容」的核心逻辑,所有结果直接输出到浏览器控制台:
<!doctype html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<title>axios 处理 responseentity 示例</title>
<!-- 引入 axios -->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<button onclick="sendpetrequest()">发送新增宠物请求</button>
<script>
// 核心:发送post请求并处理responseentity返回内容
async function sendpetrequest() {
try {
// 1. 构造请求参数(与后端pet实体匹配)
const petdata = {
name: "小白",
breed: "萨摩耶",
age: 1
};
// 2. 发送post请求,调用后端返回responseentity的接口
const response = await axios.post(
'http://localhost:8080/pets', // 后端接口地址
petdata // 请求体
);
// 3. 控制台打印responseentity的核心返回内容(重点!)
console.log("===== responseentity 返回内容解析 =====");
console.log("1. http状态码(responseentity.status):", response.status); // 201
console.log("2. 响应头(responseentity.header设置的内容):", response.headers); // 含location等
console.log("3. location响应头具体值:", response.headers.location); // /pets/3
console.log("4. 响应体(responseentity.body):", response.data); // 新增的pet对象
console.log("========================================");
} catch (error) {
// 4. 异常场景:解析错误的responseentity内容
console.log("===== 错误的responseentity返回内容 =====");
if (error.response) {
// 后端返回了错误的responseentity(如400/404)
console.log("错误状态码:", error.response.status); // 400/404等
console.log("错误响应体:", error.response.data); // 后端返回的错误信息
} else {
console.log("请求异常:", error.message); // 网络/配置错误
}
}
}
</script>
</body>
</html>核心说明(聚焦 responseentity 处理)
response.status:对应后端responseentity.status(201)设置的 http 状态码;response.headers:对应后端responseentity.header("location", ...)设置的响应头;response.data:对应后端responseentity.body(...)设置的响应体(pet 对象/错误信息);- 错误场景下,
error.response.status/error.response.data可获取后端返回的错误 responseentity 内容(如 400 时的参数错误信息)。
测试步骤
- 启动后端 spring boot 项目;
- 用浏览器打开该 html 文件,点击按钮;
- 按 f12 打开控制台(console 标签),即可看到 responseentity 各部分内容的解析结果。
控制台输出示例(成功场景)
===== responseentity 返回内容解析 =====
1. http状态码(responseentity.status): 201
2. 响应头(responseentity.header设置的内容): {location: '/pets/3', ...}
3. location响应头具体值: /pets/3
4. 响应体(responseentity.body): {id: 3, name: '小白', breed: '萨摩耶', age: 1}
========================================
控制台输出示例(错误场景,如参数为空)
===== 错误的responseentity返回内容 =====
错误状态码: 400
错误响应体: {name: '宠物名称不能为空', age: '宠物年龄不能为负数'}
核心总结
responseentity 的核心价值是「完全掌控 http 响应」,记住这几个关键用法:
- 快捷方法:
ok()(200)、created()(201)、nocontent()(204)、notfound()(404)—— 日常开发优先用,代码更简洁; - 自定义响应:
status(状态码)+header(键, 值)+body(响应体)—— 满足特殊业务需求; - 响应体灵活:可以是实体类、map、字符串,甚至 void(204 场景);
- 结合异常处理:统一返回规范的错误响应,提升接口友好性。
所有案例都能直接复制到项目中运行,用 apipost 测试时只需注意端口和请求参数,就能快速验证效果。掌握这些用法后,你的 spring boot 接口会更符合 rest 规范,也能应对各种复杂的响应需求。
responseentity 的诞生与演进
responseentity 并非 spring boot 专属特性,而是spring framework 中用于标准化 http 响应的核心类,其诞生和发展完全围绕 spring 对 restful api 支持的演进展开。
1. 首次诞生:spring framework 3.0(2009年)
responseentity 最早出现在 spring framework 3.0 版本(正式发布时间:2009年12月17日),是 spring 为强化 restful api 开发能力而新增的核心类。
诞生背景
- 2000年 roy fielding 提出 rest 架构风格后,2000年代后期 restful api 逐渐成为主流;
- spring 2.x 及更早版本对 http 响应的控制极为繁琐(需手动操作
httpservletresponse设置状态码、响应头,或通过modelandview封装结果),无法优雅适配 rest 规范; - spring 3.0 核心目标之一是「原生支持 restful 开发」,因此引入 responseentity,将 http 响应的状态码、响应头、响应体 封装为统一对象,让开发者无需直接操作底层 servlet api。
2. 关键演进节点(与 spring boot 关联)
spring boot 是基于 spring framework 的封装,其对 responseentity 的支持完全依赖底层 spring 版本:
| 框架版本 | 关键变化 |
|---|---|
| spring framework 3.0 | 首次引入 responseentity,核心能力:封装状态码、响应头、响应体 |
| spring framework 4.1 | 新增大量静态工厂方法(如 ok()、notfound()、nocontent()),简化使用 |
| spring framework 5.x | 适配响应式编程(webflux),新增 responseentity<t> 对响应式类型的支持 |
| spring framework 6.x | 适配 jakarta ee 9+(替代 java ee),包路径从 javax 迁移到 jakarta,但 responseentity 核心逻辑不变 |
| spring boot 3.x | 基于 spring framework 6.x 构建,沿用 responseentity 所有特性,无额外修改 |
3. 核心定位未变
从 2009 年诞生至今,responseentity 的核心设计目标从未改变:
- 脱离底层 servlet api 依赖,以面向对象的方式控制 http 响应;
- 严格遵循 http 规范,支持所有标准状态码(2xx/4xx/5xx)和自定义响应头;
- 保持灵活性,响应体可适配任意类型(实体类、map、字符串等)。
总结
- 「诞生时间」:2009年(spring framework 3.0);
- 「归属」:spring framework 的
spring-web模块(非 spring boot 独创); - 「spring boot 角色」:仅做集成和简化(如自动配置、无需手动注册 bean),未改变 responseentity 的核心实现。
你在 spring boot 3 中使用的 responseentity,本质是 spring framework 6.x 版本的实现,相比 2009 年的初代版本,只是增加了更便捷的静态方法和对 jakarta ee 的适配,核心能力和设计初衷完全一致。
到此这篇关于springboot3 responseentity 完全使用案例的文章就介绍到这了,更多相关springboot responseentity使用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论