💡 一则也许对你有用的小广告 🏆

欢迎飞飞程序员   ,你将获得:专属的实战项目(已更新的所有会员标识的项目都能学习) / 1v1 提问 / Java 学习路线 / PHP 学习路线 / 学习打卡 / 社群讨论

  • 正在进行中的项目:《FFBlog知识付费博客项目》 正在持续更新中,基于 Spring Boot 3.x + JDK 21...,点击查看 ;
  • 《从零开发:FFBlog知识付费博客项目(全栈开发)》 演示链接: https://ffblog.ffcxy.com/  ;

截止目前, 飞飞  正在疯狂爆肝实战项目,后续还会上新更多项目,目标是将所学知识开发成项目并且分享给大家,如知识付费系统, Ai系统, CMS系统,在线商城系统,等等 ,欢迎点击围观

摘要
详解 SpringBoot 中 @ResponseBody 注解的作用与 @RestController 的关系,以及它和 @RequestBody、统一响应类的配合,帮你搞懂返回值如何被转成 JSON 写入响应体,还有常见的踩坑点和底层 HttpMessageConverter 转换原理。

一句话:@ResponseBody 告诉 Spring:"这个方法的返回值不要当成页面名去跳转,而是直接转成数据(JSON/XML)写进 HTTP 响应体返回给前端。"

它是 Spring MVC 里非常核心的一个注解,理解它对搞懂前后端分离项目至关重要。


一、先理解"没有它"会发生什么

Spring MVC 默认遵循"返回字符串 = 视图名"的规则。

场景:不加 @ResponseBody

@Controller
public class UserController {

    @GetMapping("/hello")
    public String hello() {
        return "hello";   // Spring 认为你要跳转到 hello.html / hello.jsp
    }
}

Spring 拿到 "hello",会去找一个叫 hello 的视图(页面),然后渲染返回 HTML。

👉 返回值被当成了"页面名字"。

场景:加上 @ResponseBody

@Controller
public class UserController {

    @GetMapping("/hello")
    @ResponseBody
    public String hello() {
        return "hello";   // 直接把 "hello" 这个字符串写进响应体
    }
}

浏览器收到的是纯文本 hello,不是页面跳转。

👉 返回值被当成了"要返回的数据"。


二、两种模式的对比

不加 @ResponseBody 加 @ResponseBody
返回值含义 视图名(页面) 响应数据
处理方式 找视图渲染 HTML 转成 JSON/XML 写入响应体
典型返回 "index" → 跳转 index.html User 对象 → {"id":1,...}
适用场景 传统服务端渲染(JSP/Thymeleaf) 前后端分离(REST API)

三、@ResponseBody 到底做了什么?

它触发 Spring 的 HttpMessageConverter(消息转换器) 机制:

方法返回 User 对象
       ↓
@ResponseBody 拦截
       ↓
HttpMessageConverter 把 User 转成 JSON
       ↓
写入 HTTP 响应体
       ↓
前端收到 { "id": 1, "name": "张三" }

关键点:对象 → JSON 的转换就是靠它完成的(底层通常用 Jackson)。


四、@RestController = @Controller + @ResponseBody

写 REST API 时,如果每个方法都加 @ResponseBody 太啰嗦,Spring 提供了组合注解:

// 这两个写法完全等价
@Controller
@ResponseBody
public class UserController { ... }

// 等价于
@RestController
public class UserController { ... }

@RestController 源码本质就是:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Controller
@ResponseBody   // ← 内置了这个
public @interface RestController {
}

所以在前后端分离项目里,Controller 上写 @RestController,方法上就不用再加 @ResponseBody 了。


五、和你之前那个 Response 类的关系

还记得你写的统一响应封装吗?它俩配合起来是这样工作的:

@RestController   // ← 相当于每个方法都加了 @ResponseBody
@RequestMapping("/user")
public class UserController {

    @GetMapping("/{id}")
    public Response<User> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        return Response.success(user);   // 返回 Response 对象
    }
}

执行流程:

1. 方法返回 Response<User> 对象
        ↓
2. @RestController(含 @ResponseBody)生效
        ↓
3. HttpMessageConverter 把 Response 对象转成 JSON
        ↓
4. 写入 HTTP 响应体
        ↓
前端收到:
{
  "code": 200,
  "data": { "id": 1, "name": "张三" },
  "message": "请求成功",
  "success": true
}

👉 Response 负责"包装数据",@ResponseBody 负责"把包装好的对象转成 JSON 发出去"。两者各司其职。


六、常见搭配的注解

注解 作用 方向
@ResponseBody 返回值 → 响应体(出) 后端 → 前端
@RequestBody 请求体 → 方法参数(入) 前端 → 后端
@RequestParam URL 查询参数 → 方法参数 前端 → 后端
@PathVariable URL 路径变量 → 方法参数 前端 → 后端

一个完整例子:

@RestController
public class UserController {

    @PostMapping("/user")
    public Response<User> create(@RequestBody User user) {  
        // @RequestBody:把前端传来的 JSON 转成 User 对象
        User saved = userService.save(user);
        return Response.success(saved);
        // @RestController 隐含 @ResponseBody:把 Response 转成 JSON 返回
    }
}
  • @RequestBody:进来的 JSON → Java 对象
  • @ResponseBody:出去的 Java 对象 → JSON

一进一出,刚好配一对。


七、底层原理(了解即可)

Spring 判断返回值怎么处理,靠的是 RequestResponseBodyMethodProcessor:

  1. 检查方法/类上有没有 @ResponseBody
  2. 有 → 遍历所有 HttpMessageConverter,找到能处理该返回类型的转换器
  3. 用 MappingJackson2HttpMessageConverter(Jackson)把对象转成 JSON
  4. 写入 HttpServletResponse 的输出流

常见的 HttpMessageConverter:

转换器 处理类型
MappingJackson2HttpMessageConverter JSON(最常用)
StringHttpMessageConverter String
ByteArrayHttpMessageConverter byte[]
Jaxb2RootElementHttpMessageConverter XML

八、容易踩的坑

坑1:忘了加 @ResponseBody,返回对象被当成视图名

@Controller
public class UserController {
    @GetMapping("/user")
    public User getUser() {
        return new User();   // ❌ 报错:找不到名为 User 的视图
    }
}

解决:加 @ResponseBody 或改用 @RestController。

坑2:@Controller + 返回 String 想返回 JSON 字符串

@Controller
public class C {
    @GetMapping("/msg")
    @ResponseBody
    public String msg() {
        return "{\"name\":\"张三\"}";  // 返回的是字符串,不是对象
    }
}

如果想返回对象自动转 JSON,返回类型应该是 User 而不是 String。


九、总结

问题 答案
@ResponseBody 是什么? 让方法返回值直接写入响应体(转 JSON)
不加会怎样? 返回值被当成视图名,去找页面跳转
和 @RestController 关系? @RestController = @Controller + @ResponseBody
底层靠什么转换? HttpMessageConverter(通常是 Jackson)
和 @RequestBody 区别? 一个管"出"(响应),一个管"入"(请求)
和你写的 Response 类关系? Response 包装数据,@ResponseBody 把包装好的对象转成 JSON

一句话记住:

@ResponseBody 就是"把 Java 对象变成 JSON 发出去"的开关;@RestController 是它的懒人版,一次性给整个类都打开。

在前后端分离项目里,你几乎每个 Controller 都会用到它(或直接用 @RestController)。

上一篇 SpringBoot框架@RestController 注解用法详解
已是最后一篇

全部评论(0)

头像
😃 😁 😅 😂 😍 😜 😝 🤑 🥵 🥰 😙 😎 😵 😭 😱 😖 🥳 👽 🙈 🤡 😤 💣 💯 💢 ❤️ 👍 👏 👋 👌 🤏 🙏
还没有任何评论哟~
微信扫一扫
微信二维码
微信客服
QQ 咨询
QQ二维码
工作日 9:00 - 18:00 在线
QQ客服
在线工单
提交问题工单,我们会尽快回复处理。
提交工单
在线工单