Java-Bean Validation後端校驗總結

Validation


Information resource:

SpringBoot Docs: 2.8.9. @ConfigurationProperties Validation

url: //docs.spring.io/spring-boot/docs/2.3.12.RELEASE/reference/html/spring-boot-features.html#boot-features

Spring Boot attempts to validate @ConfigurationProperties classes whenever they are annotated with Spring』s @Validated annotation. You can use JSR-303 javax.validation constraint annotations directly on your configuration class. To do so, ensure that a compliant JSR-303 implementation is on your classpath and then add constraint annotations to your fields, as shown in the following example:

每當使用 Spring 的 @Validated 注釋時,Spring Boot 都會嘗試驗證 @ConfigurationProperties 類。 可以直接在配置類上使用 JSR-303 javax.validation 約束注釋。 為此,請確保類路徑上有一個兼容的 JSR-303 實現,然後向欄位添加約束注釋,如以下示例所示:

@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {

    @NotNull
    private InetAddress remoteAddress;

    // ... getters and setters

}

You can also trigger validation by annotating the @Bean method that creates the configuration properties with @Validated.

還可以通過注釋使用@Validated 創建配置屬性的@Bean 方法來觸發驗證。

To ensure that validation is always triggered for nested properties, even when no properties are found, the associated field must be annotated with @Valid. The following example builds on the preceding AcmeProperties example:

為確保始終為嵌套屬性觸發驗證,即使未找到任何屬性,也必須使用 @Valid 注釋關聯欄位。 以下示例建立在前面的 AcmeProperties 示例之上:

@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {

    @NotNull
    private InetAddress remoteAddress;

    @Valid
    private final Security security = new Security();

    // ... getters and setters

    public static class Security {

        @NotEmpty
        public String username;

        // ... getters and setters
    }
}

JSR-303 Validation


JSR-303 是Java EE的一個子規範,官方參考實現Hibernate Validator

JSR-303 是一個數據驗證的規範,而Hibernate Validator則是實現了這一規範,可以使用註解的方式對Bean進行驗證,它的內部已經定義好了一系列的限制註解,只需將需要的註解標註在需要驗證的實體類的屬性上或者是對應的get方法上即可

JSR-303常用校驗規則

布爾檢查

註解 描述
@AssertFalse 被標註的對象是否為False
@AssertTrue 被標註的對象是否為True

空值檢查

註解 描述
@Null 驗證被標註的對象是否為NULL
@NotNull 驗證被標註的對象是否不為NULL
@NotBlank 驗證字元串是否非空,trim()後不為””,長度大於0
@NotEmpty 驗證被標註對象是否為非空

長度檢查

註解 描述
@Length(min,max) 驗證字元串長度是否在min,max範圍內
@Size(min,max) 驗證對象(Collection,String,Map,Array)是否在規定範圍內

日期檢查

註解 描述
@Past 驗證時間對象的值是否在當前時間之前
@Future 驗證時間對象的值是否在當前時間之後
@Pattern(regexp) 驗證字元串是否符合指定的正則表達式

數值檢查

註解 描述
@Email 驗證被標註對象是否為郵箱格式,NULL值不驗證
@Valid 關聯對象是數組或集合時,對其元素進行校驗
@Digits(integer,fraction) 驗證字元串是否是符合指定格式的數字,integer整數精度,fraction小數精度
@Min 驗證字元串是否是大於Min指定的最小值的數字
@Max 驗證字元串是否是小於Max指定的最大值的數字
@Range(min,max) 驗證元素是否在min,max範圍內

使用Hibernate Validator的Demo

Demo的項目結構:

pom.xml

<!-- 使用的是hibernate validator -->
<dependency>
        <groupId>org.hibernate.validator</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>${hibernate-validator.version}</version>
</dependency>

User(Bean)

/**
 * @Email 約束輸入郵件的格式
 * @NotBlank 指字元串使用trim()去掉前後空格後,不能夠為空
 */
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User implements Serializable {

    @NotBlank(message = "郵箱不能為空")
    @Email(message = "郵箱非法")
    private String userEmail;

    @NotBlank(message = "電話不能為空")
    @Pattern(regexp = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$",message = "手機號非法")
    private String userPhone;
}

UserController

/**
 * 以POST請求為例
 * @Validated 注釋類
 * @RequestBody 可傳Javabean類型
 * @RequestParam 傳單個參數
 * @Valid 修飾在Javabean類型前
 */
@RestController
@Validated
public class UserController {

    @RequestMapping(value = "/test",method = RequestMethod.POST)
    public boolean test(@RequestBody @Valid User user){
        return true;
    }

    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    public String hello(){
        return "hello,world";
    }
}

Rusult:Postman發個請求瞅瞅結果

  • 輸入正確格式的郵箱和手機

  • 輸入非法格式的郵箱

  • 輸入非法格式的手機號碼