springboot的入參校驗--validation


參數校驗是非常重要的一個環節,嚴格的參數校驗會減少很多bug,增加接口的安全性。也會減少對接時不必要的溝通。

實現方式

​ 使用@Validated注解配合參數校驗注解,如:@NotEmpty對參數進行校驗。然后對拋出的異常ControllerAdvice進行捕獲然后調整輸出數據。

Controller

@RestController
public class TestController {

    /**
     * 表單請求
     * @param form 請求參數
     * @return 響應數據
     */
    @PostMapping("/formRequest")
    public ResultVo formRequest(@Validated RequestForm form){
        return ResultVoUtil.success(form);
    }

    /**
     * JSON請求
     * @param form 請求參數
     * @return 響應數據
     */
    @PostMapping("/jsonRequest")
    public ResultVo jsonRequest(@RequestBody @Validated RequestForm form){
        return ResultVoUtil.success(form);
    }

}

RequestForm

@Data
public class RequestForm {

    @NotEmpty(message = "姓名不能為空")
    private String name;

    @Min(value = 1 , message = "年齡不能小於1歲")
    private Integer age;

    @NotEmpty(message = "性別不能為空")
    private Integer sex;

}

當不傳參數進行訪問接口時,會返回一大堆錯誤,我們需要ControllerAdvice規范異常返回信息

ControllerAdvice

@Slf4j
@RestControllerAdvice
public class ControllerAdvice {

    /**
     * 攔截表單參數校驗
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler({BindException.class})
    public ResultVo bindException(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        return ResultVoUtil.error(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
    }
    
    /**
     * 攔截JSON參數校驗 多個錯誤只輸出一個
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultVo bindException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        return ResultVoUtil.error(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
    }
    
     /**
     * validator注解校驗返回 攔截JSON參數校驗
     * @param ex
     * @return
   	 * 這個是將所有的錯誤進行遍歷輸出
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultVo bindException(MethodArgumentNotValidException ex) {
        System.out.println("----攔截JSON參數校驗-----");
        BindingResult bindingResult = ex.getBindingResult();
        StringBuilder errorMessage = new StringBuilder(bindingResult.getFieldErrors().size() * 16);
//        errorMessage.append("Invalid Request:");
        for (int i = 0; i < bindingResult.getFieldErrors().size(); i++) {
            if (i > 0) {
                errorMessage.append(", ");
            }
            FieldError fieldError = bindingResult.getFieldErrors().get(i);
            errorMessage.append(fieldError.getField());
            errorMessage.append(": ");
            errorMessage.append(fieldError.getDefaultMessage());
        }
        return ResultVo.badError(errorMessage.toString());
    }
     */

}

常用校驗注解

注解 運行時檢查
@AssertFalse 被注解的元素必須為false
@AssertTrue 被注解的元素必須為true
@DecimalMax(value) 被注解的元素必須為一個數字,其值必須小於等於指定的最小值
@DecimalMin(Value) 被注解的元素必須為一個數字,其值必須大於等於指定的最小值
@Digits(integer=, fraction=) 被注解的元素必須為一個數字,其值必須在可接受的范圍內
@Future 被注解的元素必須是日期,檢查給定的日期是否比現在晚
@Max(value) 被注解的元素必須為一個數字,其值必須小於等於指定的最小值
@Min(value) 被注解的元素必須為一個數字,其值必須大於等於指定的最小值
@NotNull 被注解的元素必須不為null
@Null 被注解的元素必須為null
@Past(java.util.Date/Calendar) 被注解的元素必須過去的日期,檢查標注對象中的值表示的日期比當前早
@Pattern(regex=, flag=) 被注解的元素必須符合正則表達式,檢查該字符串是否能夠在match指定的情況下被regex定義的正則表達式匹配
@Size(min=, max=) 被注解的元素必須在制定的范圍(數據類型:String, Collection, Map and arrays)
@Valid 遞歸的對關聯對象進行校驗, 如果關聯對象是個集合或者數組, 那么對其中的元素進行遞歸校驗,如果是一個map,則對其中的值部分進行校驗
@CreditCardNumber 對信用卡號進行一個大致的驗證
@Email 被注釋的元素必須是電子郵箱地址
@Length(min=, max=) 被注解的對象必須是字符串的大小必須在制定的范圍內
@NotBlank 被注解的對象必須為字符串,不能為空,檢查時會將空格忽略
@NotEmpty 被注釋的對象必須為空(數據:String,Collection,Map,arrays)
@Range(min=, max=) 被注釋的元素必須在合適的范圍內 (數據:BigDecimal, BigInteger, String, byte, short, int, long and 原始類型的包裝類 )
@URL(protocol=, host=, port=, regexp=, flags=) 被注解的對象必須是字符串,檢查是否是一個有效的URL,如果提供了protocol,host等,則該URL還需滿足提供的條件

案例

@Data
public class ExampleForm {

    @NotEmpty(message = "姓名不能為空")
    @Length(min = 1 , max = 10 , message = "名字長度1~10")
    private String name;

    @Range(min = 1 , max = 99 , message = "年齡范圍在1~99歲")
    private Integer age;

    @Pattern(regexp = "^[1][3,4,5,7,8][0-9]{9}$" , message = "電話號碼有誤")
    private String phone;

    @Email(message = "郵箱格式有誤")
    private String email;

    @Valid
    @Size(min = 1 ,max =  10 , message = "列表中的元素數量為1~10")
    private List<RequestForm> requestFormList;

    @Future(message = "開始時間必須大於當前時間")
    private Date beginTime;
    
}

實現嵌套驗證

在實際的開發中,前台會后台傳遞一個list,我們不僅要限制每次請求list內的個數,同時還要對list內基本元素的屬性值進行校驗。這個時候就需要進行嵌套驗證了,實現的方式很簡單。在list上添加@Vaild就可以實現了。

@Data
public class JsonRequestForm {
    
    @Vaild
    @Size(min = 1 ,max =  10 , message = "列表中的元素數量為1~10")
    private List<RequestForm> requestFormList;
    
}

@NotNull、@NotBlank、@NotEmpty的區別

@NotNull
適用於基本數據類型(Integer,Long,Double等等),當 @NotNull 注解被使用在 String 類型的數據上,則表示該數據不能為 Null(但是可以為 Empty)
@NotBlank
適用於 String 類型的數據上,加了@NotBlank 注解的參數不能為 Null 且 trim() 之后 size > 0
@NotEmpty
適用於 String、Collection集合、Map、數組等等,加了@NotEmpty 注解的參數不能為 Null 或者 長度為 0

在使用這些注解的時候,還需要注意一點(注:否則會造成注解無效哦!!),那就是在Controller 層定義方法的時候在參數位置上加上 @Valid(javax.validation.Valid) 注解!!!
原文鏈接:https://blog.csdn.net/yangchao1125/article/details/107323177/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM