<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
目前很多專案都是前後端分離,前後端會事先約定好返回格式。那麼後端如何做,才能優雅的返回統一格式呢,接下來,請大家跟著我,一步步來實現。
先看一下最基本的例子,直接將結果原封不動返回:
@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
}
假如已經與前端開發妹子約定好了格式,比如:
{ "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; } }
後臺介面程式碼微調一下,返回值改為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()方法封裝一下。
那麼,有沒有更優雅的方法?我們繼續往下看:
實際使用場景中,並不是所有介面都需要統一格式。我們這裡使用一個註解作為開關,按需控制介面返回格式。
@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 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,就是為了自定義返回格式預留的,下面再看兩個場景:
如果個別介面的返回格式與預設格式相同,但是要求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
}
}
如果某個介面的返回格式不是預設的返回格式,比如約定返回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統一返回格式內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45