序: 最近项目用到了自定义添加校验注解,记录一下过程
1. 校验注解
使用校验注解一般是在后端实体类上进行定义,对参数数据类型进行核查,例如邮箱地址是否正确,首字母大小写等,javax.validation.constraints提供了一系列注解使用,常用比如:
@Null 验证对象是否为null
@NotNull 验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty 检查约束元素是否为NULL或者是EMPTY.
但是难免有需要自定义一些数据类型,这时候可以采用方式有两种,第一种是通过设置@Pattern
中regexp
来定义,这种方法需要使用正则表达式,例如:
@Pattern(regexp = "^[a-zA-Z]$")//匹配首字符是否为字母
还有第二种方法便是通过自定义一个注解来实现数据的校验
2. 自定义校验注解
在这之前需要导入几个依赖:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
如果使用版本过高的话还需要导入
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b08</version>
</dependency>
在准备好依赖后,就可以开始正式定义注解了,下面用一个例子来示例,定义注解ListValue,判断参数只能是0或者1:
首先,创建注解文件,输入自定义名字即可
随后,定义元注解:
@Documented //表明这个注解应该被 javadoc工具记录
@Constraint(//自定义注解校验规则
validatedBy = { }
)
@Target({//定义注解使用范围
ElementType.METHOD, ElementType.FIELD,
ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR,
ElementType.PARAMETER, ElementType.TYPE_USE
})
@Retention(RetentionPolicy.RUNTIME) //注解持续时间,这个表示在jvm加载class文件之后,仍然存在
接下来是要对验证逻辑进行判断实现,自定义一个java文件ListValueConstraintValidator
,并且将ListValueConstraintValidator
定义在刚刚创建的元注解下
package com.dcy.mall.product.valid;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;
/**
* @author :@dcy
* @date :
* @description:
* @modified By:
* @version: $
*/
public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer> {
//存储自定义参数
private Set<Integer> set = new HashSet<>();
@Override
public void initialize(ListValue constraintAnnotation) {
int[] value = constraintAnnotation.value();
for (int i : value) {
set.add(i);//将传入定义参数存储,这里传入的是[0,1]
}
}
@Override
public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) {
return set.contains(integer);//判断传入的integer是否在set中并返回,如果不在则校验失败
}
}
注解定义完毕之后随后是对方法体定义
String message() default "{com.dcy.mall.api.valid.ListValue.message}";//定义消息
Class<?>[] groups() default {};//分组
Class<? extends Payload>[] payload() default {};
int[] value() default {};//传入数组
massage需要自定义,这里可以参考其他官方注解来进行自定义,在下图所示创建ValidationMessages.properties
文件
添加语句com.dcy.mall.api.valid.ListValue.message=必须提交指定的值 [0,1]
到此注解就能生效使用了,将其定义在需要使用参数上即可
验证:
这里好像有点乱码问题…