SpringBoot統(tǒng)一返回格式的方法詳解
前言
目前很多項(xiàng)目都是前后端分離,前后端會(huì)事先約定好返回格式。那么后端如何做,才能優(yōu)雅的返回統(tǒng)一格式呢,接下來(lái),請(qǐng)大家跟著我,一步步來(lái)實(shí)現(xiàn)。
1. 直接返回結(jié)果
先看一下最基本的例子,直接將結(jié)果原封不動(dòng)返回:
@Data
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown?=?true)
public?class?TestVo?{
????private?static?final?long?serialVersionUID?=?1L;
????@Schema(name?=?"姓名")
????private?String?name;
????@Schema(name?=?"年齡")
????private?Integer?age;
}
@RestController
@RequestMapping(value?=?"/test")
public?class?TestApi?{
????@GetMapping("/simple")
????public?TestVo?simple()?{
????????TestVo?testVo?=?new?TestVo("張三",?30);
????????return?testVo;
????}
}
返回結(jié)果:
{
"name": "張三",
"age": 30
}
2. 約定返回格式
假如已經(jīng)與前端開發(fā)妹子約定好了格式,比如:
{
????"code":?0,
????"msg":?"錯(cuò)誤信息",
????"data":?實(shí)際返回結(jié)果
}
那么我們首先需要編寫一個(gè)封裝結(jié)果類Result。為了方便封裝,在這個(gè)類中增加一個(gè)success方法:
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public?class?Result<T>?implements?Serializable?{
????private?static?final?long?serialVersionUID?=?1L;
????/**
?????*?返回編碼
?????*/
????private?Integer?code;
????/**
?????*?編碼描述
?????*/
????private?String?msg;
????/**
?????*?業(yè)務(wù)數(shù)據(jù)
?????*/
????private?T?data;
????/**
?????*?返回成功結(jié)果對(duì)象
?????*
?????*?@param?data
?????*?@param?<T>
?????*?@return
?????*/
????public?static?<T>?Result<T>?success(T?data)?{
????????Result?result?=?new?Result();
????????result.setCode(0);
????????result.setMsg("success");
????????result.setData(data);
????????return?result;
????}
}
3. 返回統(tǒng)一格式結(jié)果
后臺(tái)接口代碼微調(diào)一下,返回值改為Result,泛型為原返回值的類型:
@RestController
@RequestMapping(value?=?"/test")
public?class?TestApi?{
????@GetMapping("/withResult")
????public?Result<TestVo>?withResult()?{
????????TestVo?testVo?=?new?TestVo("張三",?30);
????????return?Result.success(testVo);
????}
}
返回結(jié)果:
{
"code": 0,
"msg": "success",
"data": {
"name": "張三",
"age": 30
}
}
至此,返回結(jié)果完美符合格式。
但是這樣的代碼并不算簡(jiǎn)潔:每個(gè)接口的返回值都必須是Result<>,并且return的時(shí)候都要用Result.success()方法封裝一下。
那么,有沒有更優(yōu)雅的方法?我們繼續(xù)往下看:
4. 切片封裝統(tǒng)一格式
編寫注解
實(shí)際使用場(chǎng)景中,并不是所有接口都需要統(tǒng)一格式。我們這里使用一個(gè)注解作為開關(guān),按需控制接口返回格式。
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public?@interface?ApiResult?{
????String?value()?default?"";
????int?successCode()?default?0;
????String?successMsg()?default?"success";
????Class<??extends?IResult>?resultClass()?default?Result.class;
}
編寫ControllerAdvice
@ControllerAdvice
public?class?MyResponseBodyAdvice?implements?ResponseBodyAdvice?{
????protected?boolean?isStringConverter(Class?converterType)?{
????????return?converterType.equals(StringHttpMessageConverter.class);
????}
????protected?boolean?isApiResult(MethodParameter?returnType)?{
????????return?returnType.hasMethodAnnotation(ApiResult.class);
????}
????@Override
????public?boolean?supports(MethodParameter?returnType,?Class?converterType)?{
????????return?!isStringConverter(converterType)?&&?isApiResult(returnType);
????}
????@Override
????public?Object?beforeBodyWrite(Object?body,?MethodParameter?returnType,?MediaType?selectedContentType,
????????????????????????????????Class?selectedConverterType,?ServerHttpRequest?request,?ServerHttpResponse?response)?{
????????//關(guān)鍵?????????????????????????
????????return?Result.success(body);
????}
}
這里有一點(diǎn)要注意,這個(gè)advice中supports方法中判斷返回結(jié)果類型必須為非String類型。如果返回結(jié)果為String類型,那么result要轉(zhuǎn)為json字符串后再返回,需要再寫一個(gè)advice。
見證奇跡的時(shí)刻到了
@ApiResult
@GetMapping("/withResultHide")
public?TestVo?withResultHide()?{
????TestVo?testVo?=?new?TestVo("張三",?30);
????return?testVo;
}
這段代碼與最開始一樣,并沒有返回Result,僅僅加上了@ApiResult注解,我們看返回結(jié)果:
{
"code": 0,
"msg": "success",
"data": {
"name": "張三",
"age": 30
}
}
大功告成!
以上只是最精簡(jiǎn)的例子,實(shí)際使用中還結(jié)合了 統(tǒng)一異常封裝、自定義返回格式 等功能。我們注意到@ApiResult注解中,有三個(gè)參數(shù):successCode、successMsg、resultClass,就是為了自定義返回格式預(yù)留的,下面再看兩個(gè)場(chǎng)景:
5. 自定義返回格式
場(chǎng)景1:返回成功時(shí)code為200
如果個(gè)別接口的返回格式與默認(rèn)格式相同,但是要求code等于200時(shí)才代表成功,那么修改下successCode參數(shù)即可:
@ApiResult(successCode?=?200,?successMsg?=?"ok")
@GetMapping("/withResultHide")
public?TestVo?withResultHide()?{
????TestVo?testVo?=?new?TestVo("張三",?30);
????return?testVo;
}
返回成功時(shí),結(jié)果中的code和msg都變?yōu)樵O(shè)置的值:
{
"code": 200,
"msg": "ok",
"data": {
"name": "張三",
"age": 30
}
}
場(chǎng)景2:自定義返回格式
如果某個(gè)接口的返回格式不是默認(rèn)的返回格式,比如約定返回returnCode、returnDesc、data(對(duì)應(yīng)默認(rèn)的code、msg、data)。那么則需要新增一個(gè)返回結(jié)果類,比如ReturnResult:
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public?class?ReturnResult<T>?implements?Serializable?{
????private?static?final?long?serialVersionUID?=?1L;
????/**
?????*?返回編碼
?????*/
????private?String?returnCode;
????/**
?????*?編碼描述
?????*/
????private?String?returnDesc;
????/**
?????*?業(yè)務(wù)數(shù)據(jù)
?????*/
????private?T?data;
????/**
?????*?返回成功結(jié)果對(duì)象
?????*
?????*?@param?data
?????*?@param?<T>
?????*?@return
?????*/
????public?static?<T>?ReturnResult<T>?success(T?data)?{
????????ReturnResult?result?=?new?ReturnResult();
????????result.setReturnCode(0);
????????result.setReturnDesc("success");
????????result.setData(data);
????????return?result;
????}
}
然后修改接口上的@ApiResult注解中的resultClass屬性
@ApiResult(resultClass?=?ReturnResult.class)
@GetMapping("/withResultHide")
public?TestVo?withResultHide()?{
????TestVo?testVo?=?new?TestVo("張三",?30);
????return?testVo;
}
這時(shí),返回結(jié)果就變?yōu)橄胍母袷搅耍?/p>
{
"returnCode": "0",
"returnDesc": "success",
"data": {
"name": "張三",
"age": 30
}
}
到此這篇關(guān)于SpringBoot統(tǒng)一返回格式的方法詳解的文章就介紹到這了,更多相關(guān)SpringBoot統(tǒng)一返回格式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用IDEA搭建Hadoop開發(fā)環(huán)境的操作步驟(Window10為例)
經(jīng)過三次重裝,查閱無(wú)數(shù)資料后成功完成hadoop在win10上實(shí)現(xiàn)偽分布式集群,以及IDEA開發(fā)環(huán)境的搭建。一步一步跟著本文操作可以避免無(wú)數(shù)天坑2021-07-07
SpringBoot利用jackson格式化時(shí)間的三種方法
日常開發(fā)過程中經(jīng)常會(huì)使用json進(jìn)行數(shù)據(jù)的傳輸,這就涉及到了對(duì)象和json的相互轉(zhuǎn)化,常用的解決方案有:Jackson(推薦)、谷歌的Gson、阿里的Fastjson,這篇文章主要給大家介紹了關(guān)于SpringBoot如何利用jackson格式化時(shí)間的相關(guān)資料,需要的朋友可以參考下2021-06-06
SpringMVC視圖轉(zhuǎn)發(fā)重定向區(qū)別及控制器詳解
這篇文章主要為大家介紹了SpringMVC視圖轉(zhuǎn)發(fā)重定向區(qū)別及控制器示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
SpringBoot根據(jù)目錄結(jié)構(gòu)自動(dòng)配置Url前綴方式
這篇文章主要介紹了SpringBoot根據(jù)目錄結(jié)構(gòu)自動(dòng)配置Url前綴方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
Java Flyway與Liquibase在ORM項(xiàng)目中的應(yīng)用方式
這篇文章主要介紹了Java Flyway與Liquibase在ORM項(xiàng)目中的應(yīng)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-05-05
springboot+vue實(shí)現(xiàn)登錄功能的最新方法整理
最近做項(xiàng)目時(shí)使用到了springboot+vue實(shí)現(xiàn)登錄功能的技術(shù),所以下面這篇文章主要給大家介紹了關(guān)于springboot+vue實(shí)現(xiàn)登錄功能的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06

