使用validation校验表单参数

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;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值