Spring MVC 返回 JSON 视图的方式及对比(新增 MappingJackson2JsonView
)
1. 方式一:@ResponseBody
注解
作用:直接返回对象,由消息转换器(如 Jackson)序列化为 JSON。
适用场景:简单返回对象,无需自定义 HTTP 状态码或头信息。
代码示例:
@Controller public class UserController { @GetMapping("/user/json") @ResponseBody public User getUser() { return new User("John", 30); // 自动序列化为 JSON } }
依赖:需引入 Jackson 库(Spring Boot 默认已集成)。
特点:
- 简单直接,但需显式标注
@ResponseBody
。 - 无法直接控制 HTTP 状态码或头信息。
- 简单直接,但需显式标注
2. 方式二:@RestController
注解
作用:组合
@Controller
和@ResponseBody
,所有方法默认返回 JSON。适用场景:RESTful API 控制器,所有方法均返回 JSON。
代码示例:
@RestController public class UserController { @GetMapping("/user/json") public User getUser() { return new User("John", 30); // 无需 @ResponseBody } }
依赖:同
@ResponseBody
。特点:
- 简化配置,类级别标注即可。
- 所有方法默认返回 JSON,适合 REST API。
3. 方式三:ResponseEntity
对象
作用:返回包装对象,可自定义 HTTP 状态码、头信息和响应体。
适用场景:需要返回特定状态码(如 404、201)或自定义头信息。
代码示例:
@RestController public class UserController { @GetMapping("/user/json") public ResponseEntity<User> getUser() { User user = new User("John", 30); return ResponseEntity .status(HttpStatus.CREATED) .header("X-Custom-Header", "value") .body(user); } }
依赖:无需额外依赖。
特点:
- 灵活性高,可控制状态码、头和响应体。
- 适合复杂响应场景。
4. 方式四:@JsonView
控制序列化字段
作用:通过注解控制对象序列化的字段,避免暴露敏感数据。
适用场景:需要根据场景选择性序列化字段(如不同 API 版本)。
代码示例:
// 定义视图类 class Views { static class Public {} static class Internal extends Public {} } @RestController public class UserController { @JsonView(Views.Public.class) @GetMapping("/user/json/public") public User getPublicUser() { return new User("John", 30); // 只序列化 @JsonView(Views.Public) 的字段 } @JsonView(Views.Internal.class) @GetMapping("/user/json/internal") public User getInternalUser() { return new User("John", 30); // 序列化 Public 和 Internal 的字段 } } // User 类字段配置 public class User { @JsonView(Views.Public.class) private String name; @JsonView(Views.Internal.class) private int age; // ... }
依赖:Jackson 的
@JsonView
注解。特点:
- 精细控制序列化字段。
- 适合不同接口暴露不同数据。
5. 方式五:@RequestBody
反序列化 + @ResponseBody
序列化
作用:处理 POST/PUT 请求的 JSON 反序列化,同时返回 JSON。
适用场景:需要双向 JSON 交互(如 REST API)。
代码示例:
@RestController public class UserController { @PostMapping("/user/save") public User saveUser(@RequestBody User user) { // 反序列化 JSON 请求体到 User 对象 return user; // 序列化为 JSON 响应 } }
依赖:Jackson。
特点:
- 支持请求体反序列化和响应体序列化。
- 适合 RESTful CRUD 操作。
6. 新增方式六:MappingJackson2JsonView
作用:通过视图解析器将模型数据转换为 JSON 格式的视图。
适用场景:需要兼容旧代码或特定视图配置(如传统基于视图的 MVC 流程)。
代码示例:
@Controller public class UserController { @GetMapping("/user/json") public String getUser(Model model) { User user = new User("John", 30); model.addAttribute("user", user); // 将数据存入模型 return "jsonView"; // 视图名称 } }
视图配置:
@Configuration public class WebConfig implements WebMvcConfigurer { @Bean public View jsonView() { MappingJackson2JsonView view = new MappingJackson2JsonView(); view.setExtractValueFromSingleKeyModel(true); // 自动提取模型中的值 return view; } @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.enableContentNegotiation(); // 启用内容协商 registry.viewResolver((s, locale) -> jsonView()); } }
依赖:需引入
org.springframework:spring-webmvc
和 Jackson。特点:
- 传统视图方式:依赖视图解析器和模型数据,流程与 JSP 等视图一致。
- 配置复杂:需手动配置视图和视图解析器。
- 灵活性低:无法直接控制 HTTP 状态码或头信息。
- 适用场景:在需要与传统视图(如 JSP)共存时使用。
对比表格(新增 MappingJackson2JsonView
)
方式 | 适用场景 | 控制能力 | 代码复杂度 | 依赖 | 是否需要视图解析器 |
---|---|---|---|---|---|
@ResponseBody |
简单返回对象 | 仅返回数据,无状态/头控制 | 低 | Jackson | 否 |
@RestController |
REST API 控制器 | 同 @ResponseBody ,简化配置 |
低 | Jackson | 否 |
ResponseEntity |
需要自定义状态码/头信息 | 状态码、头、数据全控制 | 中 | 无额外依赖 | 否 |
@JsonView |
需要控制序列化字段 | 粒度控制字段序列化 | 高 | Jackson 的 @JsonView |
否 |
@RequestBody + @ResponseBody |
双向 JSON 交互(如 POST/PUT) | 反序列化请求体,序列化响应体 | 中 | Jackson | 否 |
MappingJackson2JsonView |
兼容旧代码或特定视图配置 | 仅序列化模型数据,无状态/头控制 | 高 | Spring MVC + Jackson | 是 |
关键差异总结(新增 MappingJackson2JsonView
)
控制粒度:
ResponseEntity
提供最高控制(状态码、头、数据)。@JsonView
用于字段级序列化控制。MappingJackson2JsonView
仅能序列化模型数据,无法控制状态码或头。
代码简洁性:
@RestController
和@ResponseBody
更简洁。MappingJackson2JsonView
需要额外配置视图和解析器,代码复杂度较高。
适用场景:
MappingJackson2JsonView
:适合需要与传统视图(如 JSP)共存的场景,或在旧代码中逐步迁移时使用。- 其他方式(如
@RestController
)更推荐用于现代 RESTful API 开发。
依赖与配置:
MappingJackson2JsonView
需要显式配置视图和视图解析器,而其他方式依赖注解和消息转换器。
注意事项
MappingJackson2JsonView
的局限性:- 需要通过模型传递数据,无法直接返回对象。
- 无法直接设置 HTTP 状态码或头信息,需通过
@ResponseStatus
或HandlerInterceptor
间接实现。
- 推荐场景:
- 在需要与传统视图(如 JSP)共存的项目中,
MappingJackson2JsonView
可作为过渡方案。 - 现代项目中更推荐使用
@RestController
和ResponseEntity
,因其简洁性和灵活性。
- 在需要与传统视图(如 JSP)共存的项目中,
通过新增 MappingJackson2JsonView
的对比,可以更全面地理解 Spring MVC 返回 JSON 的多种方式及其适用场景。