javax.validation @Valid注解實現參數校驗


  在 RESTful 的接口服務中,存在各種各樣的請求參數。在跳入業務處理環節之前,通常會有一個基礎的數據驗證的機制,待驗證通過,結果無誤后,請求參數才會傳遞到正式的業務處理中。

maven 依賴引入

  Spring Boot項目中,Validation校驗需要引入的兩個包:

     <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.16.Final</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>

如何使用javax.validation @Valid注解

  Hibernate-Validator的主要使用方式是在Controller的請求參數加@Valid 注解,並且是“零配置”的,無需配置也可以使用。 @Valid 注解表示需要對這個對象的屬性進行驗證:

public String saveUser(@RequestBody **@Valid** User user) {...}

  既然是屬性驗證,那么就肯定會有驗證結果,驗證結果可以通過在請求參數那直接添加一個BindingResult變量來獲取。在 User類的屬性上打上如下注解:

import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;

/**
 * @author Wiener
 * @since 2021/11/7
 */
@Data
public class User {
    @NotBlank(
            message = "姓名不能為空"
    )
    @Length(
            message = "姓名最長為 {max}個字符"
            , min = 1
            , max = 20
    )
    private String name;

    @NotBlank(
            message = "密碼不能為空"
    )
    @Length(
            message = "密碼最少為{min}個字符,最長為 {max}個字符"
            , min = 8
            , max = 30
    )
    private String password;

     /** 年齡 */
    @NotNull(message = "請輸入年齡")
    @Range(message = "年齡大小范圍為 {min} 到 {max} 之間", min = 1, max = 150)
    public Integer age;
        @NotBlank
    @Size(max=32,message="address is null")
    private String address;
    
    /**
     * 當前時間不能為空(必填)
     */
    @NotBlank(message="當前時間不能為空")
    @DateTimeStr(format ="yyyy-MM-dd HH:mm:ss", message = "格式錯誤,正確格式為:yyyy-MM-dd HH:mm:ss")
    private String currentTime;
    

}

  當輸入不能滿足條件時,就會拋出異常,而后統一由異常中心處理。也可以用BindingResult,但是用了這個后就必須手動處理異常,侵入了正常的業務邏輯,並不推薦。

常用注解

  這兒介紹Hibernate和 javax.validation 包下的一些常用校驗注解。

@Null
限制只能為null

@NotNull
限制必須不為null

@AssertFalse
限制必須為false

@AssertTrue
限制必須為true

@DecimalMax(value)
限制必須為一個不大於指定值的數字

@DecimalMin(value)
限制必須為一個不小於指定值的數字

@Digits(integer,fraction)
限制必須為一個小數,且整數部分的位數不能超過integer,小數部分的位數不能超過fraction

@Future
限制必須是一個將來的日期

@Max(value)
限制必須為一個不大於指定值的數字

@Min(value)
限制必須為一個不小於指定值的數字

@Past
限制必須是一個過去的日期

@Pattern(value)
限制必須符合指定的正則表達式

@Size(max,min)
限制字符串長度必須在min到max之間

@Past
驗證注解的元素值(日期類型)比當前時間早

@NotEmpty
驗證注解的元素值不為null且不為空(字符串長度不為0、集合大小不為0)

@NotBlank
驗證注解的元素值不為空(不為null、去除首位空格后長度為0),不同於@NotEmpty,@NotBlank只應用於字符串且在比較時會去除字符串的空格

@Email
驗證注解的元素值是Email,也可以通過正則表達式和flag指定自定義的email格式

嵌套實體驗證和測試用例

  溫馨提示:實體類驗證只是針對該實體內第一層的屬性進行驗證,如果被驗證的實體類存在另一個實體類B,那么就需要在B類成員變量上加 @valid 注解。如在Student類中添加班級CurrentTimeDto類型的成員變量並校驗其屬性:

import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.io.Serializable;

@Data
public class Student implements Serializable {
    private static final long serialVersionUID = 5285725868010678653L;

    @NotNull(
            message = "姓名不能為空"
    )
    @Length(
            message = "姓名最長為 {max}個字符"
            , min = 1
            , max = 20
    )
    private String name;

    @NotNull(
            message = "密碼不能為空"
    )
    @Length(
            message = "密碼最少為{min}個字符,最長為 {max}個字符"
            , min = 8
            , max = 30
    )
    private String password;

    /** 年齡 */
    @NotNull(message = "請輸入年齡")
    @Range(message = "年齡大小范圍為 {min} 到 {max} 之間", min = 1, max = 150)
    public Integer age;
    @NotNull(message = "請輸入address")
    @Size(max=32,message="address is null")
    private String address;

    @Pattern(regexp = "\\d{3}-\\d{8}|\\d{4}-\\d{7}|\\d{11}", message = "手機號碼不正確")
    private String telephone;

    @Valid
    private CurrentTimeDto currentTimeDto;
}
import lombok.Data;

import javax.validation.constraints.NotBlank;
import java.io.Serializable;

@Data
public class CurrentTimeDto implements Serializable {

    private static final long serialVersionUID = -7831097421296635187L;
    /**
     * 當前時間不能為空(必填)
     */
    //設置時區為上海時區,時間格式自己據需求定。
//    @JsonFormat(pattern="yyyy-MM-dd",timezone = "GMT+8")

    @NotBlank(message="當前時間不能為空")
    private String currentTime;
}

  下面是兩個基於Student類的測試用例,在請求參數前加上 @Valid注解即開啟參數校驗:

   /**
     * 參數校驗結果從bindingResult中讀取
     * @param student
     * @param bindingResult
     * @return
     */
    @ApiOperation(value = "bindingResult")
    @PostMapping("/bindingResult")
    public Object bindingResult(@RequestBody @Valid Student student, BindingResult bindingResult) {
        System.out.println("bindingResult---" + student);
        if (bindingResult.getErrorCount() > 0) {
            return bindingResult.getFieldError();
        }
        return student;
    }
    /**
     * 參數校驗結果僅僅可以從日志中查看
     * @param student
     * @return
     */
    @ApiOperation(value = "validParam")
    @PostMapping("/validParam")
    public Object validParam(@RequestBody @Valid Student student) {
        System.out.println("validParam---" + student);
        return student;
    }

小結

  願各位新時代農民工不斷打破自己,提升自己,重塑自己,從而讓自己的職業和生活更加璀璨。


免責聲明!

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



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