Hibernate Validator 第25篇:多个字段的联合约束-条件结果约束

本文详细介绍了如何在Hibernate Validator中实现多个字段的联合约束,特别是条件结果约束。当fieldA等于特定值(如"22")时,fieldB必须满足相应的条件(如"33")。此外,还探讨了如何在一个类上添加多个注解以实现多个条件结果的验证,并展示了相关的约束和校验器代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多个字段的联合约束-条件结果约束

1. 功能

  • 实现了一个请求类中,两个字段:fieldA,fieldB。当fieldA == “22”时,fieldB值必须是“33”功能。
  • fieldB的值是字符串数字,只要是数组中的一个值即可
  • fieldA的值是一个字符串,作为条件,当fieldA满足条件时,才会比较fieldB
  • 可以在一个类上添加多个注解,实现多个条件结果

2. 使用举例

@ConditionStringResultStringConstraint.List({
		@ConditionStringResultStringConstraint(conditionName = "fieldA", resultName="fieldB", conditionValue = "22", resultValue = {"33"}),
		@ConditionStringResultStringConstraint(conditionName = "fieldA", resultName="fieldB", conditionValue = "mm", resultValue = {"nn"})

})
public class DemoRequest {

		private String fieldA;
		
		private String fieldB;
		
		getter
		setter

}

  • 当fieldA == “22”时,fieldB必须等于“33”
  • 当fieldA == “mm”时,fieldB必须等于“nn”

3. 约束代码


import ConditionStringResultStringConstraintValidator;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 类中两个字段的联合约束:条件结果约束
 * 1. 当condition字段的值满足约束的时候,才会继续比较result的值的约束
 *
 * @author zhazha
 * @date 2020-07-08
 */
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ConditionStringResultStringConstraintValidator.class)
@Documented
public @interface ConditionStringResultStringConstraint {

    String message() default "{message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    /**
     * 条件属性的名字
     */
    String conditionName();

    /**
     * 结果属性的名字
     */
    String resultName();

    /**
     * 条件属性的值
     */
    String conditionValue();

    /**
     * 结果属性的值
     */
    String[] resultValue();


    @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @interface List {
        ConditionStringResultStringConstraint[] value();
    }

}

4. 校验器代码

/**
 * @author zhazha
 * @date 2021/7/8
 */
public class ConditionStringResultStringConstraintValidator
        implements ConstraintValidator<ConditionStringResultStringConstraint, Object> {

    /**
     * 条件属性名字
     */
    private String conditionName;
    /**
     * 结果属性名字
     */
    private String resultName;
    /**
     * 条件属性值
     */
    private String conditionValue;
    /**
     * 结果属性值
     */
    private Set<String> resultValueSet;

    @Override
    public void initialize(ConditionStringResultStringConstraint conditionResult) {
        this.conditionName = conditionResult.conditionName();
        this.resultName = conditionResult.resultName();

        this.conditionValue = conditionResult.conditionValue();
        this.resultValueSet = new HashSet<>(Arrays.asList(conditionResult.resultValue()));
    }

    @Override
    public boolean isValid(Object obj, ConstraintValidatorContext context) {
        try {
            // key为空
            if (StringUtils.isBlank(this.conditionName) || StringUtils.isBlank(this.resultName)) {
                return false;
            }
            // value 为空
            if (StringUtils.isBlank(this.conditionValue) || CollectionUtils.isEmpty(this.resultValueSet)) {
                return false;
            }

            final String conditionFieldValue = BeanUtils.getProperty(obj, this.conditionName);
            // 条件不成立,则此约束不进入
            if (!StringUtils.equals(this.conditionValue, conditionFieldValue)) {
                return true;
            }
            // 条件进入,则会进入此校验
            final String resultFieldValue = BeanUtils.getProperty(obj, this.resultName);
            if (!this.resultValueSet.contains(resultFieldValue)) {
                return false;
            }

        } catch (Throwable t) {
            return false;
        }
        return true;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值