欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于springboot的接口返回值統(tǒng)一標(biāo)準(zhǔn)格式

 更新時(shí)間:2022年05月05日 16:57:09   作者:shenhuxi10000  
這篇文章主要介紹了關(guān)于springboot的接口返回值統(tǒng)一標(biāo)準(zhǔn)格式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

response統(tǒng)一格式

一、目標(biāo)

  • 弄清楚為什么要對(duì)springboot,所有Controller的response做統(tǒng)一格式封裝?
  • 學(xué)會(huì)用ResponseBodyAdvice接口 和 @ControllerAdvice注解

二、為什么要對(duì)springboot的接口返回值統(tǒng)一標(biāo)準(zhǔn)格式?

我們先來看下,springboot默認(rèn)情況下的response是什么格式的

第一種格式:response為String

@GetMapping(value="/getStr")
public String ?getStr( ?){
? ? return ?"test";
}

以上springboot的返回值為

  • test

第二種格式:response為Objct

@GetMapping(value="/getObject")
public UserVO ?getObject( ?){
? ? UserVO vo=new UserVO();
? ? vo.setUsername("agan");
? ? return ?vo;
}

以上springboot的返回值為

{
? "id": null,
? "username": "agan",
? "password": null,
? "email": null,
? "phone": null,
? "idCard": null,
? "sex": null,
? "deleted": null,
? "updateTime": null,
? "createTime": null
}

第三種格式:response為void

@GetMapping(value="/empty")
public void ?empty( ?){
}

以上springboot的返回值為空

第四種格式:response為異常

@GetMapping(value="/error")
public void ?error( ?){
? ? int i=9/0;
}

以上springboot的返回值為空

{
? "timestamp": "2019-09-07T10:35:56.658+0000",
? "status": 500,
? "error": "Internal Server Error",
? "message": "/ by zero",
? "path": "/user/error"
}?

以上4種,情況,如果你和客戶端(app h5)開發(fā)人聯(lián)調(diào)接口,他們會(huì)很懵逼,因?yàn)槟憬o他們的接口沒有一個(gè)統(tǒng)一的格式,客戶端開發(fā)人員,不知道如何處理返回值。

故,我們應(yīng)該統(tǒng)一response的標(biāo)準(zhǔn)格式。

三、定義response的標(biāo)準(zhǔn)格式

一般的response的標(biāo)準(zhǔn)格式包含3部分:

1.status狀態(tài)值:代表本次請(qǐng)求response的狀態(tài)結(jié)果。

2.response描述:對(duì)本次狀態(tài)碼的描述。

3.data數(shù)據(jù):本次返回的數(shù)據(jù)。

{
? ?"status":0,
? ?"desc":"成功",
? ?"data":"test"
}

四、初級(jí)程序員對(duì)response代碼封裝

對(duì)response的統(tǒng)一封裝,是有一定的技術(shù)含量的,我們先來看下,初級(jí)程序員的封裝,網(wǎng)上很多教程都是這么寫的。

步驟1:把標(biāo)準(zhǔn)格式轉(zhuǎn)換為代碼

{
? ?"status":0,
? ?"desc":"成功",
? ?"data":"test"
}

把以上格式轉(zhuǎn)換為Result代碼

@AllArgsConstructor
@NoArgsConstructor
@Data
public class Result<T> {
? ? /**
? ? ?* 1.status狀態(tài)值:代表本次請(qǐng)求response的狀態(tài)結(jié)果。
? ? ?*/
? ? private Integer status;
? ? /**
? ? ?* 2.response描述:對(duì)本次狀態(tài)碼的描述。
? ? ?*/
? ? private String desc;
? ? /**
? ? ?* 3.data數(shù)據(jù):本次返回的數(shù)據(jù)。
? ? ?*/
? ? private T data;
? ? /**
? ? ?* 成功,創(chuàng)建ResResult:沒data數(shù)據(jù)
? ? ?*/
? ? public static Result suc() {
? ? ? ? Result result = new Result();
? ? ? ? result.setResultCode(ResultCode.SUCCESS);
? ? ? ? return result;
? ? }
? ? /**
? ? ?* 成功,創(chuàng)建ResResult:有data數(shù)據(jù)
? ? ?*/
? ? public static Result suc(Object data) {
? ? ? ? Result result = new Result();
? ? ? ? result.setResultCode(ResultCode.SUCCESS);
? ? ? ? result.setData(data);
? ? ? ? return result;
? ? }
? ? /**
? ? ?* 失敗,指定status、desc
? ? ?*/
? ? public static Result fail(Integer status, String desc) {
? ? ? ? Result result = new Result();
? ? ? ? result.setStatus(status);
? ? ? ? result.setDesc(desc);
? ? ? ? return result;
? ? }
? ? /**
? ? ?* 失敗,指定ResultCode枚舉
? ? ?*/
? ? public static Result fail(ResultCode resultCode) {
? ? ? ? Result result = new Result();
? ? ? ? result.setResultCode(resultCode);
? ? ? ? return result;
? ? }
? ? /**
? ? ?* 把ResultCode枚舉轉(zhuǎn)換為ResResult
? ? ?*/
? ? private void setResultCode(ResultCode code) {
? ? ? ? this.status = code.code();
? ? ? ? this.desc = code.message();
? ? }
}

步驟2:把狀態(tài)碼存在枚舉類里面

public enum ResultCode ?{
?? ?/* 成功狀態(tài)碼 */
?? ?SUCCESS(0, "成功"),
?? ?/* 系統(tǒng)500錯(cuò)誤*/
?? ?SYSTEM_ERROR(10000, "系統(tǒng)異常,請(qǐng)稍后重試"),
?? ?UNAUTHORIZED(10401, "簽名驗(yàn)證失敗"),
?? ?/* 參數(shù)錯(cuò)誤:10001-19999 */
?? ?PARAM_IS_INVALID(10001, "參數(shù)無效"),
?? ?/* 用戶錯(cuò)誤:20001-29999*/
?? ?USER_HAS_EXISTED(20001, "用戶名已存在"),
?? ?USER_NOT_FIND(20002, "用戶名不存在");
?? ?private Integer code;
?? ?private String message;
?? ?ResultCode(Integer code, String message) {
?? ??? ?this.code = code;
?? ??? ?this.message = message;
?? ?}
?? ?public Integer code() {
?? ??? ?return this.code;
?? ?}
?? ?public String message() {
?? ??? ?return this.message;
?? ?}
}

步驟3:加一個(gè)體驗(yàn)類

@Api(description = "用戶接口")
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
? ? @GetMapping(value="/getResult")
? ? public Result getResult( ?){
? ? ? ? return Result.suc("test");
? ? }
}

結(jié)論:看到這里,應(yīng)該有很多同學(xué)都知道這樣封裝代碼有很大弊端。

因?yàn)榻窈竽忝繉懸粋€(gè)接口,都要手工指定Result.suc()這行代碼,多累?。??

如果你寫這種代碼推廣給你整個(gè)公司用,然后硬性規(guī)定代碼必須這么寫??!所有程序都會(huì)吐槽鄙視!?。?!

五、高級(jí)程序員對(duì)response代碼封裝

如果你在公司推廣你的編碼規(guī)范,為了避免被公司其他程序員吐槽和鄙視,我們必須優(yōu)化代碼。

優(yōu)化的目標(biāo):不要每個(gè)接口都手工指定Result返回值。

步驟1:采用ResponseBodyAdvice技術(shù)來實(shí)現(xiàn)response的統(tǒng)一格式

springboot提供了ResponseBodyAdvice來幫我們處理

ResponseBodyAdvice的作用:攔截Controller方法的返回值,統(tǒng)一處理返回值/響應(yīng)體,一般用來做response的統(tǒng)一格式、加解密、簽名等等。

先看下ResponseBodyAdvice這個(gè)接口的源碼。

public interface ResponseBodyAdvice<T> {
? ? /**
? ? ?* 是否支持advice功能
? ? ?* treu=支持,false=不支持
? ? ?*/
? ? boolean supports(MethodParameter var1, Class<? extends HttpMessageConverter<?>> var2);
? ? /**
? ? ?*
? ? ?* 處理response的具體業(yè)務(wù)方法
? ? ?*/
? ? @Nullable
? ? T beforeBodyWrite(@Nullable T var1, MethodParameter var2, MediaType var3, Class<? extends HttpMessageConverter<?>> var4, ServerHttpRequest var5, ServerHttpResponse var6);
}

步驟2:寫一個(gè)ResponseBodyAdvice實(shí)現(xiàn)類

@ControllerAdvice(basePackages = "com.agan.boot")
public class ResponseHandler implements ResponseBodyAdvice<Object> {
? ? /**
? ? ?* 是否支持advice功能
? ? ?* treu=支持,false=不支持
? ? ?*/
? ? @Override
? ? public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
? ? ? ? return true;
? ? }
? ? /**
? ? ?*
? ? ?* 處理response的具體業(yè)務(wù)方法
? ? ?*/
? ? @Override
? ? public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
? ? ? ? if (o instanceof String) {
? ? ? ? ? ? return JsonUtil.object2Json(Result.suc(o));
? ? ? ? }
? ? ? ? return Result.suc(o);
? ? }
}

以上代碼,有2個(gè)地方需要重點(diǎn)講解:

第1個(gè)地方:@ControllerAdvice 注解

@ControllerAdvice這是一個(gè)非常有用的注解,它的作用是增強(qiáng)Controller的擴(kuò)展功能類。

那@ControllerAdvice對(duì)Controller增強(qiáng)了哪些擴(kuò)展功能呢?主要體現(xiàn)在2方面:

  • 對(duì)Controller全局?jǐn)?shù)據(jù)統(tǒng)一處理,例如,我們這節(jié)課就是對(duì)response統(tǒng)一封裝。
  • 對(duì)Controller全局異常統(tǒng)一處理,這個(gè)后面的課程會(huì)詳細(xì)講解。

在使用@ControllerAdvice時(shí),還要特別注意,加上basePackages,

@ControllerAdvice(basePackages = “com.agan.boot”)

因?yàn)槿绻患拥脑?,它可是?duì)整個(gè)系統(tǒng)的Controller做了擴(kuò)展功能,

它會(huì)對(duì)某些特殊功能產(chǎn)生沖突,例如 不加的話,在使用swagger時(shí)會(huì)出現(xiàn)空白頁異常。

第2個(gè)地方:beforeBodyWrite方法體的response類型判斷

if (o instanceof String) {
? ? ? ? ? ? return JsonUtil.object2Json(ResResult.suc(o));
}

以上代碼一定要加,因?yàn)镃ontroller的返回值為String的時(shí)候,它是直接返回String,不是json,

故我們要手工做下json轉(zhuǎn)換處理 

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • JAVA判斷空值方法原理解析

    JAVA判斷空值方法原理解析

    這篇文章主要介紹了JAVA判斷空值方法原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • SpringBoot實(shí)現(xiàn)HTTP調(diào)用的七種方式總結(jié)

    SpringBoot實(shí)現(xiàn)HTTP調(diào)用的七種方式總結(jié)

    小編在工作中,遇到一些需要調(diào)用三方接口的任務(wù),就需要用到 HTTP 調(diào)用工具,這里,我總結(jié)了一下 實(shí)現(xiàn) HTTP 調(diào)用的方式,共有 7 種(后續(xù)會(huì)繼續(xù)新增),需要的朋友可以參考下
    2023-09-09
  • Java自旋鎖及自旋的好處詳解

    Java自旋鎖及自旋的好處詳解

    這篇文章主要介紹了Java自旋鎖及自旋的好處詳解,自旋就是自己在這里不停地循環(huán),直到目標(biāo)達(dá)成,而不像普通的鎖那樣,如果獲取不到鎖就進(jìn)入阻塞,需要的朋友可以參考下
    2023-10-10
  • Spring Boot 使用WebAsyncTask異步返回結(jié)果

    Spring Boot 使用WebAsyncTask異步返回結(jié)果

    這篇文章主要介紹了Spring Boot 使用WebAsyncTask異步返回結(jié)果的相關(guān)資料,需要的朋友可以參考下
    2018-02-02
  • java實(shí)現(xiàn)的xml格式化實(shí)現(xiàn)代碼

    java實(shí)現(xiàn)的xml格式化實(shí)現(xiàn)代碼

    這篇文章主要介紹了java實(shí)現(xiàn)的xml格式化實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2016-11-11
  • JDBC連接Mysql的5種方式實(shí)例總結(jié)

    JDBC連接Mysql的5種方式實(shí)例總結(jié)

    JDBC是Java DataBase Connectivity技術(shù)的簡稱,是一種可用于執(zhí)行 SQL語句的Java API,下面這篇文章主要給大家介紹了關(guān)于JDBC連接Mysql的5種方式,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • 通過JDK源碼學(xué)習(xí)InputStream詳解

    通過JDK源碼學(xué)習(xí)InputStream詳解

    InputStream抽象類是所有字節(jié)輸入流的類的超類。這篇文章主要給大家介紹了關(guān)于通過JDK源碼學(xué)習(xí)InputStream的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • Zookeeper?Curator使用介紹

    Zookeeper?Curator使用介紹

    curator是Net?ix公司開源的?套Zookeeper客戶端框架,和ZKClient?樣,Curator解決了很多Zookeeper客戶端非常底層的細(xì)節(jié)開發(fā)?作,包括連接重連,反復(fù)注冊(cè)Watcher和NodeExistsException異常等,是最流行的Zookeeper客戶端之?
    2022-09-09
  • java io讀取文件操作代碼實(shí)例

    java io讀取文件操作代碼實(shí)例

    這篇文章主要介紹了java io讀取文件操作代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • java生成圖片驗(yàn)證碼實(shí)例代碼

    java生成圖片驗(yàn)證碼實(shí)例代碼

    這篇文章主要介紹了java生成圖片驗(yàn)證碼實(shí)例代碼,驗(yàn)證碼的種類有很多,問題驗(yàn)證、短信驗(yàn)證還有常見的圖片驗(yàn)證,本文就為大家介紹生成圖片驗(yàn)證碼最簡單方法,感興趣的小伙伴們可以參考一下
    2016-04-04

最新評(píng)論