精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

年輕人不講武德,竟然重構出這么優雅后臺 API 接口

開發 前端
最近偶然間在看到 Spring 官方文檔的時候,新學到一個注解 @ControllerAdvice,并且成功使用這個注解重構我們項目的對外 API 接口,去除繁瑣的重復代碼,使其開發更加優雅。

[[353770]]

 本文轉載自微信公眾號「Java極客技術」,作者鴨血粉絲 。轉載本文請聯系Java極客技術公眾號。   

 Hello,早上好,我是阿粉~

最近偶然間在看到 Spring 官方文檔的時候,新學到一個注解 @ControllerAdvice,并且成功使用這個注解重構我們項目的對外 API 接口,去除繁瑣的重復代碼,使其開發更加優雅。

展示具體重構代碼之前,我們先來看下原先對外 API 接口是如何開發的。

這個 API 接口主要是用來與我們 APP 交互,這個過程我們統一定義一個交互協議,APP 端與后臺 API 接口統一都使用 JSON 格式。

另外后臺 API 接口對 APP 返回時,統一一些錯誤碼,APP 端需要根據相應錯誤碼,在頁面彈出一些提示。

下面展示一個查詢用戶信息返回的接口數據:

  1.     "code""000000"
  2.     "msg""success"
  3.     "result": { 
  4.         "id""1"
  5.         "name""test" 
  6.     } 

code代表對外的錯誤碼,msg代表錯誤信息,result代表具體返回信息。

前端 APP 獲取這個返回信息,首先判斷接口返回 code是否為 「000000」,如果是代表查詢成功,然后獲取 result 信息作出相應的展示。否則,直接彈出相應的錯誤信息。

重構之前

下面我們來看下,重構之前的,后臺 API 層的如何編碼。

  1. /** 
  2.  * V1 版本 
  3.  * 
  4.  * @return 
  5.  */ 
  6. @RequestMapping("testv1"
  7. public APIResult testv1() { 
  8.     try { 
  9.         User user = new User(); 
  10.         user.setId("1"); 
  11.         user.setName("test"); 
  12.         return APIResult.success(user); 
  13.     } catch (APPException e) { 
  14.         log.error("內部異常", e); 
  15.         return APIResult.error(e.getCode(), e.getMsg()); 
  16.     } catch (Exception e) { 
  17.         log.error("系統異常", e); 
  18.         return APIResult.error(RetCodeEnum.FAILED); 
  19.     } 

上面的代碼其實很簡單,內部統一封裝了一個工具類 APIResult,然后用其包裝具體的結果。

  1. @Data 
  2. public class APIResult<T> implements Serializable { 
  3.  
  4.     private static final long serialVersionUID = 4747774542107711845L; 
  5.  
  6.     private String code; 
  7.  
  8.     private String msg; 
  9.  
  10.     private T result; 
  11.  
  12.  
  13.     public static <T> APIResult success(T result) { 
  14.         APIResult apiResult = new APIResult(); 
  15.         apiResult.setResult(result); 
  16.         apiResult.setCode("000000"); 
  17.         apiResult.setMsg("success"); 
  18.         return apiResult; 
  19.     } 
  20.  
  21.     public static APIResult error(String code, String msg) { 
  22.         APIResult apiResult = new APIResult(); 
  23.         apiResult.setCode(code); 
  24.         apiResult.setMsg(msg); 
  25.         return apiResult; 
  26.     } 
  27.  
  28.     public static APIResult error(RetCodeEnum codeEnum) { 
  29.         APIResult apiResult = new APIResult(); 
  30.         apiResult.setCode(codeEnum.getCode()); 
  31.         apiResult.setMsg(codeEnum.getMsg()); 
  32.         return apiResult; 
  33.     } 

除了這個以外,還定義一個異常對象 APPException,用來統一包裝內部的各種異常。

上面的代碼很簡單,但是呢可以說比較繁瑣,重復代碼也比較多,每個接口都需要使用 try...catch 包裝,然后使用 APIResult包括正常的返回信息與錯誤信息。

第二呢,接口對象只能返回 APIResult,真實業務對象只能隱藏在 APIResult中。這樣不太優雅,另外不能很直觀知道真實業務對象。

重構之后

下面我們開始重構上面的代碼,主要目的是去除重復的那一坨try...catch 代碼。

這次重構我們需要使用Spring 注解 @ControllerAdvice以及 ResponseBodyAdvice,我們先來看下重構的代碼。

ps: ResponseBodyAdvice來自 Spring 4.2 API,如果各位同學需要使用這個的話,可能需要升級 Spring 版本。

改寫返回信息

首先我們需要實現 ResponseBodyAdvice,實現我們自己的處理類。

  1. @ControllerAdvice 
  2. public class CustomResponseAdvice implements ResponseBodyAdvice { 
  3.     /** 
  4.      * 是否需要處理返回結果 
  5.      * @param methodParameter 
  6.      * @param aClass 
  7.      * @return 
  8.      */ 
  9.     @Override 
  10.     public boolean supports(MethodParameter methodParameter, Class aClass) { 
  11.         System.out.println("In supports() method of " + getClass().getSimpleName()); 
  12.         return true
  13.     } 
  14.  
  15.     /** 
  16.      * 處理返回結果 
  17.      * @param body 
  18.      * @param methodParameter 
  19.      * @param mediaType 
  20.      * @param aClass 
  21.      * @param serverHttpRequest 
  22.      * @param serverHttpResponse 
  23.      * @return 
  24.      */ 
  25.     @Override 
  26.     public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { 
  27.         System.out.println("In beforeBodyWrite() method of " + getClass().getSimpleName()); 
  28.         if (body instanceof APIResult) { 
  29.             return body; 
  30.         } 
  31.         return APIResult.success(body); 
  32.     } 

實現上面的接口,我們就可以在 beforeBodyWrite方法里,修改返回結果了。

上面代碼中,只是簡單使用 APIResult包裝了返回結果,然后返回。其實我們還可以在此增加一些額外邏輯,比如說如接口返回信息由加密的需求,我們可以在這一層統一加密。

另外,這里判斷一下 body 是否 APIResult類,如果是就直接返回,不做修改。

這么做一來兼容之前的老接口,這是因為默認情況下,我們自己實現的 CustomResponseAdvice類,將會對所有的 Controller 生效。

如果不做判斷,以前的老接返回就會被包裝了兩層 APIResul,影響 APP 解析。

除此之外,如果大家擔心這個修改對以前的老接口有影響的話,可以使用下面的方式,只對指定的方法生效。

首先自定義一個注解,比如說:

  1. @Target({ElementType.TYPE, ElementType.METHOD}) 
  2. @Retention(RetentionPolicy.RUNTIME) 
  3. @Documented 
  4. public @interface CustomResponse { 

然后將其標注在需要改動的方法中,然后我們在 ResponseBodyAdvice#supports中判斷具體方法上有沒有自定義注解 CustomResponse,如果存在,返回 true,這就代表最后將會修改返回類。如果不存在,則返回 false,那么就會跟以前流程一樣。

  1. /** 
  2.  * 是否需要處理返回結果 
  3.  * 
  4.  * @param methodParameter 
  5.  * @param aClass 
  6.  * @return 
  7.  */ 
  8. @Override 
  9. public boolean supports(MethodParameter methodParameter, Class aClass) { 
  10.     System.out.println("In supports() method of " + getClass().getSimpleName()); 
  11.     Method method = methodParameter.getMethod(); 
  12.     return method.isAnnotationPresent(CustomResponse.class); 

全局異常處理

上面的代碼重構之后,將重復代碼抽取了出來,整體的代碼就剩下我們的業務邏輯,這樣就變得非常簡潔優雅。

不過,上面的重構的代碼,還是存在問題,主要是異常的處理。

如果上面的業務代碼拋出了異常,那么接口將會返回堆棧錯誤信息,而不是我們定義的錯誤信息。所以下面我們這個,再次優化一下。

這次我們主要需要使用 @ExceptionHandler注解,這個注解需要與 @ControllerAdvice 一起使用。

  1. @Slf4j 
  2. @ControllerAdvice 
  3. public class CustomExceptionHandler { 
  4.  
  5.     @ExceptionHandler(Exception.class) 
  6.     @ResponseBody 
  7.     public APIResult handleException(Exception e) { 
  8.         log.error("系統異常", e); 
  9.         return APIResult.error(RetCodeEnum.FAILED); 
  10.     } 
  11.  
  12.     @ExceptionHandler(APPException.class) 
  13.     @ResponseBody 
  14.     public APIResult handleAPPException(APPException e) { 
  15.         log.error("內部異常", e); 
  16.         return APIResult.error(e.getCode(), e.getMsg()); 
  17.     } 
  18.  

使用這個 @ExceptionHandler,將會攔截相應的異常,然后將會調用的相應方法處理異常。這里我們就使用 APIResult包裝一些錯誤信息返回。

總結

我們可以使用 @ControllerAdvice加 ResponseBodyAdvice 攔截返回結果,統一做出一些修改。這樣就可以使用的業務代碼非常簡潔,優雅。

另外,針對業務代碼的中,我們可以使用 @ExceptionHandler注解,統一做一個全局異常處理,這樣就可以無縫的跟 ResponseBodyAdvice結合。

不過這里需要一點,我們實現的 ResponseBodyAdvice 類,一定需要跟 @ControllerAdvice配合一起使用哦,至于具體原因,下篇文章阿粉分析原來的時候,再具體解釋哦。敬請期待哦~

 

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2021-07-06 21:37:05

索引SQL數據

2021-05-31 09:03:12

算法數據技術

2021-01-27 09:19:44

MySQL數據優化器

2021-05-26 05:40:32

加密勒索軟件攻擊

2020-12-07 08:04:39

CTO中年公司

2020-12-25 11:37:32

DDoS攻擊信用卡黑客

2022-01-13 06:49:23

開源項目刪庫

2019-09-17 16:04:17

戴爾

2021-09-14 11:57:01

雙重勒索勒索軟件黑客攻擊

2021-02-28 07:52:24

蠕蟲數據金絲雀

2021-01-29 14:35:41

代碼開發服務器

2019-04-01 15:28:20

996互聯網ICU

2020-10-09 09:28:43

互聯網數據技術

2020-11-05 14:48:29

AI人工智能互聯網

2020-12-03 18:18:46

微信表情下回

2012-09-03 14:26:50

云計算亞馬遜AWS

2020-05-20 15:37:43

VR虛擬現實年輕人

2021-03-01 19:11:10

大數據技術金融

2010-08-20 10:34:29

施密特
點贊
收藏

51CTO技術棧公眾號

欧美一级日本a级v片| 久久免费视频在线| 亚洲天堂网2018| 性xxxxfjsxxxxx欧美| 91在线观看地址| 国产精品老牛影院在线观看| 手机在线免费看毛片| 久久porn| 欧美精品亚洲一区二区在线播放| 久久福利一区二区| 国产在线视频资源| 国产成人在线视频网站| 国产精品igao视频| 激情五月少妇a| 国产精品一区二区av日韩在线| 91精品国产综合久久香蕉的特点| 乱妇乱女熟妇熟女网站| av片在线观看| 久久精品水蜜桃av综合天堂| 99久久99久久| 中文字幕在线播出| 国产视频一区在线观看一区免费| 久久精品色欧美aⅴ一区二区| 无码人妻aⅴ一区二区三区| 99国内精品久久久久| 欧美午夜精品伦理| 欧美 亚洲 视频| 日本中文字幕在线2020| 91蜜桃网址入口| 99r国产精品视频| 伊人免费在线观看| 午夜综合激情| 久久久久久久久久国产| 永久av免费网站| 欧美精美视频| 日韩经典中文字幕| 四虎精品一区二区| 岛国av一区| 日韩欧美国产精品| 久久久久久综合网| 欧美暴力调教| 欧美午夜精品久久久久久人妖| 很污的网站在线观看| av小次郎在线| 亚洲免费观看高清完整版在线观看 | 极品在线视频| 亚洲一区二区三区三| 99精品一区二区三区的区别| 色哟哟免费在线观看| 国产精品网站一区| 相泽南亚洲一区二区在线播放| 日本啊v在线| 26uuu久久天堂性欧美| 韩国成人av| 国产精品国产高清国产| 91麻豆国产精品久久| 麻豆精品传媒视频| 国产玉足榨精视频在线观看| 国产欧美一区视频| 亚洲图色在线| 久久久久久国产精品免费无遮挡| 国产精品成人免费精品自在线观看| 亚洲春色在线视频| 欧美三级黄网| 一区二区三区在线视频观看58| 日韩毛片网站| 最新欧美色图| 日本一区二区三级电影在线观看| 久久亚洲免费| 国产日本在线观看| 日本一区二区三区四区在线视频| 日韩理论片在线观看| 91伦理视频在线观看| 一区在线中文字幕| 免费看日本黄色| 欧美久久天堂| 精品视频1区2区| 51自拍视频在线观看| 一区二区三区高清在线观看| 亚洲精品国产美女| 国产精品久久久视频| 亚洲影视一区二区三区| 欧美精品久久久久久久免费观看| 黄网在线观看视频| 麻豆精品一区二区综合av| 999国内精品视频在线| 天堂成人在线观看| 亚洲国产精品激情在线观看 | 欧美精品久久久久久| 日韩在线不卡视频| 国产精品1000| 蜜臀精品一区二区三区在线观看 | 日韩免费高清在线| 日韩欧乱色一区二区三区在线| 欧美大片在线观看一区| 给我免费观看片在线电影的| 91麻豆精品国产91久久久平台| 欧美日韩国产999| 精品无码一区二区三区的天堂| 国产一区激情在线| 欧美不卡1区2区3区| 成人在线观看免费网站| 欧美日韩一区二区三区在线免费观看| 亚洲一区精品视频在线观看| 美女呻吟一区| 欧美另类在线播放| 69av视频在线观看| 成人看片黄a免费看在线| 亚洲一区综合| 另类专区亚洲| 亚洲国产高清自拍| 91嫩草丨国产丨精品| 久久一区视频| 国产精品视频在线免费观看| 毛片在线视频| 91久久久免费一区二区| 先锋资源av在线| 中文精品久久| 国产精品视频最多的网站| 午夜性色福利影院| 夜夜亚洲天天久久| 久久久久久综合网| 久久久综合色| 国产精品激情av电影在线观看| 天堂在线观看免费视频| 一区二区三区不卡视频在线观看| 五月激情五月婷婷| 菠萝蜜一区二区| 欧洲一区二区视频| 熟妇高潮一区二区三区| 亚洲在线一区二区三区| 国产精品久久久久久久99| 日韩一级毛片| 国产精品久久久久久搜索| 四虎成人免费在线| 舔着乳尖日韩一区| 天天躁日日躁狠狠躁免费麻豆| 亚洲影视一区二区三区| 91在线观看免费观看| 黄色网页在线免费观看| 777欧美精品| 性生交大片免费全黄| 美女视频黄免费的久久 | 在线观看免费视频国产| 欧美精品91| 99国精产品一二二线| 欧美草逼视频| 亚洲精品一区二区精华| 久久久久久久久久久久久久免费看 | 欧美激情第10页| 亚洲综合日韩中文字幕v在线| 免费的黄网站在线观看| 欧美人成免费网站| 老司机成人免费视频| 国产精品一区二区三区乱码| 四虎永久免费网站| 日韩一区二区三区高清在线观看| 欧美另类暴力丝袜| 理论片中文字幕| 婷婷激情综合网| 全黄一级裸体片| 美国欧美日韩国产在线播放| 中文字幕一区二区三区四区五区六区 | 中文字幕 自拍| 蜜桃一区二区三区四区| 中文字幕剧情在线观看一区| 一区二区日韩| 欧美亚洲成人xxx| 国产在线一在线二| 欧美日韩久久久| 三级影片在线看| www.亚洲精品| 免费裸体美女网站| 91影院成人| 国产精品美女久久久久av福利| 九色porny自拍视频在线观看| 国产亚洲精品91在线| 91麻豆国产在线| 亚洲电影一区二区三区| 亚洲av成人无码久久精品 | 日本福利一区二区| 成年人二级毛片| 高清不卡一区二区| 亚洲视频在线观看一区二区三区| 国产韩国精品一区二区三区| 国产精品免费一区二区三区四区| 成人性生活视频| 久久久精品日本| 内衣办公室在线| 日韩欧美国产系列| 性色av一区二区三区四区| 亚洲黄色尤物视频| 在线不卡av电影| 国产一区二区三区四区在线观看| 69堂免费视频| 亚洲精品小说| 欧美中日韩一区二区三区| 亚洲国产中文在线二区三区免| 日本精品va在线观看| 精品国产白色丝袜高跟鞋| 亚洲激情中文字幕| 国产精品自偷自拍| 色av综合在线| 中文字幕第28页| 亚洲欧洲性图库| 亚洲综合网在线观看| 成人小视频在线| 国产aⅴ爽av久久久久| 欧美综合国产| 日韩亚洲欧美视频| 91tv官网精品成人亚洲| 日韩欧美一区二区视频在线播放| 国产精品tv| 亚洲影院高清在线| 国产一区二区主播在线| 78色国产精品| av在线网页| 欧美成人一二三| 日本三级在线播放完整版| 亚洲第一区在线| 精品国产一级片| 欧美日韩精品欧美日韩精品一 | 热久久免费视频| 亚洲中文字幕无码专区| 极品少妇一区二区三区| 992tv快乐视频| 亚洲v在线看| 亚洲精品视频一二三| 欧美日韩国产免费观看视频| 久久综合狠狠综合久久综青草| jizz国产精品| 国产精品二区二区三区| 亚洲国产中文在线二区三区免| 成人美女免费网站视频| 小说区图片区亚洲| 国产免费观看久久黄| 欧美特大特白屁股xxxx| 45www国产精品网站| 免费h在线看| 97热在线精品视频在线观看| 超碰资源在线| 97久久国产精品| 男人久久天堂| 欧美一级视频在线观看| 女人高潮被爽到呻吟在线观看| 性日韩欧美在线视频| gogo久久| 4388成人网| 日本免费一区二区三区四区| 国产精品91久久| 97成人超碰| 成人免费xxxxx在线观看| 久久综合偷偷噜噜噜色| 99超碰麻豆| 女同一区二区三区| 欧美二区在线看| 国产一区二区三区站长工具| 婷婷久久五月天| 亚洲91久久| 男女激情免费视频| 一本色道88久久加勒比精品| 欧美在线观看成人| 日韩成人免费电影| 日本在线播放一区二区| 黑人巨大精品欧美黑白配亚洲| 超级砰砰砰97免费观看最新一期| 成人一道本在线| 三级黄色片网站| 国产精品三级久久久久三级| 中文字幕电影av| 亚洲成人免费av| 国产精品免费无遮挡无码永久视频| 欧美日韩在线播放三区四区| 国产哺乳奶水91在线播放| 亚洲国产成人久久| 在线免费看a| 久久久久久国产精品美女| 成人欧美magnet| 亚洲一区二区三区毛片 | 亚洲一区二区三区色| 午夜久久tv| 国产三级三级三级看三级| 国产裸体歌舞团一区二区| 五级黄高潮片90分钟视频| 最新日韩在线视频| 国产91精品一区| 3d成人h动漫网站入口| 欧美一区二区三区激情| 中文字幕免费精品一区高清| 在线午夜影院| 日韩av手机在线观看| 97色婷婷成人综合在线观看| 久久精品99久久| 亚洲高清资源在线观看| 久草青青在线观看| 国产在线不卡视频| 李宗瑞91在线正在播放| 一区二区三区在线视频播放| 免费黄色一级大片| 亚洲精品一区二区三区99| 在线日本中文字幕| 欧洲成人免费aa| 网站一区二区| 一区二区三区在线视频看| 99亚洲伊人久久精品影院红桃| 中文字幕22页| 国产日韩欧美综合在线| 国产 欧美 日韩 在线| 5566中文字幕一区二区电影| 毛片在线能看| 国内精品小视频在线观看| www一区二区三区| 日本一区二区三区www| 一区二区三区国产盗摄 | 欧美欧美在线| 亚洲成人自拍视频| 久久综合五月| 成年人的黄色片| 亚洲国产wwwccc36天堂| hs视频在线观看| 久久久精品免费视频| 久久伊人国产| 视频一区三区| 三级欧美韩日大片在线看| 亚洲国产果冻传媒av在线观看| 一区二区三区欧美久久| 91尤物国产福利在线观看| 国产一区二区精品丝袜| 电影天堂国产精品| 久久久久久久久久久久久久久久av | 手机看片久久久| 日韩电影中文字幕一区| 不卡的av影片| 国产精品美女久久久久av福利| 欧美日韩18| 无码人妻一区二区三区在线| 一区二区成人在线观看| 精品国产黄色片| 精品中文字幕乱| 操欧美女人视频| 欧美一级爱爱视频| 国产69精品久久久久777| 欧美三级 欧美一级| 日韩欧美国产系列| 久久青青色综合| 狠狠色综合网站久久久久久久| 亚洲国产片色| 老熟妇精品一区二区三区| 精品久久久视频| 日韩a在线观看| 国产v综合ⅴ日韩v欧美大片 | 成人污版视频| 在线观看三级网站| 国产高清在线观看免费不卡| 一区二区三区免费高清视频| 亚洲电影av在线| 天堂电影一区| 色就是色欧美| 久久av中文字幕片| 国产精品久久久久久久精| 精品国产污网站| 九色porny丨国产首页在线| 欧美日韩亚洲在线| 精品一区二区三区免费播放| 一区二区成人免费视频| 亚洲电影免费观看高清完整版在线观看| 91精品国产黑色瑜伽裤| 欧美高清性xxxxhdvideosex| 日韩高清一区在线| 视频这里只有精品| 亚洲经典中文字幕| 日韩天堂在线| 日本一二三区视频在线| av午夜精品一区二区三区| 做爰视频毛片视频| 色综合久久精品亚洲国产 | 国产盗摄精品一区二区三区在线| 麻豆国产尤物av尤物在线观看| 日韩精品视频在线免费观看| 欧美日韩国产网站| 久久久久久久久久久综合| 26uuu亚洲综合色| 97人妻人人澡人人爽人人精品| 久久久久国产精品免费| 国产亚洲电影| 制服.丝袜.亚洲.中文.综合懂| 欧美午夜影院在线视频| 日本中文在线| 国产专区一区二区| 久久99久久99| 一级片中文字幕| 久久综合九色九九| 香蕉久久夜色精品国产更新时间| 亚洲va综合va国产va中文| 午夜天堂影视香蕉久久| 在线观看免费黄色| 久久精品久久精品国产大片| 久久精品免费看| 久久久精品免费看| 蜜月aⅴ免费一区二区三区|