SpringBoot3實現(xiàn)統(tǒng)一結(jié)果封裝的示例代碼
前置條件
已經(jīng)初始化好一個spring boot項目且版本為3X,項目可正常啟動。
作者版本為3.2.2
初始化教程:
新版idea(2023)創(chuàng)建spring boot3項目
封裝目的
Spring Boot進(jìn)行統(tǒng)一結(jié)果封裝的主要目的是提高開發(fā)效率、降低代碼重復(fù)率,并且提供一致的API響應(yīng)格式,從而簡化前后端交互和錯誤處理
具體好處如下:
- 方便前端處理:前端可以統(tǒng)一根據(jù)返回格式進(jìn)行處理,而不用關(guān)注具體的返回類型和內(nèi)容。
- 提高 API 的可讀性和可維護(hù)性:統(tǒng)一結(jié)果封裝可以使 API 的返回更加規(guī)范化,統(tǒng)一了 API 返回結(jié)果的格式,使得代碼更加易于閱讀和維護(hù)。
- 增加系統(tǒng)的健壯性:通過統(tǒng)一結(jié)果封裝,能夠更好地處理錯誤和異常情況,從而增加系統(tǒng)的健壯性和穩(wěn)定性。
- 統(tǒng)一日志輸出:通過統(tǒng)一結(jié)果封裝,可以方便地記錄請求參數(shù)、請求結(jié)果、異常信息等,方便后續(xù)的日志分析和排查問題。
常用格式
最常用的格式為狀態(tài)碼、提示信息、攜帶數(shù)據(jù)如圖
具體格式還要看團(tuán)隊,這里我就使用這種通用的格式。
定義返回結(jié)果枚舉類
通過使用這樣的枚舉類有助于避免硬編碼的狀態(tài)碼和消息,提高了代碼的可維護(hù)性。
import lombok.Getter; /** * @author mijiupro */ @Getter public enum ResultEnum { /* 成功狀態(tài)碼 */ SUCCESS(1, "操作成功!"), /* 錯誤狀態(tài)碼 */ FAIL(0, "操作失??!"), /* 參數(shù)錯誤:10001-19999 */ PARAM_IS_INVALID(10001, "參數(shù)無效"), PARAM_IS_BLANK(10002, "參數(shù)為空"), PARAM_TYPE_BIND_ERROR(10003, "參數(shù)格式錯誤"), PARAM_NOT_COMPLETE(10004, "參數(shù)缺失"), /* 用戶錯誤:20001-29999*/ USER_NOT_LOGGED_IN(20001, "用戶未登錄,請先登錄"), USER_LOGIN_ERROR(20002, "賬號不存在或密碼錯誤"), USER_ACCOUNT_FORBIDDEN(20003, "賬號已被禁用"), USER_NOT_EXIST(20004, "用戶不存在"), USER_HAS_EXISTED(20005, "用戶已存在"), /* 系統(tǒng)錯誤:40001-49999 */ FILE_MAX_SIZE_OVERFLOW(40003, "上傳尺寸過大"), FILE_ACCEPT_NOT_SUPPORT(40004, "上傳文件格式不支持"), /* 數(shù)據(jù)錯誤:50001-599999 */ RESULT_DATA_NONE(50001, "數(shù)據(jù)未找到"), DATA_IS_WRONG(50002, "數(shù)據(jù)有誤"), DATA_ALREADY_EXISTED(50003, "數(shù)據(jù)已存在"), AUTH_CODE_ERROR(50004, "驗證碼錯誤"), /* 權(quán)限錯誤:70001-79999 */ PERMISSION_UNAUTHENTICATED(70001, "此操作需要登陸系統(tǒng)!"), PERMISSION_UNAUTHORIZED(70002, "權(quán)限不足,無權(quán)操作!"), PERMISSION_EXPIRE(70003, "登錄狀態(tài)過期!"), PERMISSION_TOKEN_EXPIRED(70004, "token已過期"), PERMISSION_LIMIT(70005, "訪問次數(shù)受限制"), PERMISSION_TOKEN_INVALID(70006, "無效token"), PERMISSION_SIGNATURE_ERROR(70007, "簽名失敗"); // 狀態(tài)碼 int code; // 提示信息 String message; ResultEnum(int code, String message) { this.code = code; this.message = message; } public int code() { return code; } public String message() { return message; } public void setCode(int code) { this.code = code; } public void setMessage(String message) { this.message = message; } }
定義返回結(jié)果封裝類
import com.mijiu.commom.enumerate.ResultEnum; import lombok.Data; /** * @author mijiupro */ @Data public class Result<T> { // 操作代碼 Integer code; // 提示信息 String message; // 結(jié)果數(shù)據(jù) T data; public Result(ResultEnum resultCode) { this.code = resultCode.code(); this.message = resultCode.message(); } public Result(ResultEnum resultCode, T data) { this.code = resultCode.code(); this.message = resultCode.message(); this.data = data; } public Result(String message) { this.message = message; } //成功返回封裝-無數(shù)據(jù) public static Result<String> success() { return new Result<String>(ResultEnum.SUCCESS); } //成功返回封裝-帶數(shù)據(jù) public static <T> Result<T> success(T data) { return new Result<T>(ResultEnum.SUCCESS, data); } //失敗返回封裝-使用默認(rèn)提示信息 public static Result<String> error() { return new Result<String>(ResultEnum.FAIL); } //失敗返回封裝-使用返回結(jié)果枚舉提示信息 public static Result<String> error(ResultEnum resultCode) { return new Result<String>(resultCode); } //失敗返回封裝-使用自定義提示信息 public static Result<String> error(String message) { return new Result<String>(message); } }
對返回結(jié)果封裝
此時我們就可以使用封裝類封裝統(tǒng)一格式的響應(yīng)了
import com.mijiu.common.result.Result; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author mijiupro */ @RestController @RequestMapping("/test1") public class Test1Controller { @GetMapping("/hello") public Result<String> hello() { return Result.success("hello world"); } }
我們的接口通常有很多,如果對每個接口都封裝屬于重復(fù)勞動,可以利用AOP技術(shù)攔截控制類的返回結(jié)果進(jìn)行封裝。
代碼如下
import cn.hutool.json.JSONUtil; import com.mijiu.commom.result.Result; import io.micrometer.common.lang.NonNullApi; import io.micrometer.common.lang.Nullable; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; /** * 統(tǒng)一結(jié)果封裝增強(qiáng)器 * @author mijiupro */ @RestControllerAdvice(basePackages = "com.mijiu.controller")//指定要增強(qiáng)的包 @NonNullApi public class ResultAdvice implements ResponseBodyAdvice<Object> { /** * 判斷是否支持對返回類型的處理 * * @param returnType 方法參數(shù)的類型 * @param converterType 轉(zhuǎn)換器的類型 * @return 是否支持處理 */ @Override public boolean supports(MethodParameter returnType, Class converterType) { return true; } /** * 在寫入響應(yīng)體之前對返回結(jié)果進(jìn)行處理和封裝 * * @param body 返回結(jié)果對象 * @param returnType 方法參數(shù)的類型 * @param selectedContentType 響應(yīng)內(nèi)容的類型 * @param selectedConverterType 轉(zhuǎn)換器的類型 * @param request HTTP 請求對象 * @param response HTTP 響應(yīng)對象 * @return 處理后的返回結(jié)果 */ @Override public Object beforeBodyWrite(@Nullable Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { //當(dāng)返回結(jié)果為字符串類型需要單獨處理 if (body instanceof String) { // 如果返回結(jié)果是字符串類型,將其封裝為成功的結(jié)果對象,并轉(zhuǎn)換為 JSON 字符串 return JSONUtil.toJsonStr(Result.success(body)); } // 將返回結(jié)果封裝為成功的結(jié)果對象 return Result.success(body); } }
此代碼可以兼容任何類型的返回結(jié)果對其進(jìn)行統(tǒng)一封裝。
為何遇到方法的返回結(jié)果是String類型需要手動轉(zhuǎn)成json返回呢?
測試封裝
現(xiàn)在com.mijiu.controller下的所有控制類的所有方法都會被攔截將返回結(jié)果進(jìn)行統(tǒng)一格式封裝。
到這里返回結(jié)果統(tǒng)一封裝結(jié)束。
以上就是SpringBoot3實現(xiàn)統(tǒng)一結(jié)果封裝的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot3統(tǒng)一結(jié)果封裝的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
spring boot利用docker構(gòu)建gradle項目的實現(xiàn)步驟
這篇文章主要給大家介紹了關(guān)于spring boot利用docker構(gòu)建gradle項目的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05Java開發(fā)者結(jié)合Node.js編程入門教程
這篇文章主要介紹了Java開發(fā)者結(jié)合Node.js編程入門教程,我將先向您展示如何使用Java EE創(chuàng)建一個簡單的Rest服務(wù)來讀取 MongoDB數(shù)據(jù)庫。然后我會用node.js來實現(xiàn)相同的功能,需要的朋友可以參考下2014-09-09SpringBoot自定義轉(zhuǎn)換器應(yīng)用實例講解
SpringBoot在響應(yīng)客戶端請求時,將提交的數(shù)據(jù)封裝成對象時,使用了內(nèi)置的轉(zhuǎn)換器,SpringBoot 也支持自定義轉(zhuǎn)換器,這個內(nèi)置轉(zhuǎn)換器在 debug的時候,可以看到,提供了124個內(nèi)置轉(zhuǎn)換器2022-08-08Java匿名內(nèi)部類導(dǎo)致內(nèi)存泄露的原因與解決方案詳解
這篇文章主要為大家詳細(xì)介紹了Java因為匿名內(nèi)部類導(dǎo)致內(nèi)存泄露的原因以及其解決方案,文中的示例代碼講解詳細(xì),希望對大家有所幫助2022-11-11SpringBoot整合Ehcache3的實現(xiàn)步驟
本文主要介紹了SpringBoot整合Ehcache3的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01SpringMVC?HttpMessageConverter報文信息轉(zhuǎn)換器
這篇文章主要為大家介紹了SpringMVC?HttpMessageConverter報文信息轉(zhuǎn)換器,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05