<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SpringBoot使用@Valid注解+Exception全局處理器優(yōu)雅處理參數(shù)驗(yàn)證

          共 6643字,需瀏覽 14分鐘

           ·

          2022-06-28 00:50

          目錄

          一、為什么使用 @Valid 來(lái)驗(yàn)證參數(shù)

          二、@Valid 注解的作用

          三、@Valid 的相關(guān)注解

          四、使用 @Valid 進(jìn)行參數(shù)校驗(yàn)步驟

          • 實(shí)體類(lèi)中添加 @Valid 相關(guān)注解

          • 接口類(lèi)中添加 @Valid 注解

          • 全局異常處理類(lèi)中處理 @Valid 拋出的異常

          五、SpringBoot 中使用 @Valid 示例

          • Maven 引入相關(guān)依賴(lài)

          • 自定義個(gè)異常類(lèi)

          • 自定義響應(yīng)枚舉類(lèi)

          • 自定義響應(yīng)對(duì)象類(lèi)

          • 自定義實(shí)體類(lèi)中添加 @Valid 相關(guān)注解

          • Controller 中添加 @Valid 注解

          • 全局異常處理

          • 啟動(dòng)類(lèi)

          • 示例測(cè)試

          相關(guān)地址:

          Spring Servlet 文檔:
          https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/web/servlet示例項(xiàng)目 Github:https://github.com/my-dlq/blog-example/tree/master/springboot/springboot-filter-example系統(tǒng)環(huán)境:

          Jdk 版本:jdk 8

          SpringBoot 版本:2.2.1.RELEASE

          一、為什么使用 @Valid 來(lái)驗(yàn)證參數(shù)

          在平常通過(guò) Spring 框架寫(xiě)代碼時(shí)候,會(huì)經(jīng)常寫(xiě)接口類(lèi),相信大家對(duì)該類(lèi)的寫(xiě)法非常熟悉。在寫(xiě)接口時(shí)經(jīng)常要寫(xiě)效驗(yàn)請(qǐng)求參數(shù)邏輯,這時(shí)候我們會(huì)常用做法是寫(xiě)大量的 if 與 if else 類(lèi)似這樣的代碼來(lái)做判斷,如下:

          這樣的代碼如果按正常代碼邏輯來(lái)說(shuō),是沒(méi)有什么問(wèn)題的,不過(guò)按優(yōu)雅來(lái)說(shuō),簡(jiǎn)直糟糕透了。不僅不優(yōu)雅,而且如果存在大量的驗(yàn)證邏輯,這會(huì)使代碼看起來(lái)亂糟糟,大大降低代碼可讀性,那么有沒(méi)有更好的方法能夠簡(jiǎn)化這個(gè)過(guò)程呢?

          答案當(dāng)然是有,推薦的是使用 @Valid 注解來(lái)幫助我們簡(jiǎn)化驗(yàn)證邏輯。

          二、@Valid 注解的作用

          注解 @Valid 的主要作用是用于數(shù)據(jù)校驗(yàn),可以在定義的實(shí)體中的屬性上,添加不同的注解來(lái)完成不同的校驗(yàn)規(guī)則,而在接口類(lèi)中的接收數(shù)據(jù)參數(shù)中添加 @valid 注解,這時(shí)你的實(shí)體將會(huì)開(kāi)啟一個(gè)校驗(yàn)的功能。

          三、@Valid 的相關(guān)注解

          下面是 @Valid 相關(guān)的注解,在實(shí)體類(lèi)中不同的屬性上添加不同的注解,就能實(shí)現(xiàn)不同數(shù)據(jù)的效驗(yàn)功能。

          四、使用 @Valid 進(jìn)行參數(shù)校驗(yàn)步驟

          整個(gè)過(guò)程如下圖所示,用戶(hù)訪(fǎng)問(wèn)接口,然后進(jìn)行參數(shù)效驗(yàn),因?yàn)?@Valid 不支持平面的參數(shù)效驗(yàn)(直接寫(xiě)在參數(shù)中字段的效驗(yàn))所以基于 GET 請(qǐng)求的參數(shù)還是按照原先方式進(jìn)行效驗(yàn),而 POST 則可以以實(shí)體對(duì)象為參數(shù),可以使用 @Valid 方式進(jìn)行效驗(yàn)。如果效驗(yàn)通過(guò),則進(jìn)入業(yè)務(wù)邏輯,否則拋出異常,交由全局異常處理器進(jìn)行處理。

          1、實(shí)體類(lèi)中添加 @Valid 相關(guān)注解

          使用 @Valid 相關(guān)注解非常簡(jiǎn)單,只需要在參數(shù)的實(shí)體類(lèi)中屬性上面添加如 @NotBlank、@Max、@Min 等注解來(lái)對(duì)該字段進(jìn)限制,如下:

          User:

          如果是嵌套的實(shí)體對(duì)象,則需要在最外層屬性上添加 @Valid 注解:

          User:

          UserInfo:

          2、接口類(lèi)中添加 @Valid 注解

          在 Controller 類(lèi)中添加接口,POST 方法中接收設(shè)置了 @Valid 相關(guān)注解的實(shí)體對(duì)象,然后在參數(shù)中添加 @Valid 注解來(lái)開(kāi)啟效驗(yàn)功能,需要注意的是, @Valid 對(duì) Get 請(qǐng)求中接收的平面參數(shù)請(qǐng)求無(wú)效,稍微略顯遺憾。

          3、全局異常處理類(lèi)中處理 @Valid 拋出的異常

          最后,我們寫(xiě)一個(gè)全局異常處理類(lèi),然后對(duì)接口中拋出的異常進(jìn)行處理,而 @Valid 配合 Spring 會(huì)拋出
          MethodArgumentNotValidException 異常,這里我們需要對(duì)該異常進(jìn)行處理即可。

          五、SpringBoot 中使用 @Valid 示例

          1、Maven 引入相關(guān)依賴(lài)

          Maven 引入 SpringBoot 相關(guān)依賴(lài),這里引入了 Lombok 包來(lái)簡(jiǎn)化開(kāi)發(fā)過(guò)程。

          2、自定義個(gè)異常類(lèi)

          自定義個(gè)異常類(lèi),方便我們處理 GET 請(qǐng)求(GET 請(qǐng)求參數(shù)中一般是沒(méi)有實(shí)體對(duì)象的,所以不能使用 @Valid),當(dāng)請(qǐng)求驗(yàn)證失敗時(shí),手動(dòng)拋出自定義異常,交由全局異常處理。

          3、自定義響應(yīng)枚舉類(lèi)

          定義一個(gè)返回信息的枚舉類(lèi),方便我們快速響應(yīng)信息,不必每次都寫(xiě)返回消息和響應(yīng)碼。

          4、自定義響應(yīng)對(duì)象類(lèi)

          創(chuàng)建用于返回調(diào)用方的響應(yīng)信息的實(shí)體類(lèi)。

          5、自定義實(shí)體類(lèi)中添加 @Valid 相關(guān)注解

          下面將創(chuàng)建用于 POST 方法接收參數(shù)的實(shí)體對(duì)象,里面添加 @Valid 相關(guān)驗(yàn)證注解,并在注解中添加出錯(cuò)時(shí)的響應(yīng)消息。

          User

          UserInfo

          6、Controller 中添加 @Valid 注解

          接口類(lèi)中添加 GET 和 POST 方法的兩個(gè)接口用于測(cè)試,其中 POST 方法以上面創(chuàng)建的 Uer 實(shí)體對(duì)象接收參數(shù),并使用 @Valid,而 GET 請(qǐng)求一般接收參數(shù)較少,所以使用正常判斷邏輯進(jìn)行參數(shù)效驗(yàn)。

          7、全局異常處理

          這里創(chuàng)建一個(gè)全局異常處理類(lèi),方便統(tǒng)一處理異常錯(cuò)誤信息。里面添加了不同異常處理的方法,專(zhuān)門(mén)用于處理接口中拋出的異常信。

          import club.mydlq.valid.entity.ResponseResult;import club.mydlq.valid.enums.ResultEnum;import club.mydlq.valid.exception.ParamaErrorException;import lombok.extern.slf4j.Slf4j;import org.springframework.http.HttpStatus;import org.springframework.http.converter.HttpMessageNotReadableException;import org.springframework.util.StringUtils;import org.springframework.validation.BindingResult;import org.springframework.validation.FieldError;import org.springframework.validation.ObjectError;import org.springframework.web.bind.MethodArgumentNotValidException;import org.springframework.web.bind.MissingServletRequestParameterException;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseStatus;import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.List;@Slf4j@RestControllerAdvice("club.mydlq.valid")public class GlobalExceptionHandler {    /**
          * 忽略參數(shù)異常處理器
          *
          * @param e 忽略參數(shù)異常
          * @return ResponseResult
          */

          @ResponseStatus(HttpStatus.BAD_REQUEST)
          @ExceptionHandler(MissingServletRequestParameterException.class)
          public ResponseResult parameterMissingExceptionHandler(MissingServletRequestParameterException e) {
          log.error("", e); return new ResponseResult(ResultEnum.PARAMETER_ERROR.getCode(), "請(qǐng)求參數(shù) " + e.getParameterName() + " 不能為空");
          } /**
          * 缺少請(qǐng)求體異常處理器
          *
          * @param e 缺少請(qǐng)求體異常
          * @return ResponseResult
          */

          @ResponseStatus(HttpStatus.BAD_REQUEST)
          @ExceptionHandler(HttpMessageNotReadableException.class)
          public ResponseResult parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) {
          log.error("", e); return new ResponseResult(ResultEnum.PARAMETER_ERROR.getCode(), "參數(shù)體不能為空");
          } /**
          * 參數(shù)效驗(yàn)異常處理器
          *
          * @param e 參數(shù)驗(yàn)證異常
          * @return ResponseInfo
          */

          @ResponseStatus(HttpStatus.BAD_REQUEST)
          @ExceptionHandler(MethodArgumentNotValidException.class)
          public ResponseResult parameterExceptionHandler(MethodArgumentNotValidException e) {
          log.error("", e); // 獲取異常信息
          BindingResult exceptions = e.getBindingResult(); // 判斷異常中是否有錯(cuò)誤信息,如果存在就使用異常中的消息,否則使用默認(rèn)消息
          if (exceptions.hasErrors()) {
          List<ObjectError> errors = exceptions.getAllErrors(); if (!errors.isEmpty()) { // 這里列出了全部錯(cuò)誤參數(shù),按正常邏輯,只需要第一條錯(cuò)誤即可
          FieldError fieldError = (FieldError) errors.get(0); return new ResponseResult(ResultEnum.PARAMETER_ERROR.getCode(), fieldError.getDefaultMessage());
          }
          } return new ResponseResult(ResultEnum.PARAMETER_ERROR);
          } /**
          * 自定義參數(shù)錯(cuò)誤異常處理器
          *
          * @param e 自定義參數(shù)
          * @return ResponseInfo
          */

          @ResponseStatus(HttpStatus.BAD_REQUEST)
          @ExceptionHandler({ParamaErrorException.class})
          public ResponseResult paramExceptionHandler(ParamaErrorException e) {
          log.error("", e); // 判斷異常中是否有錯(cuò)誤信息,如果存在就使用異常中的消息,否則使用默認(rèn)消息
          if (!StringUtils.isEmpty(e.getMessage())) { return new ResponseResult(ResultEnum.PARAMETER_ERROR.getCode(), e.getMessage());
          } return new ResponseResult(ResultEnum.PARAMETER_ERROR);
          }

          }

          8、啟動(dòng)類(lèi)

          9、示例測(cè)試

          下面將針對(duì)上面示例中設(shè)置的兩種接口進(jìn)行測(cè)試,分別來(lái)驗(yàn)證參數(shù)效驗(yàn)功能。

          || - 測(cè)試接口 /user/{username}

          使用 GET 方法請(qǐng)求地址
          http://localhost:8080/user?username=test 時(shí),返回信息:

          {
              "code"1000,
              "msg""請(qǐng)求成功"}

          當(dāng)不輸入?yún)?shù),輸入地址
          http://localhost:8080/user 時(shí),返回信息:

          {
              "code"1001,
              "msg""請(qǐng)求參數(shù) username 不能為空"}

          可以看到在執(zhí)行 GET 請(qǐng)求,能夠正常按我們?nèi)之惓L幚砥髦械脑O(shè)置處理異常信息。

          || - 測(cè)試接口 /user

          (1)、使用 POST 方法發(fā)起請(qǐng)求,首先進(jìn)行不加 JSON 請(qǐng)求體來(lái)對(duì)
          http://localhost:8080/user 地址進(jìn)行請(qǐng)求,返回信息:

          {
              "code"1001,
              "msg""參數(shù)體不能為空"}

          (2)、輸入部分參數(shù)進(jìn)行測(cè)試。

          請(qǐng)求內(nèi)容:

          {
           "username":"test",
           "password":"123"}

          返回信息:

          {
              "code"1001,
              "msg""userinfo不能為空"}

          (3)、輸入完整參數(shù),且設(shè)置 age > 18 時(shí),進(jìn)行測(cè)試。

          {
           "username":"111",
           "password":"sa",
            "userInfo":{
              "age":19,
              "gender":"男"  }
          }

          返回信息:

          {
              "code"1001,
              "msg""不能超過(guò)18歲"}

          可以看到在執(zhí)行 POST 請(qǐng)求,也能正常按我們?nèi)之惓L幚砥髦械脑O(shè)置處理異常信息,且提示信息為我們?cè)O(shè)置在實(shí)體類(lèi)中的 Message。


          END


          推薦閱讀

          一鍵生成Springboot & Vue項(xiàng)目!【畢設(shè)神器】

          Java可視化編程工具系列(一)

          Java可視化編程工具系列(二)


          順便給大家推薦一個(gè)GitHub項(xiàng)目,這個(gè) GitHub 整理了上千本常用技術(shù)PDF,絕大部分核心的技術(shù)書(shū)籍都可以在這里找到,

          GitHub地址:https://github.com/javadevbooks/books

          電子書(shū)已經(jīng)更新好了,你們需要的可以自行下載了,記得點(diǎn)一個(gè)star,持續(xù)更新中..




          瀏覽 41
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  男女做事网站 | 国产做受 高潮游戏视频 | a√在线播放 | 操逼操逼操逼操逼操逼操逼操逼操逼 | 色九九色九九色九九 |