来吧,比较下注解@RestController与@Controller,消磨下时间

232 阅读4分钟

心灵鸡汤

世界很大,每个人很渺小,但每个人都是独一无二的。

上班不是在为老板工作,而是在为自己的未来积累能力。

前因

最近,闲来无事,就东瞅瞅西看看,也没发现什么。无意中翻了翻项目,看到项目中使用注解 @RestController,是用来做处理请求的,好多项目都使用这个了。最在我想关闭项目的时候,在一个角落中发现有一个项目中使用了@Controller。话说@RestController@Controller升级版,心想着还是有区别的,特此来整理分析下,希望大家多多指教!

核心比较

在 Spring框架中,@Controller 和 @RestController 是用于标识控制器组件的核心注解,二者均用于处理 HTTP 请求,但在响应数据的处理方式上存在本质区别。下面从功能、使用场景、代码示例和执行流程等方面详细解析。

一、核心功能与本质区别

  1. @Controller:传统 MVC 控制器
    是 Spring 最早提供的控制器注解,主要用于传统 MVC 架构,负责接收请求、处理业务逻辑后返回视图(如 JSP、Thymeleaf 页面)。若需返回 JSON 等数据,需配合 @ResponseBody 注解使用。
  2. @RestController:RESTful API 控制器
    是 Spring 4.0 新增的注解,本质是 @Controller 与 @ResponseBody 的组合注解(@RestController = @Controller + @ResponseBody),专门用于前后端分离的 RESTful API 开发,默认将所有方法的返回值转换为 JSON/XML 等响应体,无需额外添加 @ResponseBody

二、代码示例对比

1. @Controller 的使用

适用于返回视图的场景,如需返回数据需添加 @ResponseBody

@Controller
@RequestMapping("/mvc")
public class MvcController {

    // 1. 返回视图(无需@ResponseBody)
    @GetMapping("/page")
    public String showPage(Model model) {
        model.addAttribute("message", "Hello, MVC!");
        return "index"; // 跳转到index.html视图
    }

    // 2. 返回JSON数据(需添加@ResponseBody)
    @GetMapping("/data")
    @ResponseBody
    public Map<String, String> returnData() {
        Map<String, String> data = new HashMap<>();
        data.put("name", "Spring MVC");
        return data; // 返回{"name":"Spring MVC"}
    }
}

2. @RestController 的使用

适用于返回数据的场景,默认所有方法均返回响应体。

@RestController
@RequestMapping("/api")
public class RestApiController {

    // 1. 直接返回JSON(无需@ResponseBody)
    @GetMapping("/user")
    public User getUser() {
        User user = new User();
        user.setId(1);
        user.setName("Alice");
        return user; // 返回{"id":1,"name":"Alice"}
    }

    // 2. 处理POST请求并返回结果
    @PostMapping("/submit")
    public Result submit(@RequestBody User user) {
        return new Result(200, "提交成功", user);
    }

    // 静态内部类:用户实体
    static class User {
        private Integer id;
        private String name;
        // getter/setter省略
    }

    // 静态内部类:统一响应格式
    static class Result {
        private int code;
        private String message;
        private Object data;
        // 构造方法、getter/setter省略
    }
}

三、执行流程对比

1. @Controller 执行流程

客户端请求 → DispatcherServlet → @Controller方法 → 
  ├─ 无@ResponseBody → 视图解析器 → 渲染视图(如HTML)→ 响应客户端
  └─ 有@ResponseBody → 消息转换器 → 转换为JSON/XML → 响应客户端

2. @RestController 执行流程

客户端请求 → DispatcherServlet → @RestController方法 → 
  消息转换器(默认生效)→ 转换为JSON/XML → 响应客户端

关键差异@RestController 省略了手动添加 @ResponseBody 的步骤,且无法直接返回视图(若强制返回字符串,会被当作响应体而非视图名称)。

四、适用场景分析

注解适用场景响应类型典型应用
@Controller传统 MVC 开发(前后端不分离)视图(HTML)或数据企业管理系统、CMS 内容管理系统
@RestControllerRESTful API 开发(前后端分离)数据(JSON/XML)移动应用后端、小程序接口、微服务

五、流程图:请求处理路径对比

┌───────────────┐     ┌──────────────────────────────────────┐
│   客户端      │     │             Spring 容器               │
│  (浏览器/App)│     │                                      │
└───────┬───────┘     ├───────────────┬──────────────────────┘
        │             │               │
        ▼             ▼               ▼
┌───────────────┐  ┌──────────┐  ┌───────────────┐
│ HTTP 请求     │  │@Controller│  │@RestController│
└───────┬───────┘  └────┬─────┘  └───────┬───────┘
        │               │                │
        │               │  方法无@ResponseBody
        │               ├───────────────►┐
        │               │                │
        │               │  视图解析器    │  消息转换器
        │               │  生成HTML      │  生成JSON/XML
        │               │                │
        └───────────────┼────────────────┘
                        │
                        ▼
                ┌───────────────┐
                │  响应客户端   │
                └───────────────┘

六、常见问题与注意事项

  1. @RestController 能否返回视图?
    不能。@RestController 内置 @ResponseBody,所有方法返回值都会被转换为响应体。若需返回视图,需改用 @Controller
  2. @Controller 如何同时支持视图和数据?
    可在同一个 @Controller 中混合使用:无 @ResponseBody 的方法返回视图,有 @ResponseBody 的方法返回数据。
  3. 响应格式转换原理
    二者均依赖 Spring 的 HttpMessageConverter 进行数据转换(如 Jackson 处理 JSON),@RestController 只是默认启用了这一功能。

总结

@Controller 和 @RestController 都是 Spring 处理请求的核心控制器注解,核心区别在于响应处理方式:

  • @Controller 适用于传统 MVC 架构,需配合 @ResponseBody 才能返回数据;
  • @RestController 适用于前后端分离的 API 开发,默认返回 JSON 等数据,简化了 RESTful 接口开发。

建议,在实际开发中,应根据项目架构、项目场景选择合适的注解。主要还是一点,根据需求来选择合适的注解,主要是自己喜欢就好,哈哈!

祝愿

祝愿看到这篇文章的掘友们:

愿你被岁月温柔以待,也被自己好好珍惜。未来的每一天,都比昨天更幸福、更充实、更美好。

愿你一路前行,一路成长;所遇皆温柔,所行皆坦途,日子越过越顺,生活越来越好。