返回json & 通用返回值設(shè)計(jì) | SpringMVC系列第8篇
大家好,我是【路人甲 Java】號(hào)主路人,本文如果對(duì)你有幫助,點(diǎn)個(gè)在看,順便忙轉(zhuǎn)發(fā)一下,非常需要大家的支持,對(duì) java 有興趣的朋友歡迎加我微信 itsoku 交流。
目前比較流行前后端分離,后端只需為前端提供 restfull 接口,所有的接口都返回 json 格式的數(shù)據(jù),前端接收到 json 數(shù)據(jù)之后再進(jìn)行處理。
那么在 SpringMVC 中如何向前端輸出 json 格式的數(shù)據(jù)呢?
常見(jiàn)的有 3 種方式,我們來(lái)了解下。
1、方式 1:方法上添加@ResponseBody
需求
使用 springmvc 提供一個(gè)接口,以 json 格式輸出用戶列表。
3 個(gè)步驟
step1:maven 配置引入 jackjson
jackjson 用于將 java 對(duì)象轉(zhuǎn)換為 json 格式的字符串,也可以將 json 格式的字符串轉(zhuǎn)換為 java 對(duì)象
我們的接口需要將 java 對(duì)象轉(zhuǎn)換為 json 格式的字符串輸出到客戶端,所以我們需要用到這個(gè)包。
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.11.4version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.11.4version>
dependency>
step2:springmvc 配置文件中添加注解驅(qū)動(dòng)
<mvc:annotation-driven/>
添加了這段代碼之后,springmvc 就被賦予了將 java 對(duì)象轉(zhuǎn)換為 json 格式字符串輸出到客戶端的能力。
step3:處理器的方法上添加@ResponseBody 注解
如下代碼,我們希望 list()方法用于向客戶端以 json 格式輸出用戶列表。
此時(shí)只需要在這個(gè)方法上面添加一個(gè)
@ResponseBody注解,SpringMVC 發(fā)現(xiàn)這個(gè)方法上有@ResponseBody這個(gè)注解,并且方法返回值是一個(gè)普通的 java 對(duì)象的時(shí)候,會(huì)將方法的返回值使用 jackson 轉(zhuǎn)換為 json 格式的字符串,然后輸出到客戶端。
@Controller
public class UserController {
/**
* 用戶列表(用戶id->用戶信息)
*/
Map userDtoMap = new ConcurrentHashMap<>();
{
userDtoMap.put(1L, new UserDto(1L, "路人", 30));
userDtoMap.put(2L, new UserDto(2L, "張三", 20));
userDtoMap.put(3L, new UserDto(3L, "李四", 18));
}
@GetMapping("/user/list.do")
@ResponseBody
public Collection list() {
return this.userDtoMap.values();
}
}
驗(yàn)證效果
谷歌瀏覽器中訪問(wèn)下這個(gè)接口

F12 看一下接口的響應(yīng)頭,如下,可以看到 response 的Content-Type的值為application/json;chatset=UTF-8,這個(gè)說(shuō)明響應(yīng)結(jié)果的內(nèi)容格式是 json 格式。

2、方式 2:Controller 上添加@ResponseBody 注解
當(dāng)我們 controller 中方法很多的時(shí)候,且所有方法都要求返回 json 格式的數(shù)據(jù)的時(shí)候,如果按照方式 1,我們需要在每個(gè)方法上都要添加@ResponseBody注解,此時(shí)有更簡(jiǎn)單的方法,將所有方法上的@ResponseBody注解都去掉,然后在 Controller 上加上@ResponseBody就可以了。
比如下面這段代碼,我們可以將 2 個(gè)方法上面的@ResponseBody干掉,然后在類上添加@ResponseBody注解就可以了。
@Controller
public class UserController {
Map userDtoMap = new ConcurrentHashMap<>();
{
userDtoMap.put(1L, new UserDto(1L, "路人", 30));
userDtoMap.put(2L, new UserDto(2L, "張三", 20));
userDtoMap.put(3L, new UserDto(3L, "李四", 18));
}
@GetMapping("/user/list.do")
@ResponseBody
public Collection list() {
return this.userDtoMap.values();
}
@GetMapping("/user/{id}.do")
@ResponseBody
public UserDto user(@PathVariable("id") Long id) {
return this.userDtoMap.get(id);
}
}
調(diào)整之后如下
@Controller
@ResponseBody
public class UserController {
Map userDtoMap = new ConcurrentHashMap<>();
{
userDtoMap.put(1L, new UserDto(1L, "路人", 30));
userDtoMap.put(2L, new UserDto(2L, "張三", 20));
userDtoMap.put(3L, new UserDto(3L, "李四", 18));
}
@GetMapping("/user/list.do")
public Collection list() {
return this.userDtoMap.values();
}
@GetMapping("/user/{id}.do")
public UserDto user(@PathVariable("id") Long id) {
return this.userDtoMap.get(id);
}
}
3、方式 3:Controllers 上使用@RestController
我們回頭再看下上面代碼,如下圖,UserController 上有 2 個(gè)注解@Controller和@ResponseBody,而 SpringMVC 提供了一個(gè)更好的注解@RestController,相當(dāng)于這 2 個(gè)注解的合體,所以可以用來(lái)替換這 2 個(gè)注解。



4、restfull 接口通用返回值
客戶端調(diào)用服務(wù)器端接口的時(shí)候,接口有可能會(huì)發(fā)生異常,這些異常信息需要返回給調(diào)用者,通常我們會(huì)為錯(cuò)誤定義錯(cuò)誤碼以及提示信息。
一般我們會(huì)定義通用的返回值類型,格式如下:
/**
* rest接口通用返回值數(shù)據(jù)結(jié)構(gòu)
* @param
*/
public class ResultDto<T> {
//接口狀態(tài)(成功還是失?。?/span>
private Boolean success;
//錯(cuò)誤碼
private String code;
//提示信息
private String msg;
//數(shù)據(jù)
private T data;
public static ResultDto success(T data) {
return success(data, "操作成功!");
}
public static ResultDto success(T data, String msg) {
ResultDto result = new ResultDto<>();
result.setSuccess(Boolean.TRUE);
result.setMsg(msg);
result.setData(data);
return result;
}
//省略get、set方法
}
控制器中所有的方法都返回 ResultDto 類型的結(jié)果,如下代碼
@RestController
public class UserController {
Map userDtoMap = new ConcurrentHashMap<>();
{
userDtoMap.put(1L, new UserDto(1L, "路人", 30));
userDtoMap.put(2L, new UserDto(2L, "張三", 20));
userDtoMap.put(3L, new UserDto(3L, "李四", 18));
}
@GetMapping("/user/list.do")
public ResultDto<collection > list() {
return ResultDto.success(this.userDtoMap.values());
}
@GetMapping("/user/{id}.do")
public ResultDto user(@PathVariable("id") Long id) {
return ResultDto.success(this.userDtoMap.get(id));
}
}
</collection 5、案例代碼
git地址:https://gitee.com/javacode2018/springmvc-series

6、總結(jié)
掌握@ResponseBody 的用法,用來(lái)返回 json 格式的數(shù)據(jù),注意需要在 springmvc 配置文件中添加注解驅(qū)動(dòng)的配置,否則調(diào)用會(huì)報(bào)錯(cuò)
<mvc:annotation-driven/>掌握通用接口返回值的用法
7、SpringMVC 系列
SpringMVC 系列第 1 篇:helloword SpringMVC 系列第 2 篇:@Controller、@RequestMapping SpringMVC 系列第 3 篇:異常高效的一款接口測(cè)試?yán)?/a> SpringMVC 系列第 4 篇:controller 常見(jiàn)的接收參數(shù)的方式 SpringMVC 系列第 5 篇:@RequestBody 大解密,說(shuō)點(diǎn)你不知道的 SpringMVC 系列第 6 篇:上傳文件的 4 種方式,你都會(huì)么?
8、更多好文章
Spring 高手系列(共 56 篇) Java 高并發(fā)系列(共 34 篇) MySql 高手系列(共 27 篇) Maven 高手系列(共 10 篇) Mybatis 系列(共 12 篇) 聊聊 db 和緩存一致性常見(jiàn)的實(shí)現(xiàn)方式 接口冪等性這么重要,它是什么?怎么實(shí)現(xiàn)? 泛型,有點(diǎn)難度,會(huì)讓很多人懵逼,那是因?yàn)槟銢](méi)有看這篇文章!
9、推薦一個(gè)高質(zhì)量的公眾號(hào)
大家平時(shí)在學(xué)習(xí)技術(shù)的過(guò)程中,苦于找不到高質(zhì)量的學(xué)習(xí)資料的,可以關(guān)注一下【Java 充電社】,這個(gè)號(hào)專注于為大家提供高質(zhì)量的學(xué)習(xí)資源,已發(fā)布了大量高質(zhì)量的學(xué)習(xí)視頻、及資源,大家可以關(guān)注下。
