在学习分布式项目时,做完前端的校验后,后端校验也是必不可少的,后端校验采用的是JSR303,在学完后端校验后,小生在此做下笔记,以后可能会再次用到
1、基本使用:
第一步:
导包(实体类需要用到的相关注解),并在实体类上写上需要验证的注解
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.2.0.Final</version>
</dependency>
相关注解如下:
在这里需要注意的是:
@NotNull
适用于基本数据类型(Integer,Long,Double等等),当 @NotNull 注解被使用在 String 类型的数据上,则表示该数据不能为 Null(但是可以为 Empty)
@NotBlank
适用于 String 类型的数据上,加了@NotBlank 注解的参数不能为 Null 且 trim() 之后 size > 0
@NotEmpty
适用于 String、Collection集合、Map、数组等等,加了@NotEmpty 注解的参数不能为 Null 或者 长度为 0
/**
* 品牌id
*/
@Null(message = "新增不能指定ID")
@NotNull(message = "修改必须指定ID")
@TableId
private Long brandId;
/**
* 品牌名
*/
@NotBlank(message = "品牌名不能为空")
private String name;
/**
* 品牌logo地址
*/
@URL(message = "logo必须是合法地址")
private String logo;
/**
* 介绍
*/
private String descript;
/**
* 显示状态[0-不显示;1-显示]
*/
@ListValue(values = {0,1})
private Integer showStatus;
/**
* 检索首字母
*/
@NotBlank
@Pattern(regexp = "^[a-zA-Z]$")
private String firstLetter;
/**
* 排序
*/
@NotNull
@Min(value = 0, message = "排序必须大于0")
private Integer sort;
第二步:
我们字段控制层是接收前端的数据,我们需要告知这些数据需要被校验,添加@Valid注解
@RequestMapping("/save")
public R save(@Valid @RequestBody BrandEntity brand){
brandService.save(brand);
return R.ok();
}
2、分组校验
对于有些字段,我们希望他在添加是不能为空,修改可以为空(或其他业务),这时我们可以采用分组校验
第一步:
准备几个分组的接口,不需要做任何实现,只是作为一个标识作用吧,可以如下:
第二步
在相关的字段上加上分组=哪个组(哪种业务)的注解,如下操作:
/**
* 品牌id
*/
@Null(message = "新增不能指定ID",groups = AddGroup.class)
@NotNull(message = "修改必须指定ID",groups = UpdateGroup.class)
@TableId
private Long brandId;
/**
* 品牌名
*/
@NotBlank(message = "品牌名不能为空",groups = {AddGroup.class,UpdateGroup.class})
private String name;
/**
* 品牌logo地址
*/
@NotBlank(groups = AddGroup.class)
@URL(message = "logo必须是合法地址" ,groups = {AddGroup.class,UpdateGroup.class})
private String logo;
/**
* 介绍
*/
private String descript;
/**
* 显示状态[0-不显示;1-显示]
*/
@ListValue(values = {0,1}, groups = {AddGroup.class, UpdateStatusGroup.class})
private Integer showStatus;
/**
* 检索首字母
*/
@NotBlank(groups = AddGroup.class)
@Pattern(regexp = "^[a-zA-Z]$", message = "检索首字母必须是一个字母",groups = {AddGroup.class,UpdateGroup.class})
private String firstLetter;
/**
* 排序
*/
@NotNull(groups = AddGroup.class)
@Min(value = 0, message = "排序必须大于0",groups = {AddGroup.class,UpdateGroup.class})
private Integer sort;
第三步:
将之前的@Valid注解替换为@Validated注解,@Validated源码可以知道可以填写一个数组,@Validated(组1,组2....)
3、自定义校验
在校验相关字段时,API中提供的验证并不能满足所有要求,这时候我们就需要自己来定义一些注解了
例如:
现在有一个字段:显示状态[0-不显示;1-显示],只能填写0或1,其他字段均不满足条件
第一步:
在字段上写上定义的注解,并配置注解信息,如下:
/**
* 显示状态[0-不显示;1-显示]
*/
@ListValue(values = {0,1}, groups = {AddGroup.class, UpdateStatusGroup.class})
private Integer showStatus;
我们自定义一个@Listvalue注解,复制其他注解里面的进行修改即可
@Documented
@Constraint(
validatedBy = {}
)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ListValue {
//com.gulimall.common.valid.ListValue.message是配置文件中的配置名
String message() default "{com.gulimall.common.valid.ListValue.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
int[] values() default {}; //这个是我们字段允许的值
}
message信息都写在ValidationMessages.properties文件中,于是我们自己定义一个ValidationMessages.properties文件,写想配置的一些信息:
com.gulimall.common.valid.ListValue.message=配置的提示信息
com.gulimall.common.valid.ListValue.message对应上图的message() default "{}"中的内容
第二步:
注解配置完成,我们需要自定义一个校验器,来判断@Listvalue注解中的values值是否满足
在@Listvalue注解中有一个@Constraint( validatedBy = {} ),看validatedBy 源码如下:
可以了解到,我们需要自定义一个 ConstraintValidator的一个实现类,写入@Constraint( validatedBy = {实现类} )即可
于是我们可以定义一个ListvalueConstraintValidator,如下:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
private Set<Integer> set = new HashSet<>();
@Override
public void initialize(ListValue constraintAnnotation) {
int[] values = constraintAnnotation.values();
for(int value: values){
set.add(value);
}
}
//判断是否成功
@Override
public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
return set.contains(value);
}
}
最后修改@Listvalue中的配置:
@Constraint( validatedBy = {ListValueConstraintValidator.class} )
自定义的配置完成,可以进行相关测试了!
JSR303后端校验的一些学习,还有许多不足,望见谅,希望帮助到大家!!!