题目
Spring MVC中@Controller和@RestController的区别及使用场景
信息
- 类型:问答
- 难度:⭐
考点
Spring MVC注解,控制器设计,HTTP响应处理
快速回答
主要区别:
- @Controller:用于传统Web应用,需配合@ResponseBody返回数据
- @RestController:是@Controller+@ResponseBody的组合,直接返回JSON/XML数据
使用场景:
- @Controller:需要返回视图(如JSP/Thymeleaf)的页面渲染场景
- @RestController:构建RESTful API时返回结构化数据
1. 核心区别
@Controller 是Spring MVC的基础注解,标记类作为Web请求处理器。其方法默认返回逻辑视图名,由视图解析器渲染HTML页面。若需返回数据,必须额外添加@ResponseBody注解。
@RestController 是Spring 4.0引入的复合注解,等价于@Controller + @ResponseBody。其方法返回值会自动序列化为JSON/XML并通过HTTP响应体返回。
2. 代码示例
// 传统@Controller示例
@Controller
public class UserController {
// 返回视图名
@GetMapping("/profile")
public String userProfile(Model model) {
model.addAttribute("user", getUser());
return "profile-page"; // 解析为profile-page.html
}
// 返回JSON需显式添加@ResponseBody
@ResponseBody
@GetMapping("/api/user")
public User getUserData() {
return getUser(); // 自动转为JSON
}
}
// @RestController示例
@RestController
public class UserApiController {
// 自动返回JSON
@GetMapping("/api/users")
public List<User> getUsers() {
return userService.findAll(); // 无需@ResponseBody
}
}3. 使用场景对比
| 场景 | @Controller | @RestController |
|---|---|---|
| 返回HTML视图 | ✅ 推荐 | ❌ 不适用 |
| 返回JSON/XML数据 | 需配合@ResponseBody | ✅ 自动处理 |
| RESTful API | 可用但冗余 | ✅ 最佳实践 |
| 混合返回视图和数据 | ✅ 灵活支持 | ❌ 无法返回视图 |
4. 底层原理
Spring通过HandlerMapping定位控制器后:
- @Controller方法返回值由ViewResolver处理
- @RestController方法返回值通过HttpMessageConverter(如Jackson)序列化
5. 常见错误
- 在@Controller中忘记加@ResponseBody导致返回视图名被当作字符串传输
- 在@RestController中尝试返回视图名,结果变成JSON字符串(如返回"success"会输出
"success"而非跳转页面) - 混淆注解导致HTTP 406错误(缺少合适的MessageConverter)
6. 最佳实践
- 前后端分离项目:统一使用@RestController构建API
- 传统服务端渲染:使用@Controller + 视图技术
- 混合架构:可同时使用两类控制器,用URL路径区分(如
/web/和/api/)
7. 扩展知识
- @ResponseBody:可单独用于方法,实现混合控制器内的数据返回
- 内容协商:通过请求头
Accept自动切换JSON/XML等格式 - 替代方案:可直接用
@Controller配合@ResponseBody实现类似@RestController的效果