SprinBoot使用JSR303的自定義校驗

1、什麼是JSR303

JSR-303 是 JAVA EE 6 中的一項子規範,叫做 Bean Validation,官方參考實現是Hibernate Validator。此實現與 Hibernate ORM 沒有任何關係。 JSR 303 用於對 Java Bean 中的字段的值進行驗證。Spring MVC 3.x 之中也大力支持 JSR-303,可以在控制器中對錶單提交的數據方便地驗證。
注:可以使用註解的方式進行驗證

2、如何在springboot使用JSR303自定義校驗

1、導入相關依賴

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>2.3.4.RELEASE</version>
</dependency>

2、編寫一個自定義註解

首先創建一個自定義註解ListValue(該例子完成自定義註解實現校驗提交的值必須是指定的值)

內容我們可以模仿自帶的@NotNull註解,我們點進該註解可以看到

springboot3 對應的Jasyp版本_#java

模仿該註解首先將元註解複製過去(不要@Repeatable)

因為我們的註解的作用的校驗只能提交指定的值,所以我們需要定義一個數組

那麼String message() default "{javax.validation.constraints.NotNull.message}";這個是什麼意思呢

idea雙擊shift搜索ValidationMessages.properties發現org\hibernate\validator\hibernate-validator\6.0.18.Final\hibernate-validator-6.0.18.Final.jar下有一個配置文件我們可以找到該內容

springboot3 對應的Jasyp版本_自定義_02

現在我們也在自己的工程項目模仿着寫一個配置文件,在resources目錄下創建ValidationMessages.properties,並編寫如下配置

com.huidu.common.valid.ListValue=必須提交指定的值

註解編寫大致內容如下

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
        validatedBy = {}
)
public @interface ListValue {


    String message() default "{com.huidu.common.valid.ListValue}";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };

    int[]  vals() default { };
}

3、編寫一個自定義校驗器

同樣,我們點進**@Constraint該註解,發現它是一個接口,並且是一個ConstraintValidator**數組

springboot3 對應的Jasyp版本_hibernate_03

所以現在我們創建一個類ListValueConstraintValidator實現ConstraintValidator接口,並實現相關的方法

接口的第一個泛型為註解,第二個泛型表示要校驗什麼類型的數據

initialize方法的constraintAnnotation參數可以獲取到註解vals的值,isValid的value是表單傳過來的值,我們創建一個set集合判斷註解上的值是否包含表單傳過來的值就可以進行校驗了

public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer> {
    private Set<Integer> set = new HashSet<>();

    @Override
    public void initialize(ListValue constraintAnnotation) {
        int[] vals = constraintAnnotation.vals();
        for (int val : vals) {
            set.add(val);
        }
    }

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        return set.contains(value);
    }
}

4、關聯自定義的校驗器和自定義的校驗註解

首先完善自定義編寫的註解,在validatedBy = {}添加校驗器類

@Constraint(
        validatedBy = {ListValueConstraintValidator.class}
)

現在我們在實體屬性上添加我們的自定義校驗註解(這裏使用的分組校驗就不一一概述了

@NotNull(groups = {AddGroup.class, UpdateStatusGroup.class})
@ListValue(vals={0,1},groups = {AddGroup.class, UpdateStatusGroup.class})
private Integer showStatus;


最後再在controller的方法體裏添加@Validated就能實現校驗了

@RequestMapping("/update/status")
public R updateStatus(@Validated({UpdateStatusGroup.class}) @RequestBody BrandEntity brand){
    brandService.updateById(brand);
    return R.ok();
}