SpringBoot統(tǒng)一返回結(jié)果問題
目前很多項(xiàng)目都是前后端分離,前后端會(huì)事先約定好返回格式,前端如果使用axios的話,會(huì)在全局過濾器里進(jìn)行校驗(yàn),那么后端如何做,才能優(yōu)雅的返回固定的統(tǒng)一格式呢,接下來我會(huì)帶著你一步步實(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. 約定返回格式
假如與前端開發(fā)妹子約定好了格式,比如:
{
"code": 0,
"msg": "錯(cuò)誤信息",
"data": 實(shí)際返回結(jié)果
}那么我們首先需要編寫一個(gè)封裝結(jié)果類Result,為了方便封裝,我們?cè)偬峁┮粋€(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é)果完美符合格式,但是每個(gè)接口的返回值都是Result<>,并且return的時(shí)候都要用success方法封裝一下,不夠優(yōu)雅,怎么辦?我們繼續(xù)看:
4. 切片封裝統(tǒng)一格式
編寫注解
實(shí)際使用場(chǎng)景中,并不是所有接口都能完美的統(tǒng)一格式,使用注解可以按需控制接口返回格式。
@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
@Order(0)
@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;
}這段代碼與直接返回結(jié)果的一樣,僅僅加上了@ApiResult注解,我們看返回結(jié)果:
{
"code": 0,
"msg": "success",
"data": {
"name": "張三",
"age": 30
}
}大功告成!
以上只是最精簡(jiǎn)的例子,實(shí)際使用中還結(jié)合了 統(tǒng)一異常封裝、自定義返回格式 等功能。
我們注意到@ApiResult注解中,有三個(gè)參數(shù):successCode、successMsg、resultClass,就是為了自定義返回格式預(yù)留的,
下面看個(gè)例子:
5. 自定義返回格式
返回成功時(shí)code為200
如果個(gè)別接口的返回格式與默認(rèn)格式相同,但是要求code等于200代表成功,那么修改下successCode參數(shù)即可:
@ApiResult(successCode = 200, successMsg = "ok")
@GetMapping("/withResultHide")
public TestVo withResultHide() {
TestVo testVo = new TestVo("張三", 30);
return testVo;
}我們發(fā)現(xiàn),返回成功時(shí),結(jié)果中的code和msg都變?yōu)樵O(shè)置的值:
{
"code": 200,
"msg": "ok",
"data": {
"name": "張三",
"age": 30
}
}自定義返回格式
如果個(gè)別的接口返回格式不是默認(rèn)的返回格式,那么我們需要新增一個(gè)返回結(jié)果類,比如ReturnResult,里面包含returnCode、returnDesc、data三個(gè)屬性:
@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
}
}注意:以上自定義返回結(jié)果的例子需要自行根據(jù)實(shí)際情況添加,文章中的例子并不能實(shí)現(xiàn)
總結(jié)
只要按照上面一步步改造,即可實(shí)現(xiàn)統(tǒng)一返回結(jié)果,既規(guī)范、又優(yōu)雅,也可根據(jù)自己所需添加對(duì)應(yīng)的屬性和數(shù)據(jù)。還等什么,搞起來吧~
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- SpringBoot統(tǒng)一數(shù)據(jù)返回格式的實(shí)現(xiàn)示例
- SpringBoot如何統(tǒng)一處理返回結(jié)果和異常情況
- 詳解SpringBoot中的統(tǒng)一結(jié)果返回與統(tǒng)一異常處理
- Springboot設(shè)置統(tǒng)一的返回格式的方法步驟
- SpringBoot返回結(jié)果統(tǒng)一處理實(shí)例詳解
- 淺析SpringBoot統(tǒng)一返回結(jié)果的實(shí)現(xiàn)
- SpringBoot全局處理統(tǒng)一返回類型方式
- 詳解SpringBoot如何統(tǒng)一處理返回的信息
- SpringBoot統(tǒng)一返回格式的方法詳解
- SpringBoot統(tǒng)一數(shù)據(jù)返回的幾種方式
相關(guān)文章
Java編程利用socket多線程訪問服務(wù)器文件代碼示例
這篇文章主要介紹了Java編程利用socket多線程訪問服務(wù)器文件代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-10-10
SpringMVC實(shí)現(xiàn)自定義類型轉(zhuǎn)換器
本篇文章主要介紹了SpringMVC實(shí)現(xiàn)自定義類型轉(zhuǎn)換器 ,詳細(xì)的介紹了自定義類型轉(zhuǎn)換器的用法和好處,有興趣的可以了解一下。2017-04-04
java實(shí)現(xiàn)遍歷樹形菜單兩種實(shí)現(xiàn)代碼分享
這篇文章主要介紹了java實(shí)現(xiàn)遍歷樹形菜單兩種實(shí)現(xiàn)代碼分享,兩種實(shí)現(xiàn):OpenSessionView實(shí)現(xiàn)、TreeAction實(shí)現(xiàn)。具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11
Java結(jié)構(gòu)型設(shè)計(jì)模式之享元模式示例詳解
享元模式(FlyWeight?Pattern),也叫蠅量模式,運(yùn)用共享技術(shù),有效的支持大量細(xì)粒度的對(duì)象,享元模式就是池技術(shù)的重要實(shí)現(xiàn)方式。本文將通過示例詳細(xì)講解享元模式,感興趣的可以了解一下2022-09-09
Java 程序設(shè)計(jì)總復(fù)習(xí)題(java基礎(chǔ)代碼)
這篇文章主要介紹了Java 程序設(shè)計(jì)總復(fù)習(xí)題,主要是java基礎(chǔ)代碼,方便學(xué)習(xí)java的同學(xué)2021-05-05

