精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

视频一区在线播放| 成年人在线看片| 日本性生活一级片| 你懂的在线免费观看| 一区二区三区高清在线观看| 国产日韩影视精品| 午夜欧美大片免费观看| 中日韩在线视频| 国产欧美一区二区三区在线看蜜臂| 日本国产一区| 国产日韩精品一区二区浪潮av| 国产精品露脸自拍| 在线观看福利片| 僵尸再翻生在线观看免费国语| 国产激情一区二区三区桃花岛亚洲| 国产午夜精品视频免费不卡69堂| 噜噜噜久久亚洲精品国产品麻豆| 草草视频在线播放| 欧美~级网站不卡| 91精品国产丝袜白色高跟鞋| 亚洲一区二区在线免费观看| 国产精品51麻豆cm传媒| 国产中文字幕一区二区三区| 欧美日韩国产区| 精品一区久久| 天天做天天爱夜夜爽| 久久悠悠精品综合网| 亚洲风情在线资源站| 成人情视频高清免费观看电影| 久久国产高清视频| 日韩精品一级| 亚洲综合另类小说| 国产精品毛片va一区二区三区| 我家有个日本女人| 亚洲一区二区三区在线免费| 欧美影院精品一区| 亚洲看片网站| 国产视频在线免费观看| 亚洲男女av一区二区| 91精品国产福利| 日韩精品免费播放| 瑟瑟视频在线| 国产福利一区二区| 国产欧美日韩高清| www青青草原| 久久国产小视频| 欧美一区二区三区性视频| 三年中国国语在线播放免费| 五月婷婷在线视频| 国产亚洲欧美激情| 欧美精品123| 中文字幕日韩三级| 午夜精品久久99蜜桃的功能介绍| 一本一道久久a久久精品逆3p | 美女网站色免费| 日本中文字幕在线观看| 国产亲近乱来精品视频| 国产在线精品一区免费香蕉| 精品国产乱码久久久久久鸭王1 | 国产乡下妇女做爰毛片| 色天下一区二区三区| 欧美亚洲禁片免费| 黑人粗进入欧美aaaaa| 三上悠亚一区二区| 椎名由奈av一区二区三区| av资源站久久亚洲| 香蕉污视频在线观看| 亚洲精品网址| 日韩av在线网站| 国产精品嫩草影院8vv8| 超碰99在线| 五月天欧美精品| 在线一区高清| h片在线免费| 国产网站一区二区三区| 日本一区二区三不卡| va婷婷在线免费观看| 可以免费看不卡的av网站| 日本成熟性欧美| 久久成人在线观看| av亚洲免费| 亚洲精品大尺度| 欧美视频亚洲图片| 成人精品电影在线| 国产精品的网站| 久久精品国产精品国产精品污| 国产精品探花视频| 日本强好片久久久久久aaa| 国语自产在线不卡| 国产成人综合在线视频| 国产精品一线天粉嫩av| 日韩中文在线观看| 日韩中文字幕有码| 欧美日韩导航| 精品处破学生在线二十三| 三年中文在线观看免费大全中国| 欧美激情三级| 56国语精品自产拍在线观看| 福利在线一区二区三区| 国产精品igao视频网网址不卡日韩| 在线视频一区二区三| 69堂免费视频| 欧美aaaaaaaa| 欧美丝袜丝nylons| 成人啪啪18免费游戏链接| 国产电影一区| 亚洲欧美国产一本综合首页| av2014天堂网| 久久夜色精品国产噜噜av小说| 国产亚洲一区二区在线| 一区二区三区免费高清视频| 综合天堂久久久久久久| 欧美亚洲另类激情另类| 国产污污视频在线观看| 麻豆精品新av中文字幕| 国产精自产拍久久久久久| 国产91绿帽单男绿奴| 国产成人精品免费看| 亚洲资源在线看| 国产福利小视频| 久久精品一二三| 日本一区二区三区视频在线观看 | 久久av国产紧身裤| 久久精品99久久久久久久久| 天天摸日日摸狠狠添| 欧美日韩中字| 国外成人在线视频| 国产黄色小视频在线观看| 国产日产精品1区| 国产免费黄色一级片| 成av人片在线观看www| 欧美久久久久久久久| 色婷婷一区二区三区在线观看| 综合伊思人在钱三区| 亚洲激情免费观看| www.av成人| 亚洲成人tv| 国产精品美女久久久久av超清| 五月天福利视频| 久久久久国产免费免费 | 精品人妻互换一区二区三区| 99国产精品私拍| 日本成人在线视频网址| 亚洲三级黄色片| 午夜成人在线视频| 看欧美ab黄色大片视频免费| 亚洲精品蜜桃乱晃| 欧美综合第一页| 可以直接在线观看的av| 欧美性色xo影院| 午夜宅男在线视频| 欧美精品色图| 国产精品男人爽免费视频1| 国产在线超碰| 亚洲精品精品亚洲| 国产亚洲精品网站| 中文成人在线| 亚洲精品97久久| 日韩三级一区二区三区| 热久久久久久久| 亚洲高清精品中出| 亚洲色图综合| 欧美成人网在线| 久久99国产综合精品免费| 97久久精品人人做人人爽| 伊人情人网综合| 天堂久久一区| 久久777国产线看观看精品| 日韩av大片在线观看| 91免费在线视频观看| 欧美日韩一级在线 | 欧美性在线观看| 日本一区二区三区在线观看视频| 国产精品午夜在线| 国产日韩av网站| 少妇精品导航| 国产精品久久久久久久av电影 | 国产精品精品软件男同| 国产精品18久久久久| 青青草国产精品视频| 宅男噜噜噜66国产精品免费| 精品自在线视频| 五月婷婷六月丁香| 欧美三级日韩三级| 少妇特黄一区二区三区| 在线观看视频日韩| 91在线视频九色| av在线免费播放网站| 精品日韩视频在线观看| 国产人妻人伦精品1国产丝袜| 最新国产精品| 久久精品五月婷婷| 日韩精品一级毛片在线播放| 欧美精品videossex88| 国产乱码久久久| 亚洲一本大道在线| 无码国产精品一区二区高潮| 91精品久久久久久久久久不卡| 不卡视频一区二区| 色婷婷综合久久久中字幕精品久久 | 欧美色图另类小说| 水蜜桃精品av一区二区| 欧美一级在线播放| 麻豆传媒在线观看| 欧美无砖砖区免费| 国产精品白浆一区二小说| 国产成人在线色| 国产精品亚洲αv天堂无码| 青青操综合网| 成人免费看片视频| 黄页视频在线播放| 69堂亚洲精品首页| 久久人妻免费视频| 91视频一区二区| 亚洲最大天堂网| 麻豆91精品| 欧美日韩亚洲综合一区二区三区激情在线| 本网站久久精品| 色伦专区97中文字幕| 日韩二区三区| 精品伦理精品一区| 久久亚洲国产成人精品性色| 国产拍揄自揄精品视频麻豆| 亚洲啪av永久无码精品放毛片 | 大尺度一区二区| 男人草女人视频| 一区二区三区四区精品视频| 国产精品久久久久久久久影视| 国产福利片在线观看| 欧美成年人网站| 婷婷激情在线| 一本色道久久88综合亚洲精品ⅰ| 无码精品视频一区二区三区| 欧美变态口味重另类| 99久久精品国产成人一区二区| 欧美在线短视频| 7799精品视频天天看| 欧美日韩国产综合新一区 | 国产女同一区二区| 国产第一亚洲| 国产精品久久久久久久久久尿| 五月天国产在线| 亚洲最新视频在线| 欧美日韩激情视频一区二区三区| 精品久久国产字幕高潮| 99久久久久成人国产免费| 欧美美女网站色| 亚洲一级av毛片| 一区二区国产盗摄色噜噜| 中日韩一级黄色片| 一区免费观看视频| 久久一级免费视频| 成人av网站免费| 国产一级做a爰片久久| 久热国产精品| 91香蕉视频导航| 麻豆精品久久久| 91亚洲精品久久久蜜桃借种| 精品中文字幕一区二区小辣椒 | 亚洲影院在线| 中文视频一区视频二区视频三区| 成久久久网站| 国产精品久久久久久免费观看 | 美国av一区二区三区| 国产欧美在线观看免费| 国产欧美一区二区三区久久人妖| 国产亚洲一区二区手机在线观看| 国产精品video| 国产原创一区| 91原创国产| 国产精品第一国产精品| 成人国产精品av| 精品麻豆剧传媒av国产九九九| 91网免费观看| 久久久精品国产**网站| 日本高清不卡三区| 国产精品99久久精品| 久久国产精品一区二区三区四区| 伊人成综合网yiren22| 亚洲国产欧美一区二区三区不卡| 91不卡在线观看| 99色这里只有精品| 三级在线观看一区二区| 亚洲精品国产一区二区三区| 久久精品成人| 超碰人人草人人| 成人午夜在线播放| 人妻av无码一区二区三区 | av男人的天堂av| 亚洲欧美色一区| 中文天堂资源在线| 亚洲综合清纯丝袜自拍| 99re这里只有精品在线| 欧美性高潮床叫视频| 亚洲综合精品在线| 亚洲激情视频在线播放| 精产国品自在线www| 欧美一级电影久久| 精品视频在线观看免费观看| 鲁鲁狠狠狠7777一区二区| 午夜精品久久久久久久四虎美女版| 18黄暴禁片在线观看| 久久精品亚洲人成影院 | 日韩精品乱码免费| 国产精品50p| 狠狠色狠狠色综合| 99日在线视频| 91丨porny丨首页| 青娱乐91视频| 欧美视频一区在线| 西西人体44www大胆无码| 在线亚洲欧美视频| h视频在线播放| 97精品久久久| 国产精品亚洲综合在线观看| 日本一区二区三区在线视频| 亚洲黄色三级| 成人在线免费在线观看| 国产乱码一区二区三区| 九色91porny| 中文字幕精品综合| 国产成人免费看| 欧美tickling挠脚心丨vk| 日韩在线资源| 国产成人免费av| 久久日本片精品aaaaa国产| 精品日本一区二区| 国一区二区在线观看| 337p粉嫩大胆噜噜噜鲁| 国产91丝袜在线播放0| 亚洲 欧美 变态 另类 综合| 欧美性猛片xxxx免费看久爱| 精品亚洲成a人片在线观看| 97国产真实伦对白精彩视频8| 91成人午夜| 成人在线免费观看视频网站| 国产精品视区| 少妇激情一区二区三区| 91视频免费看| 永久免费无码av网站在线观看| 亚洲第一中文字幕| 黄网在线免费| 啪一啪鲁一鲁2019在线视频| 欧美a一欧美| www.99热这里只有精品| 成人在线综合网站| 国产污视频在线观看| 欧美精品一区二区三区高清aⅴ | 欧洲成人免费aa| 美女一区二区在线观看| 黄色大片中文字幕| kk眼镜猥琐国模调教系列一区二区| 99久久久无码国产精品性| 黑人欧美xxxx| 欧美在线观看在线观看| 日韩免费观看网站| 精品三级国产| 成人在线观看毛片| 成人午夜激情影院| 97人人澡人人爽人人模亚洲 | 成人影院免费观看| 国产精品视频男人的天堂| 999久久久国产精品| 搡的我好爽在线观看免费视频| 99久久免费视频.com| 久久夜色精品亚洲| 亚洲人精品午夜在线观看| 在线观看三级视频| 国产精品电影久久久久电影网| 国产精品三级| 992kp免费看片| 亚洲成人777| 国产中文字幕在线观看| 国产美女扒开尿口久久久| 欧美fxxxxxx另类| 亚洲一区二区三区综合| 欧洲av在线精品| av软件在线观看| 国产区日韩欧美| 伊人青青综合网| 欧美双性人妖o0| 在线观看免费视频综合| h片在线免费| 欧美第一黄网| 国产美女精品人人做人人爽| 国产精品不卡av| 色噜噜狠狠狠综合曰曰曰88av | 久久精品亚洲| 亚洲女人久久久| 亚洲电影第1页| 福利一区二区三区视频在线观看| 国产乱子伦精品视频| 久久先锋影音av鲁色资源| 日本三级网站在线观看| 亚洲视频一区二区| 91麻豆精品国产91久久久久推荐资源| 制服国产精品| 91性感美女视频| www日本在线| 国产精品入口免费视|