1、校验两次密码相等
自定Equals注解实现校验两次密码相等
1.1、创建自定义注解Equals
@Target({ElementType.TYPE,ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EqualsValidator.class)
@Documented
public @interface Equals {
String message() default "不一致";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* 触发字段
*/
String triggerField();
/**
* 目标字段
*/
String targetField();
}
1.2、实现验证器
@Slf4j
public class EqualsValidator implements ConstraintValidator<Equals,Object> {
private String triggerField;
private String targetField;
@Override
public void initialize(Equals constraintAnnotation) {
this.triggerField = constraintAnnotation.triggerField();
this.targetField = constraintAnnotation.targetField();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
if (Objects.isNull(value)) {
return true;
}
try {
//springboot项目使用此方法获取字段值
BeanWrapperImpl beanWrapper = new BeanWrapperImpl(value);
Object triggerValue = beanWrapper.getPropertyValue(triggerField);
Object targetValue = beanWrapper.getPropertyValue(targetField);
return Objects.equals(triggerValue, targetValue);
} catch (Exception ex) {
log.error("EqualsValidator isValid error:{}", ex.getMessage(), ex);
return false;
}
}
}
1.3、应用
// 在class上使用注解
@Data
@Equals(triggerField = "confirmPassword",targetField = "password",message = "两次密码不一致")
public class RegisterParam implements Serializable {
private static final long serialVersionUID = 3352825675218895093L;
@NotBlank(message = "账户名不能为空")
private String account;
@NotBlank(message = "密码不能为空")
private String password;
@NotBlank(message = "确认密码不能为空")
private String confirmPassword;
}
2、字段动态校验
应用场景:表单中有类型字段,选择不同的类型对应的表单字段内容不一样,校验规则也不一样,例如个人和企业注册必填字段不一样,个人注册姓名和证件号必填,企业注册企业名和企业代码必填,可以通过继承DefaultGroupSequenceProvider
动态定义验证组来实现。
@Data
@GroupSequenceProvider(RegisterParam.RegisterGroupSequenceProvider.class)
public class RegisterParam implements Serializable {
private static final long serialVersionUID = 3352825675218895093L;
@NotBlank(message = "账户名不能为空")
private String account;
/**
* 类型(1个人、2企业)
*/
@Range(min = 1, max = 2, message = "类型(1个人、2企业)")
private Integer type;
@NotBlank(message = "原名不能为空", groups = {IfPerson.class})
private String realName;
@NotBlank(message = "证件号码不能为空",groups = {IfPerson.class})
private String idNo;
@NotBlank(message = "企业名称不能为空", groups = {IfEnt.class})
private String entName;
@NotBlank(message = "企业代码不能为空", groups = {IfEnt.class})
private String entCode;
private interface IfPerson {
}
private interface IfEnt {
}
public static class RegisterGroupSequenceProvider implements DefaultGroupSequenceProvider<RegisterParam> {
@Override
public List<Class<?>> getValidationGroups(RegisterParam registerParam) {
List<Class<?>> sequence = new ArrayList<>();
sequence.add(RegisterParam.class); //始终包含默认组
if (ObjectUtils.isNotEmpty(registerParam)) {
Integer paramType = registerParam.getType();
switch (paramType) {
case 1:
sequence.add(IfPerson.class);
break;
case 2:
sequence.add(IfEnt.class);
break;
}
}
return sequence;
}
}
}
3、在方法中校验对象字段
使用Validator中的validate方法在方法中校验对象的字段
3.1、定义帮助类
@Component
@RequiredArgsConstructor
public class ValidUtil {
private final Validator validator;
/**
* 校验实体,校验失败随机抛出一条失败信息
*
* @param t
* @param <T>
*/
public <T> void valid(T t, Class<?>... groups) {
Set<ConstraintViolation<T>> violations = validator.validate(t, groups);
if (!violations.isEmpty()) {
String errMsg = violations.stream().findFirst().map(ConstraintViolation::getMessage).get();
throw new ServerException(errMsg);
}
}
/**
* 校验实体,校验失败时抛出所有的失败信息,多条以"|"分割
*
* @param t
* @param <T>
*/
public <T> void validAll(T t, Class<?>... groups) {
Set<ConstraintViolation<T>> violations = validator.validate(t, groups);
if (!violations.isEmpty()) {
String errCollect = violations.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining("|"));
throw new ServerException(errCollect);
}
}
/**
* 校验实体,返回所有异常信息
*
* @param t
* @param <T>
*/
public <T> String validAllReturn(T t, Class<?>... groups) {
Set<ConstraintViolation<T>> violations = validator.validate(t, groups);
if (!violations.isEmpty()) {
String errCollect = violations.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining("|"));
return errCollect;
}
return null;
}
}
3.2 、应用
@AllArgsConstructor
public class Test {
private final ValidUtil validUtil;
public Boolean validTest(String jsonStr) {
TestParam param = JSONObject.parseObject(jsonStr, TestParam.class);
//校验
validUtil.valid(param);
return true;
}
}