在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    瞧瞧人家用SpringBoot寫的后端API接口,那叫一個優(yōu)雅

    日常工作中,我們開發(fā)接口時,一般都會涉及到參數(shù)校驗、異常處理、封裝結(jié)果返回等處理。如果每個后端開發(fā)在參數(shù)校驗、異常處理等都是各寫各的,沒有統(tǒng)一處理的話,代碼就不優(yōu)雅,也不容易維護(hù)。所以,作為一名合格的后端開發(fā)工程師,我們需要統(tǒng)一校驗參數(shù),統(tǒng)一異常處理、統(tǒng)一結(jié)果返回,讓代碼更加規(guī)范、可讀性更強(qiáng)、更容易維護(hù)。

    • 使用注解,優(yōu)雅進(jìn)行參數(shù)校驗
    • 統(tǒng)一結(jié)果返回
    • 統(tǒng)一異常處理
    • 嘮叨幾句

    1. 使用注解,統(tǒng)一參數(shù)校驗

    假設(shè)實現(xiàn)一個注冊用戶的功能,在controller 層,他會先進(jìn)行校驗參數(shù),如下:

    @RestController@RequestMappingpublic class UserController { @RequestMapping(“addUser”) public String addUser(UserParam userParam) { if (StringUtils.isEmpty(userParam.getUserName())) { return “用戶名不能為空”; } if (StringUtils.isEmpty(userParam.getPhone())) { return “手機(jī)號不能為空”; } if (userParam.getPhone().length() > 11) { return “手機(jī)號不能超過11”; } if (StringUtils.isEmpty(userParam.getEmail())) { return “郵箱不能為空”; } //省略其他參數(shù)校驗 //todo 插入用戶信息表 return “SUCCESS”; }}

    以上代碼有什么問題嘛?其實沒什么問題,就是校驗有點辣眼睛。正常的添加用戶業(yè)務(wù)還沒寫,參數(shù)校驗就一大堆啦。假設(shè)后來,又接了一個需求:編輯用戶信息。實現(xiàn)編輯用戶信息前,也是先校驗信息,如下:

    @RequestMapping(“editUser”)public String editUser(UserParam userParam) { if (StringUtils.isEmpty(userParam.getUserName())) { return “用戶名不能為空”; } if (StringUtils.isEmpty(userParam.getPhone())) { return “手機(jī)號不能為空”; } if (userParam.getPhone().length() > 11) { return “手機(jī)號不能超過11”; } if (StringUtils.isEmpty(userParam.getEmail())) { return “郵箱不能為空”; } //省略其他參數(shù)校驗 //todo 編輯用戶信息表 return “SUCCESS”;}

    我們可以使用注解的方式,來進(jìn)行參數(shù)校驗,這樣代碼更加簡潔,也方便統(tǒng)一管理。實際上, spring boot有個validation的組件,我們可以拿來即用。引入這個包即可:

    org.springframework.boot spring-boot-starter-validation

    引入包后,參數(shù)校驗就非常簡潔啦,如下:

    public class UserParam { @NotNull(message = “用戶名不能為空”) private String userName; @NotNull(message = “手機(jī)號不能為空”) @Max(value = 11) private String phone; @NotNull(message = “郵箱不能為空”) private String email;

    然后在UserParam參數(shù)對象中,加入@Validated注解哈,把錯誤信息接收到BindingResult對象,代碼如下:

    @RequestMapping(“addUser”) public String addUser(@Validated UserParam userParam, BindingResult result) { List fieldErrors = result.getFieldErrors(); if (!fieldErrors.isEmpty()) { return fieldErrors.get(0).getDefaultMessage(); } //todo 插入用戶信息表 return “SUCCESS”; }

    2. 接口統(tǒng)一響應(yīng)對象返回

    如果你在你們項目代碼中,看到controller 層報文返回結(jié)果,有這樣的:

    @RequestMapping(“/hello”)public String getStr(){ return “hello,test”;}//返回hello,test

    也有這樣的:

    @RequestMapping(“queryUser”)public UserVo queryUser(String userId) { return new UserVo(“666”, “test”);}//返回:{“userId”:”666″,”name”:”test”}

    顯然,如果接口返回結(jié)果不統(tǒng)一,前端處理就不方便,我們代碼也不好維護(hù)。再比如有的人喜歡用Result處理結(jié)果,有點人喜歡用Response處理結(jié)果,可以想象一下,這些代碼有多亂。

    所以作為后端開發(fā),我們項目的響應(yīng)結(jié)果,需要統(tǒng)一標(biāo)準(zhǔn)的返回格式。一般一個標(biāo)準(zhǔn)的響應(yīng)報文對象,都有哪些屬性呢?

    • code :響應(yīng)狀態(tài)
    • message :響應(yīng)結(jié)果描述
    • data:返回的數(shù)據(jù)

    響應(yīng)狀態(tài)碼一般用枚舉表示哈:

    public enum CodeEnum { /**操作成功**/ SUCCESS(“0000″,”操作成功”), /**操作失敗**/ ERROR(“9999″,”操作失敗”),; /** * 自定義狀態(tài)碼 **/ private String code; /**自定義描述**/ private String message; CodeEnum(String code, String message){ this.code = code; this.message = message; } public String getCode() { return code; } public String getMessage() { return message; }}

    因為返回的數(shù)據(jù)類型不是確定的,我們可以使用泛型,如下:

    /** * @author kevin * @param */public class BaseResponse { /** * 響應(yīng)狀態(tài)碼(0000表示成功,9999表示失敗 */ private String code; /** * 響應(yīng)結(jié)果描述 */ private String message; /** * 返回的數(shù)據(jù) */ private T data; /** * 成功返回 * @param data * @param * @return */ public static BaseResponse success(T data) { BaseResponse response= new BaseResponse(); response.setCode(CodeEnum.SUCCESS.getCode()); response.setMessage(CodeEnum.SUCCESS.getMessage()); response.setData(data); return response; } /** * 失敗返回 * @param code * @param message * @param * @return */ public static BaseResponse fail(String code, String message) { BaseResponse response = new BaseResponse(); response.setCode(code); response.setMessage(message); return response; } public void setCode(String code) { this.code = code; } public void setMessage(String message) { this.message = message; } public void setData(T data) { this.data = data; }}

    有了統(tǒng)一的響應(yīng)體,我們就可以優(yōu)化一下controller 層的代碼啦:

    @RequestMapping(“/hello”)public BaseResponse getStr(){ return BaseResponse.success(“hello,test”);}//output{“code”:”0000″,”message”:”操作成功”,”data”:”hello,test”}@RequestMapping(“queryUser”)public BaseResponse queryUser(String userId) { return BaseResponse.success(new UserVo(“666”, “test”));}//output{“code”:”0000″,”message”:”操作成功”,”data”:{“userId”:”666″,”name”:”test”}}

    3. 統(tǒng)一異常處理

    日常開發(fā)中,我們一般都是自定義統(tǒng)一的異常類,如下:

    public class BizException extends RuntimeException { private String retCode; private String retMessage; public BizException() { super(); } public BizException(String retCode, String retMessage) { this.retCode = retCode; this.retMessage = retMessage; } public String getRetCode() { return retCode; } public String getRetMessage() { return retMessage; }}

    在controller 層,很可能會有類似代碼:

    @RequestMapping(“/query”)public BaseResponse queryUserInfo(UserParam userParam) { try { return BaseResponse.success(userService.queryUserInfo(userParam)); } catch (BizException e) { //doSomething } catch (Exception e) { //doSomething } return BaseResponse.fail(CodeEnum.ERROR.getCode(),CodeEnum.ERROR.getMessage());}

    這塊代碼,沒什么問題哈,但是如果try…catch太多,不是很優(yōu)雅。

    可以借助注解@RestControllerAdvice,讓代碼更優(yōu)雅。@RestControllerAdvice是一個應(yīng)用于Controller層的切面注解,它一般配合@ExceptionHandler注解一起使用,作為項目的全局異常處理。我們來看下demo代碼哈。

    還是原來的UserController,和一個會拋出異常的userService的方法,如下:

    @RestControllerpublic class UserController { @Autowired private UserService userService; @RequestMapping(“/query”) public BaseResponse queryUserInfo1(UserParam userParam) { return BaseResponse.success(userService.queryUserInfo(userParam)); }}@Servicepublic class UserServiceImpl implements UserService { //拋出異常 @Override public UserVo queryUserInfo(UserParam userParam) throws BizException { throw new BizException(“6666”, “測試異常類”); }}

    我們再定義一個全局異常處理器,用@RestControllerAdvice注解,如下:

    @RestControllerAdvice(annotations = RestController.class)public class ControllerExceptionHandler {}

    我們有想要攔截的異常類型,比如想攔截BizException類型,就新增一個方法,使用@ExceptionHandler注解修飾,如下:

    @RestControllerAdvice(annotations = RestController.class)public class ControllerExceptionHandler { @ExceptionHandler(BizException.class) @ResponseBody public BaseResponse handler(BizException e) { System.out.println(“進(jìn)入業(yè)務(wù)異常”+e.getRetCode()+e.getRetMessage()); return BaseResponse.fail(CodeEnum.ERROR.getCode(), CodeEnum.ERROR.getMessage()); }}

    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
    用戶投稿
    上一篇 2022年6月21日 09:05
    下一篇 2022年6月21日 09:05

    相關(guān)推薦

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時間:周一至周五,10:30-18:30,節(jié)假日休息