Spring MVC 返回 JSON 視圖的方式及對比(新增 MappingJackson2JsonView
)
1. 方式一:@ResponseBody
注解
-
作用:直接返回對象,由消息轉換器(如 Jackson)序列化為 JSON。
-
適用場景:簡單返回對象,無需自定義 HTTP 狀態碼或頭信息。
-
代碼示例:
@Controller public class UserController {@GetMapping("/user/json")@ResponseBodypublic 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 {@Beanpublic View jsonView() {MappingJackson2JsonView view = new MappingJackson2JsonView();view.setExtractValueFromSingleKeyModel(true); // 自動提取模型中的值return view;}@Overridepublic 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 的多種方式及其適用場景。