Hibernate Validator校验
自定义注解
1、创建自定义annotation
/**
* <P>
* <B>Description: 校验注解</B>
* </P>
* Revision Trail: (Date/Author/Description)
* 2022/8/26 Ryan Huang CREATE
*
* @author Ryan Huang
* @version 1.0
*/
@Target({ METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = CheckValidator.class)
public @interface Check {
/**
* 错误信息
*/
String message() default "Format is error.";
/**
* 分组
*/
Class<?>[] groups() default {};
/**
* payload 属性: Bean Validation API 的使用者可以通过此属性来给约束条件指定严重级别. 这个属性并不被API自身所使用。
*/
Class<? extends Payload>[] payload() default {};
/**
* 是否允许为空
*/
boolean allowNull() default true;
/**
* 校验类型
*/
String value() default "";
/**
* 数组校验-该值是否存在于该数组中
*/
String[] values() default {};
}
2、自定义校验器
/**
* <P>
* <B>Description: 校验器</B>
* </P>
* Revision Trail: (Date/Author/Description)
* 2022/8/26 Ryan Huang CREATE
* <P>
* ConstraintValidator定义了两个泛型参数,
* 第一个是这个校验器所服务到标注类型(在我们的例子中即Dict),
* 第二个这个校验器所支持到被校验元素到类型 (即Object).
* </P>
* @author Ryan Huang
* @version 1.0
*/
public class CheckValidator implements ConstraintValidator<Check, Object> {
/**
* 注解
*/
private Check check;
/**
* 校验类型
*/
private String value;
/**
* 是否为空
*/
private boolean allowNull;
/**
* 数组校验-该值是否存在于该数组中
*/
private List<String> values;
@Override
public void initialize(Check check) {
this.check = check;
this.value = check.value();
this.allowNull = check.allowNull();
this.values = Arrays.asList(check.values());
}
@Override
public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
if(o == null && !allowNull){
return false;
}
if(StringUtils.isNotBlank(value)){
return valueValidation(o);
}else if(!values.isEmpty()){
return valuesValidation(o);
}
return false;
}
/**
* 检验该值是否存在于该数组
* @param obj 数据
* @return 是否存在
*/
private boolean valuesValidation(Object obj){
if(obj == null || values.isEmpty()){
return true;
}
return CollectionUtil.contains(values, obj);
}
/**
* 校验数据是否符合指定类型格式
* @param obj 数据
* @return 是否符合
*/
private boolean valueValidation(Object obj){
String data = obj == null ? null : obj.toString();
switch (value){
case CheckParameter.PHONE:
return PhoneUtil.isPhone(data);
case CheckParameter.MOBILE:
return PhoneUtil.isMobile(data);
case CheckParameter.IDENTITY_NUMBER:
return IdcardUtil.isValidCard(data);
default:
return false;
}
}
}
3、校验中使用到的常量
/**
* <P>
* <B>Description: 自定义校验常量</B>
* </P>
* Revision Trail: (Date/Author/Description)
* 2022/12/12 Ryan Huang CREATE
*
* @author Ryan Huang
* @version 1.0
*/
public class CheckParameter {
/**
* 座机号码+手机号码
*/
public static final String PHONE = "phone";
/**
* 手机号码
*/
public static final String MOBILE = "mobile";
/**
* 身份证号,支持18位、15位和港澳台的10位
*/
public static final String IDENTITY_NUMBER = "identityNumber";
}
自定义校验工具
/**
* <P>
* <B>Description: 校验工具</B>
* </P>
* Revision Trail: (Date/Author/Description)
* 2022/11/30 Ryan Huang CREATE
*
* @author Ryan Huang
* @version 1.0
*/
public class ValidateUtil {
/**
* 校验对象
* @param obj 需要校验的对象
* @return 错误信息
*/
public static Set<String> validator(Object obj){
Set<String> errorMessage = Sets.newHashSet();
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();
setConstraintViolationMessage(errorMessage, validator, obj);
return errorMessage;
}
/**
* 校验对象
* @param obj 需要校验的对象
* @param failFast 是否遇到一个失败就停止检查 true:是;false:否
* @return 错误信息
*/
public static Set<String> validator(Object obj, boolean failFast){
Set<String> errorMessage = Sets.newHashSet();
Validator validator = Validation.byProvider(HibernateValidator.class)
.configure()
.failFast(failFast)
.buildValidatorFactory()
.getValidator();
setConstraintViolationMessage(errorMessage, validator, obj);
return errorMessage;
}
/**
* 存储校验对象的错误信息
* @param errorMessage 错误信息
* @param validator 校验器
* @param obj 需要校验的对象
*/
public static void setConstraintViolationMessage(Set<String> errorMessage, Validator validator, Object obj){
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(obj);
if(constraintViolations != null && !constraintViolations.isEmpty()){
for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
errorMessage.add(constraintViolation.getMessage());
}
}
}
}