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註解,我們點進該註解可以看到
模仿該註解首先將元註解複製過去(不要@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下有一個配置文件我們可以找到該內容
現在我們也在自己的工程項目模仿着寫一個配置文件,在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**數組
所以現在我們創建一個類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();
}