为什么 Spring Boot 中用 @Controller 返回 JSON 会 404?正确使用 @RestController 的姿势
问题复现
今天在用Swagger进行测试的时候发现我明明写了接口但是还是显示404,在DeBug的时候发现发送的HTTP请求已经被Controller接收了但是还是显示的404,然后才发现了注解写错了。
假设你有如下控制器代码:
@Controller // 注意这里是 @Controller
public class ContactController {
@Resource
private ContactService contactService;
@PostMapping("/user/addContact")
public Result addContact(@RequestBody Contact contact) {
log.info("添加联系人");
contactService.addContact(contact);
return Result.success(); // 返回一个自定义的 Result 对象
}
}
当你用 Apifox 或前端调用 /user/addContact 接口时,返回 404 Not Found!
但只要把 @Controller 换成 @RestController,立马恢复正常,返回 JSON 数据:
{
"code": 200,
"msg": "success",
"data": null
}
这是为什么?

🔍 根本原因:Spring 对返回值的处理逻辑不同
✅ @RestController = @Controller + @ResponseBody
-
@RestController是一个组合注解,它的内部实现相当于:@Controller @ResponseBody public @interface RestController { ... } -
@ResponseBody的作用是:告诉 Spring MVC,不要把返回值当作视图名(View Name)去解析页面,而是直接写入 HTTP 响应体(Response Body),通常以 JSON 或 XML 形式返回。
❌ 而 @Controller 默认行为是“返回视图”
当你只用 @Controller 时:
- Spring 会认为你的方法是要跳转到某个页面;
- 它会把
return Result.success()的结果(比如Result(code=200, msg="success", data=null))当作字符串视图名; - 然后尝试去找
templates/Result@xxxx.html或类似名称的模板文件; - 但你的项目是纯 API 服务,根本没有这些页面;
- 最终:找不到视图 → 返回 404!
💡 即使你返回的是一个对象,Spring 也会调用它的
toString()当作视图名,而不是序列化为 JSON!
✅ 正确解决方案
方案一:使用 @RestController(推荐!)
如果你开发的是 前后端分离的 API 接口(返回 JSON),请始终使用 @RestController:
@RestController
public class ContactController {
@PostMapping("/user/addContact")
public Result addContact(@RequestBody Contact contact) {
contactService.addContact(contact);
return Result.success();
}
}
✅ 简洁、清晰、符合 RESTful 规范。

方案二:保留 @Controller,但加 @ResponseBody
如果你出于某些原因必须用 @Controller(比如混合页面和 API),那么每个返回数据的方法都要加 @ResponseBody:
@Controller
public class ContactController {
@PostMapping("/user/addContact")
@ResponseBody // ← 关键!
public Result addContact(@RequestBody Contact contact) {
contactService.addContact(contact);
return Result.success();
}
}
⚠️ 注意:
@ResponseBody必须加在方法上,否则无效。
📌 使用场景总结
| 场景 | 推荐注解 | 说明 |
|---|---|---|
| 开发 RESTful API(返回 JSON/XML) | ✅ @RestController | 所有方法自动返回数据 |
| 开发传统 Web 应用(返回 HTML 页面) | ✅ @Controller | 配合 Thymeleaf/JSP 渲染页面 |
| 混合项目(既有页面又有 API) | @Controller + 方法级 @ResponseBody | 灵活但需小心管理 |
✅ 结语
@Controller 和 @RestController 虽然只差一个字,但用途截然不同:
做 API,用
@RestController;做页面,用@Controller。
理解这一点,就能避免“为什么我的接口 404”的经典坑!
希望这篇文章能帮到你,也欢迎点赞、收藏、转发给更多正在踩坑的朋友!
更多推荐



所有评论(0)