在 Spring 框架中,@RestController 和 @Controller 是用于定义控制器组件的两个注解,它们的核心区别在于 响应体的处理方式。以下是详细对比:
一、核心区别
| 注解 | @Controller | @RestController |
|---|---|---|
| 响应体处理 | 需要配合 @ResponseBody 返回 JSON/XML | 直接返回 JSON/XML(默认) |
| 视图解析 | 支持视图解析(如返回 HTML 页面) | 不支持视图解析,直接返回数据 |
| 典型应用场景 | MVC 架构中的页面控制器 | RESTful API 服务 |
| 出现版本 | Spring MVC | Spring 4.0 引入 |
二、代码示例对比
1. @Controller + @ResponseBody
@Controller
public class UserController {
@GetMapping("/users/{id}")
@ResponseBody // 必须添加该注解才能返回 JSON
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
@GetMapping("/home")
public String home(Model model) {
model.addAttribute("message", "Hello World");
return "home"; // 返回视图名称,由视图解析器处理
}
}
2. @RestController
@RestController // 等价于 @Controller + @ResponseBody
public class UserRestController {
@GetMapping("/api/users/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id); // 直接返回对象,自动序列化为 JSON
}
@GetMapping("/api/message")
public String getMessage() {
return "This is a REST API"; // 返回字符串,而非视图名称
}
}
三、技术细节对比
| 特性 | @Controller | @RestController |
|---|---|---|
| 注解本质 | 是 @Component 的派生注解 | 是 @Controller 和 @ResponseBody 的组合注解 |
| 返回值处理 | – 返回 String:视图名称– 返回对象:需 @ResponseBody | – 返回 String:字符串内容– 返回对象:自动 JSON 序列化 |
| 视图解析 | 依赖 ViewResolver 解析视图 | 忽略视图解析,直接返回数据 |
| 响应格式 | 需手动配置 produces 属性或消息转换器 | 默认 JSON,可通过 produces 覆盖 |
四、常见应用场景
1. @Controller 的适用场景
- 传统 MVC 应用,需要返回 HTML 页面。
- 服务端渲染(如 Thymeleaf、JSP)。
- 需要复杂视图逻辑的场景。
2. @RestController 的适用场景
- RESTful API 开发。
- 前后端分离架构。
- 微服务间通信(如返回 JSON/XML 数据)。
五、关键注意事项
避免混用
- 在
@RestController中使用@ResponseBody是多余的。 - 在
@Controller中不使用@ResponseBody会导致返回视图解析错误。
响应格式定制
- 通过
produces属性指定响应类型:
@GetMapping(path = "/data", produces = MediaType.APPLICATION_XML_VALUE)
public User getData() { ... }
兼容性
@RestController是 Spring 4.0 引入的,若使用旧版本 Spring,需用@Controller + @ResponseBody。
六、总结
- 选
@RestController:如果你的控制器是用于提供 REST API,返回 JSON/XML 等数据。 - 选
@Controller:如果需要返回视图(如 HTML 页面),或需要混合使用视图和 JSON 响应