基于本文回答
0
评论

@Controller与@RestController区别

知识点图片

@RestController@Controller@ResponseBody 的组合注解。它专门用于构建返回 JSON/XML 数据的 RESTful API。而 @Controller 主要用于传统 MVC 应用,默认返回视图(如 HTML 页面)。

这是一个非常核心且常见的 Spring MVC 问题。我们来详细解释一下 @Controller@RestController 的区别。

一、核心总结(一句话概括)

@RestController 是一个“组合注解”,它等同于 @Controller + @ResponseBody

这意味着,当你在一个类上使用 @RestController 时,该类中所有方法的返回值都会被自动序列化成 JSON(或 XML 等)格式,并直接写入 HTTP 响应体(Response Body)中,而不会被视图解析器处理。


二、详细对比

为了更好地理解,我们从几个方面进行详细对比。

1. @Controller

  • 用途:用于标记一个类是 Spring MVC 的控制器(Controller)。这是构建传统 Web 应用程序的核心注解。
  • 返回值处理:默认情况下,@Controller 中方法的返回值会被 Spring 的视图解析器(ViewResolver)处理。这意味着返回值通常是一个字符串,代表着一个视图的逻辑名称(比如 JSP 文件的路径或者 Thymeleaf 模板的名称)。Spring 会根据这个名称找到对应的视图并进行渲染,最终返回一个完整的 HTML 页面给客户端。
  • 如何返回数据?:如果在使用 @Controller 的情况下,你想让某个方法返回 JSON 或 XML 等数据而不是视图,你需要在该方法上额外添加 @ResponseBody 注解

代码示例 (@Controller)

java
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller // 标记这是一个传统的MVC控制器
public class UserController {

    // 1. 返回一个视图 (HTML页面)
    // 返回值 "user-page" 会被视图解析器解析为 /templates/user-page.html (假设使用Thymeleaf)
    @GetMapping("/user/page")
    public String getUserPage(Model model) {
        model.addAttribute("userName", "Alice");
        return "user-page"; // 返回视图名称
    }

    // 2. 返回JSON数据
    // 需要在方法上显式添加 @ResponseBody 注解
    @GetMapping("/api/user")
    @ResponseBody // 告诉Spring将返回值直接写入响应体,并序列化为JSON
    public User getUserData() {
        return new User(1, "Bob"); // 这个User对象会被Jackson库转换为JSON字符串
    }
}

// 辅助类
class User {
    public int id;
    public String name;
    // 构造函数、Getter/Setter省略
}

2. @RestController

  • 用途:专门为构建 RESTful Web 服务 而设计的注解。它简化了返回数据的过程。
  • 返回值处理@RestController 标记的类中,所有的方法都默认被应用了 @ResponseBody 注解。因此,任何方法的返回值(无论是对象、集合还是基本类型)都会被自动序列化为 JSON 格式并作为 HTTP 响应体返回。
  • 如何返回数据?:你不需要做任何额外的事情,直接返回数据对象即可。

代码示例 (@RestController)

java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController // 标记这是一个RESTful控制器,等同于 @Controller + @ResponseBody
public class UserRestController {

    // 所有方法默认都带有 @ResponseBody 的效果
    @GetMapping("/api/v2/user")
    public User getUserData() {
        // 直接返回对象,Spring会自动将其转换为JSON
        return new User(2, "Charlie");
    }

    @GetMapping("/api/v2/users")
    public List<User> getAllUsers() {
        // 返回集合也会被自动转换为JSON数组
        return List.of(new User(2, "Charlie"), new User(3, "David"));
    }
}

三、对比表格

特性/方面 @Controller @RestController
主要用途 构建传统的Web应用,返回HTML视图(如JSP, Thymeleaf) 构建RESTful API,返回JSON/XML等数据
返回值类型 默认是视图名称(String),由视图解析器处理 默认是数据对象,直接写入HTTP响应体
@ResponseBody 需要在想返回数据的方法上手动添加 自动为类中所有方法应用,无需添加
本质 基础的MVC控制器注解 @Controller + @ResponseBody 的组合注解
典型场景 服务器端渲染(SSR)的Web项目 前后端分离项目(如Vue/React/Angular的后端)、微服务

四、如何选择?

  • 使用 @Controller

    • 当你的项目是传统的Web应用,主要功能是渲染并返回HTML页面。
    • 当一个控制器中既有需要返回页面的方法,也有需要返回JSON数据的方法时(虽然更推荐将API和页面控制器分开)。
  • 使用 @RestController

    • 当你正在构建一个纯粹的后端服务,只负责提供数据接口(API)。
    • 你的项目是前后端分离架构,前端(如Vue, React)通过AJAX请求获取JSON数据。
    • 你在开发微服务,服务之间通过HTTP和JSON进行通信。

简单来说,如果你想返回一个页面,就用 @Controller;如果你想返回JSON或XML数据,就用 @RestController

右滑查看面试常问