国产av一二三区|日本不卡动作网站|黄色天天久久影片|99草成人免费在线视频|AV三级片成人电影在线|成年人aV不卡免费播放|日韩无码成人一级片视频|人人看人人玩开心色AV|人妻系列在线观看|亚洲av无码一区二区三区在线播放

網(wǎng)易首頁 > 網(wǎng)易號 > 正文 申請入駐

五個(gè)步驟,助你優(yōu)雅的寫好 Controller 層代碼!

0
分享至

Java精選面試題(微信小程序):5000+道面試題和選擇題,真實(shí)面經(jīng),簡歷模版,包含Java基礎(chǔ)、并發(fā)、JVM、線程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架構(gòu)設(shè)計(jì)、大廠真題等,在線隨時(shí)刷題!

Controller 層邏輯

MVC架構(gòu)下,我們的web工程結(jié)構(gòu)會(huì)分為三層,自下而上是dao層,service層和controller層。controller層為控制層,主要處理外部請求,調(diào)用service層。

一般情況下,controller層不應(yīng)該包含業(yè)務(wù)邏輯,controller的功能應(yīng)該有以下五點(diǎn):

⑴、接收請求并解析參數(shù)

⑵、業(yè)務(wù)邏輯執(zhí)行成功做出響應(yīng)

⑶、異常處理

⑷、轉(zhuǎn)換業(yè)務(wù)對象

⑸、調(diào)用 Service 接口

普通寫法

@RestController publicclass TestController {     @Autowired     private UserService userService;     @PostMapping("/test") public Result service(@Validated  @RequesBody  UserRequestBo requestBo) throws Exception {         Result result = new Result();         // 參數(shù)校驗(yàn)         if (StringUtils.isNotEmpty(requestBo.getId())                 || StringUtils.isNotEmpty(requestBo.getType())                 || StringUtils.isNotEmpty(requestBo.getName())                 || StringUtils.isNotEmpty(requestBo.getAge())) {             thrownew Exception("必輸項(xiàng)校驗(yàn)失敗");         } else {             // 調(diào)用service更新user,更新可能拋出異常,要捕獲             try {                 int count = 0;                 User user = userService.queryUser(requestBo.getId());                 if (ObjectUtils.isEmpty(user)) {                     result.setCode("11111111111");                     result.setMessage("請求失敗");                     return result;                 }                 // 轉(zhuǎn)換業(yè)務(wù)對象                 UserDTO userDTO = new UserDTO();                 BeanUtils.copyProperties(requestBo, userDTO);                 if ("02".equals(user.getType())) {// 退回修改的更新                     count = userService.updateUser(userDTO)                 }elseif ("03".equals(user.getType())) {// 已生效狀態(tài),新增一條待復(fù)核                     count = userService.addUser(userDTO);                 }                 // 組裝返回對象                 result.setData(count);                 result.setCode("00000000");                 result.setMessage("請求成功");             } catch (Exception ex) {                 // 異常處理                 result.setCode("111111111111");                 result.setMessage("請求失敗");             }         }         return result;     } }
優(yōu)化思路 1、調(diào)用 Service 層接口

一般情況下,controller作為控制層調(diào)用service層接口,不應(yīng)該包含任何業(yè)務(wù)邏輯,所有的業(yè)務(wù)操作,都放在service層實(shí)現(xiàn),把controller層相關(guān)代碼去掉

controller層就變成了:

@RestController publicclass TestController { @Autowired private UserService userService; @PostMapping("/test") public Result service(@Validated  @RequesBody  UserRequestBo requestBo) throws Exception {     Result result = new Result();     // 參數(shù)校驗(yàn)     if (StringUtils.isNotEmpty(requestBo.getId())             || StringUtils.isNotEmpty(requestBo.getType())             || StringUtils.isNotEmpty(requestBo.getName())             || StringUtils.isNotEmpty(requestBo.getAge())) {         thrownew Exception("必輸項(xiàng)校驗(yàn)失敗");     } else {         // 調(diào)用service更新user,更新可能拋出異常,要捕獲         try {          // 轉(zhuǎn)換業(yè)務(wù)對象             UserDTO userDTO = new UserDTO();             BeanUtils.copyProperties(requestBo, userDTO);             int count = userService.updateUser(userDTO);             // 組裝返回對象             result.setData(count);             result.setCode("00000000");             result.setMessage("請求成功");         } catch (Exception ex) {             // 異常處理             result.setCode("EEEEEEEE");             result.setMessage("請求失敗");         }     }     return result; }
2、參數(shù)校驗(yàn)

其實(shí)大多數(shù)的參數(shù)校驗(yàn)就是判空或者空字符串,那么我們可以用@NotBlank等注解。在UserRequestBo類中name屬性上加上@NotBlank注解。另外,推薦公眾號Java精選,回復(fù)java面試,獲取在線面試資料,支持在線隨時(shí)隨地刷題。

優(yōu)化后如下:

@Data public class UserRequestBo {     @NotBlank     private String id;     @NotBlank     private String type;     @NotBlank     private String name;     @NotBlank     private String age; }

controller層就變成了:

@RestController publicclass TestController {     @Autowired     private UserService userService;     @PostMapping("/test")     public Result service( @Validated  @RequesBody  UserRequestBo requestBo) throws Exception {         Result result = new Result();         // 調(diào)用service更新user,更新可能拋出異常,要捕獲         try {          // 轉(zhuǎn)換業(yè)務(wù)對象             UserDTO userDTO = new UserDTO();             BeanUtils.copyProperties(requestBo, userDTO);             int count = userService.updateUser(userDTO);             // 組裝返回對象             result.setData(count);             result.setCode("00000000");             result.setMessage("請求成功");         } catch (Exception ex) {             // 異常處理             result.setCode("EEEEEEEE");             result.setMessage("請求失敗");         }         return result;     } }

備注:@NotNull、@NotBlank、@NotEmpty的區(qū)別,也適用于代碼中的校驗(yàn)方法


  • @NotNull:平常用于基本數(shù)據(jù)的包裝類(Integer,Long,Double等等),如果@NotNull 注解被使用在 String 類型的數(shù)據(jù)上,則表示該數(shù)據(jù)不能為 Null,但是可以為空字符串(“”),空格字符串(“ ”)等。

  • @NotEmpty:平常用于 String、Collection集合、Map、數(shù)組等等,@NotEmpty注解的參數(shù)不能為 Null 或者 長度為 0,如果用在String類型上,則字符串也不能為空字符串(“”), 但是空格字符串(“ ”)不會(huì)被校驗(yàn)住。

  • @NotBlank:平常用于 String 類型的數(shù)據(jù)上,加了@NotBlank注解的參數(shù)不能為 Null ,不能為空字符串(“”), 也不能會(huì)空格字符串(“ ”),多了一個(gè)trim()得到效果。

3、統(tǒng)一封裝返回對象

代碼中無論是業(yè)務(wù)成功或者失敗,都需要封裝返回對象,目前代碼中都是哪里用到就在哪里進(jìn)行封裝

我們可以統(tǒng)一封裝返回對象

優(yōu)化后如下:

@Data publicclass Result

  {     private String code;     private String message;     private T data; // 請求成功,指定data     publicstatic    Result   success(T data) {         returnnew Result<>(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMessage(), data);     }      // 請求成功,指定data和指定message     publicstatic    Result   success(String message, T data) {         returnnew Result<>(ResultEnum.SUCCESS.getCode(), message, data);     }      // 請求失敗     publicstatic Result failed() {         returnnew Result<>(ResultEnum.COMMON_FAILED.getCode(), ResultEnum.COMMON_FAILED.getMessage(), null);     }      // 請求失敗,指定message     publicstatic Result failed(String message) {         returnnew Result<>(ResultEnum.COMMON_FAILED.getCode(), message, null);     }          // 請求失敗,指定code和message     publicstatic Result failed(String code, String message) {         returnnew Result<>(code, message, null);     } }

controller層就變成了:

@RestController publicclass TestController {     @Autowired     private UserService userService;     @PostMapping("/test")     public Result service(@Validated  @RequesBody  UserRequestBo requestBo) throws Exception {         // 調(diào)用service更新user,更新可能拋出異常,要捕獲         try {          // 轉(zhuǎn)換業(yè)務(wù)對象             UserDTO userDTO = new UserDTO();             BeanUtils.copyProperties(requestBo, userDTO);             int count = userService.updateUser(userDTO);             // 組裝返回對象             Result.success(count);         } catch (Exception ex) {             // 異常處理             Result.failed(ex.getMessage());         }     } } 
4、統(tǒng)一的異常捕獲

Controller層和service存在大量的try-catch,都是重復(fù)代碼并且看起來也不優(yōu)雅。可以給controller層的方法加上切面來統(tǒng)一處理異常。

@ControllerAdvice注解(@RestControllerAdvice也可以),用來定義controller層的切面,添加@Controller注解的類中的方法執(zhí)行都會(huì)進(jìn)入該切面,同時(shí)我們可以使用@ExceptionHandler來對不同的異常進(jìn)行捕獲和處理,對于捕獲的異常,我們可以進(jìn)行日志記錄,并且封裝返回對象。

優(yōu)化后如下:

// @RestControllerAdvice(basePackages = "com.ruoyi.web.controller.demo.test"), 指定包路徑進(jìn)行切面 // @RestControllerAdvice(basePackageClasses = TestController.class) , 指定Contrller.class進(jìn)行切面 // @RestControllerAdvice 不帶參數(shù)默認(rèn)覆蓋所有添加@Controller注解的類 @RestControllerAdvice(basePackageClasses = TestController.class) public class TestControllerAdvice {     @Autowired     HttpServletRequest httpServletRequest;     private void logErrorRequest(Exception e){         // 組裝日志內(nèi)容         String logInfo = String.format("報(bào)錯(cuò)API URL: %S, error = ", httpServletRequest.getRequestURI(), e.getMessage());         // 打印日志         System.out.println(logInfo);     }     /**      * {@code @RequestBody} 參數(shù)校驗(yàn)不通過時(shí)拋出的異常處理      */     @ExceptionHandler({MethodArgumentNotValidException.class})     public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {         // 打印日志         logErrorRequest(ex);         // 組織異常信息,可能存在多個(gè)參數(shù)校驗(yàn)失敗         BindingResult bindingResult = ex.getBindingResult();         StringBuilder sb = new StringBuilder("校驗(yàn)失敗:");         for (FieldError fieldError : bindingResult.getFieldErrors()) {        sb.append(fieldError.getField()).append(":").append(fieldError.getDefaultMessage()).append(", ");         }         return Result.failed(ResultEnum.VALIDATE_FAILED.getCode(), sb.toString());     }     /**      * 業(yè)務(wù)層異常,如果項(xiàng)目中有自定義異常則使用自定義業(yè)務(wù)異常,如果沒有,可以和其他異常一起處理      *      * @param exception      * @return      */     @ExceptionHandler(RuntimeException.class)     protected Result serviceException(RuntimeException exception) {         logErrorRequest(exception);         return Result.failed(exception.getMessage());     }     /**      * 其他異常      *      * @param exception      * @return      */     @ExceptionHandler({HttpClientErrorException.class, IOException.class, Exception.class})     protected Result serviceException(Exception exception) {         logErrorRequest(exception);         return Result.failed(exception.getMessage());     } }

controller層就變成了:

@RestController publicclass TestController {     @Autowired     private UserService userService;     @PostMapping("/test")     public Result service( @Validated  @RequesBody  UserRequestBo requestBo) throws Exception {         UserDTO userDTO = new UserDTO();         BeanUtils.copyProperties(requestBo, userDTO);         // 調(diào)用service層接口         int count = userService.updateUser(userDTO);         //組裝返回對象         return Result.success(count);     } }
5、轉(zhuǎn)換業(yè)務(wù)對象

代碼中可能有很多個(gè)地方轉(zhuǎn)換同一個(gè)業(yè)務(wù)對象,入?yún)?code>UserRequestBo可以轉(zhuǎn)換為userDTO,可以理解為這是UserRequestBo的一個(gè)特性或者能力,我們可以參考充血模式的思想,在UserRequestBo中定義convertToUserDTO方法,我們的目的是轉(zhuǎn)換業(yè)務(wù)對象,至于使用什么方式轉(zhuǎn)換,調(diào)用方并不關(guān)心,現(xiàn)在使用的BeanUtils.copyProperties(),如果有一天想修改成使用Mapstruct來進(jìn)行對象轉(zhuǎn)換,只需要修改UserRequestBoconvertToUserDTO方法即可,不會(huì)涉及到業(yè)務(wù)代碼的修改。

優(yōu)化后代碼:

@Data publicclass UserRequestBo {     @NotBlank     private String id;     @NotBlank     private String type;     @NotBlank     private String name;     @NotBlank     private String age;     /**      * UserRequestBo對象為UserDTO      * */     public UserDTO convertToUserDTO(){         UserDTO userDTO = new UserDTO();         // BeanUtils.copyProperties要求字段名和字段類型都要保持一致,如果有不一樣的字段,需要單獨(dú)set         BeanUtils.copyProperties(this, userDTO);         userDTO.setType(this.getType());         return userDTO;     } }

controller層就變成了:

@RestController public class TestController {     @Autowired     private UserService userService;     @PostMapping("/test")     public Result service(@Validated  @RequesBody  UserRequestBo requestBo) throws Exception {         return Result.success(userService.updateUser(requestBo.convertToUserDTO()));     } }

優(yōu)化結(jié)束,打完收工。

作者:桃花影落丶飛神劍

https://blog.csdn.net/weixin_44271364/article/details/129157011

公眾號“Java精選”所發(fā)表內(nèi)容注明來源的,版權(quán)歸原出處所有(無法查證版權(quán)的或者未注明出處的均來自網(wǎng)絡(luò),系轉(zhuǎn)載,轉(zhuǎn)載的目的在于傳遞更多信息,版權(quán)屬于原作者。如有侵權(quán),請聯(lián)系,筆者會(huì)第一時(shí)間刪除處理!

最近有很多人問,有沒有讀者交流群!加入方式很簡單,公眾號Java精選,回復(fù)“加群”,即可入群!

文章有幫助的話,點(diǎn)在看,轉(zhuǎn)發(fā)吧!

特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關(guān)推薦
熱點(diǎn)推薦
美國吃華人絕戶財(cái)富已經(jīng)成為一個(gè)公開的密碼了!

美國吃華人絕戶財(cái)富已經(jīng)成為一個(gè)公開的密碼了!

達(dá)文西看世界
2026-01-24 15:32:33
中國金花距離澳網(wǎng)決賽一步之遙,女單冠軍爭奪戰(zhàn)逐漸明朗

中國金花距離澳網(wǎng)決賽一步之遙,女單冠軍爭奪戰(zhàn)逐漸明朗

體育豐蘊(yùn)
2026-01-29 16:08:58
國產(chǎn)固態(tài)電池量產(chǎn)加速!數(shù)千萬新能源車主,恐成最大“接盤俠”?

國產(chǎn)固態(tài)電池量產(chǎn)加速!數(shù)千萬新能源車主,恐成最大“接盤俠”?

胖福的小木屋
2026-01-28 10:43:40
剖人心者終被食:亂世惡棍張彥澤的結(jié)局比電視上還慘

剖人心者終被食:亂世惡棍張彥澤的結(jié)局比電視上還慘

愛歷史
2026-01-28 10:07:37
價(jià)格大跳水!主力車型直降超15萬,中年男人的夢中豪車撐不住了?

價(jià)格大跳水!主力車型直降超15萬,中年男人的夢中豪車撐不住了?

財(cái)經(jīng)八卦
2026-01-28 20:05:03
女子用剁椒魚頭試探“網(wǎng)戀男友”,仍被騙68萬

女子用剁椒魚頭試探“網(wǎng)戀男友”,仍被騙68萬

中國日報(bào)
2026-01-29 12:00:59
編程門檻被壓到799美元?“那個(gè)拿著Mac Mini+Claude的「門外漢」,搶走了程序員3個(gè)月的活!”

編程門檻被壓到799美元?“那個(gè)拿著Mac Mini+Claude的「門外漢」,搶走了程序員3個(gè)月的活!”

CSDN
2026-01-27 18:10:04
阿富汗塔利班恢復(fù)奴隸制?

阿富汗塔利班恢復(fù)奴隸制?

孫曉宇
2026-01-28 14:18:17
貝森特再點(diǎn)卡尼:你這種人我見得多了,別搞事

貝森特再點(diǎn)卡尼:你這種人我見得多了,別搞事

觀察者網(wǎng)
2026-01-29 08:51:38
周總理逝世21年后,中國銀行核查賬目時(shí)發(fā)現(xiàn)他名下存有巨額存款,一番調(diào)查后揭開了背后的真相

周總理逝世21年后,中國銀行核查賬目時(shí)發(fā)現(xiàn)他名下存有巨額存款,一番調(diào)查后揭開了背后的真相

寄史言志
2026-01-17 16:37:15
無法復(fù)制的價(jià)值!95年喬丹第一次復(fù)出有多轟動(dòng)?魔術(shù)師曾為他下跪

無法復(fù)制的價(jià)值!95年喬丹第一次復(fù)出有多轟動(dòng)?魔術(shù)師曾為他下跪

禾三千體育
2026-01-29 16:42:32
要打就打痛!中國手段已升級,日本:中方不批準(zhǔn)駐重慶總領(lǐng)事任命

要打就打痛!中國手段已升級,日本:中方不批準(zhǔn)駐重慶總領(lǐng)事任命

墨蘭史書
2026-01-28 20:45:03
偉大的2-0!中國金花直通澳網(wǎng)決賽:解鎖2大成就,爭冠對手確定!

偉大的2-0!中國金花直通澳網(wǎng)決賽:解鎖2大成就,爭冠對手確定!

劉姚堯的文字城堡
2026-01-29 16:33:24
本期禁足名單分布:31名球員、6名教練、17名足協(xié)官員、1名裁判

本期禁足名單分布:31名球員、6名教練、17名足協(xié)官員、1名裁判

慢歌輕步謠
2026-01-29 14:03:07
陳永貴夫人宋玉林離世,葬禮之上郭鳳蓮致悼詞,現(xiàn)場人山人海滿是悲戚

陳永貴夫人宋玉林離世,葬禮之上郭鳳蓮致悼詞,現(xiàn)場人山人海滿是悲戚

文史明鑒
2026-01-22 17:37:12
金價(jià)創(chuàng)新高!黃金變現(xiàn)業(yè)務(wù)爆了

金價(jià)創(chuàng)新高!黃金變現(xiàn)業(yè)務(wù)爆了

環(huán)球網(wǎng)資訊
2026-01-29 11:28:09
能否逆轉(zhuǎn)銷量?曝特斯拉即將推出Model YL+,88度電池,續(xù)航800km

能否逆轉(zhuǎn)銷量?曝特斯拉即將推出Model YL+,88度電池,續(xù)航800km

凡兮說
2026-01-29 16:44:36
大S雕像揭幕儀式即將開啟,出席人員曝光!汪小菲有望上金寶山!

大S雕像揭幕儀式即將開啟,出席人員曝光!汪小菲有望上金寶山!

娛樂團(tuán)長
2026-01-29 12:26:42
再打下去,烏克蘭沒男人了!澤連斯基解禁,允許年輕男性出國避難

再打下去,烏克蘭沒男人了!澤連斯基解禁,允許年輕男性出國避難

史智文道
2026-01-29 16:22:57
阿森納全勝領(lǐng)銜 英超隊(duì)踢歐冠怎么就如此輕松?

阿森納全勝領(lǐng)銜 英超隊(duì)踢歐冠怎么就如此輕松?

體壇周報(bào)
2026-01-29 16:16:23
2026-01-29 17:23:00
Java精選
Java精選
一場永遠(yuǎn)也演不完的戲
1768文章數(shù) 3859關(guān)注度
往期回顧 全部

科技要聞

周亞輝的AI新賭局:國內(nèi)太卷 出海另起爐灶

頭條要聞

女大學(xué)生到東北游玩暈倒雪地凍傷 三根手指或面臨截肢

頭條要聞

女大學(xué)生到東北游玩暈倒雪地凍傷 三根手指或面臨截肢

體育要聞

詹姆斯哭了!騎士視頻致敬41歲超巨

娛樂要聞

張譯不再隱瞞!公開回應(yīng)退圈息影真相

財(cái)經(jīng)要聞

崔東樹:中國汽車未來年銷或達(dá)5000萬輛

汽車要聞

車長超5米還帶后輪轉(zhuǎn)向 比亞迪海豹08/海獅08將亮相

態(tài)度原創(chuàng)

本地
房產(chǎn)
藝術(shù)
公開課
軍事航空

本地新聞

云游中國|撥開云霧,巫山每幀都是航拍大片

房產(chǎn)要聞

萬科難眠夜:前董事長郁亮失聯(lián),三筆債券靠深鐵才通過展期

藝術(shù)要聞

梵高全集(高清350張)震撼……

公開課

李玫瑾:為什么性格比能力更重要?

軍事要聞

中國代表:支持伊朗國家穩(wěn)定 武力解決不了問題

無障礙瀏覽 進(jìn)入關(guān)懷版