问题复现

今天在用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”的经典坑!

希望这篇文章能帮到你,也欢迎点赞、收藏、转发给更多正在踩坑的朋友!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐