SpringBoot統一返回格式的方法詳解
前言
目前很多項目都是前後端分離,前後端會事先約定好返回格式。那麼後端如何做,才能優雅的返回統一格式呢,接下來,請大傢跟著我,一步步來實現。
1. 直接返回結果
先看一下最基本的例子,直接將結果原封不動返回:
@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; } }
返回結果:
{
"name": "張三",
"age": 30
}
2. 約定返回格式
假如已經與前端開發妹子約定好瞭格式,比如:
{ "code": 0, "msg": "錯誤信息", "data": 實際返回結果 }
那麼我們首先需要編寫一個封裝結果類Result。為瞭方便封裝,在這個類中增加一個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; /** * 業務數據 */ private T data; /** * 返回成功結果對象 * * @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. 返回統一格式結果
後臺接口代碼微調一下,返回值改為Result,泛型為原返回值的類型:
@RestController @RequestMapping(value = "/test") public class TestApi { @GetMapping("/withResult") public Result<TestVo> withResult() { TestVo testVo = new TestVo("張三", 30); return Result.success(testVo); } }
返回結果:
{
"code": 0,
"msg": "success",
"data": {
"name": "張三",
"age": 30
}
}
至此,返回結果完美符合格式。
但是這樣的代碼並不算簡潔:每個接口的返回值都必須是Result<>,並且return的時候都要用Result.success()方法封裝一下。
那麼,有沒有更優雅的方法?我們繼續往下看:
4. 切片封裝統一格式
編寫註解
實際使用場景中,並不是所有接口都需要統一格式。我們這裡使用一個註解作為開關,按需控制接口返回格式。
@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) { //關鍵 return Result.success(body); } }
這裡有一點要註意,這個advice中supports方法中判斷返回結果類型必須為非String類型。如果返回結果為String類型,那麼result要轉為json字符串後再返回,需要再寫一個advice。
見證奇跡的時刻到瞭
@ApiResult @GetMapping("/withResultHide") public TestVo withResultHide() { TestVo testVo = new TestVo("張三", 30); return testVo; }
這段代碼與最開始一樣,並沒有返回Result,僅僅加上瞭@ApiResult註解,我們看返回結果:
{
"code": 0,
"msg": "success",
"data": {
"name": "張三",
"age": 30
}
}
大功告成!
以上隻是最精簡的例子,實際使用中還結合瞭 統一異常封裝、自定義返回格式 等功能。我們註意到@ApiResult註解中,有三個參數:successCode、successMsg、resultClass,就是為瞭自定義返回格式預留的,下面再看兩個場景:
5. 自定義返回格式
場景1:返回成功時code為200
如果個別接口的返回格式與默認格式相同,但是要求code等於200時才代表成功,那麼修改下successCode參數即可:
@ApiResult(successCode = 200, successMsg = "ok") @GetMapping("/withResultHide") public TestVo withResultHide() { TestVo testVo = new TestVo("張三", 30); return testVo; }
返回成功時,結果中的code和msg都變為設置的值:
{
"code": 200,
"msg": "ok",
"data": {
"name": "張三",
"age": 30
}
}
場景2:自定義返回格式
如果某個接口的返回格式不是默認的返回格式,比如約定返回returnCode、returnDesc、data(對應默認的code、msg、data)。那麼則需要新增一個返回結果類,比如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; /** * 業務數據 */ private T data; /** * 返回成功結果對象 * * @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; }
這時,返回結果就變為想要的格式瞭:
{
"returnCode": "0",
"returnDesc": "success",
"data": {
"name": "張三",
"age": 30
}
}
到此這篇關於SpringBoot統一返回格式的方法詳解的文章就介紹到這瞭,更多相關SpringBoot統一返回格式內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- SpringBoot返回統一的JSON標準格式實現步驟
- ResponseBodyAdvice踩坑及解決
- SpringBoot 統一公共返回類的實現
- SpringBoot實現統一封裝返回前端結果集的示例代碼
- SpringBoot中controller深層詳細講解