【问题标题】:Different validations on same field based on active validation group基于活动验证组对同一字段的不同验证
【发布时间】:2017-04-20 00:19:17
【问题描述】:

我正在尝试使用Hibernate Validator 验证请求对象。

作为一个简单的示例,假设我要验证的对象的类具有 B bObj 字段,其中 B 是另一个具有 String name 字段的类。

因此,我实现了我自己的自定义 Constraint Annotations 链接到自定义 MyValidator implements ConstraintValidator 类。

DTO 类

@AclassValidate(groups = {Operations.Insert.class, Operations.Update.class javax.validation.groups.Default.class})
public class A {

    @BclassValidate(groups = {Operations.Insert.class, Operations.Update.class})
    private B bObj;

    // setters, getters
}

我的端点方法签名(调用验证器并设置活动组):

@PostMapping("/test")
public A createA(
        @Validated(value = Operations.Insert.class) 
        // @Validated(value = Operations.Update.class) 
        @RequestBody A a
)

我的验证器类

public class BclassValidator implements ConstraintValidator<BclassValidate, B> {

    public void initialize(BclassValidate constraintAnnotation) {
    }

    public boolean isValid(B b, ConstraintValidatorContext constraintContext) {

        boolean valid = true;

        // Get active group here
        activeGroup = ..?
        if (activeGroup == Operations.Insert.class) {
            // check if b.getName() equals to "John"
        }
        else if (activeGroup == Operations.Update.class) {
            // check if b.getName() equals to "Doe"
        }

        return valid;
    }
}

我想要实现的是根据活动组对同一字段应用不同的验证。活动组是组,设置在@Validated 注释。问题是如何检索活动组以根据其值应用不同的验证?

【问题讨论】:

    标签: spring hibernate hibernate-validator validationgroup


    【解决方案1】:

    您无法从约束验证器中获取当前已验证的组。

    相反,您应该将约束拆分为多个约束,在您的情况下,一个用于插入,一个用于更新。然后,您可以将这些单独的约束分别分配给一个验证组。

    【讨论】:

      【解决方案2】:

      您应该像这样获得有效的验证组:

      public class BclassValidator implements ConstraintValidator<BclassValidate, B> {
      
          public void initialize(BclassValidate constraintAnnotation) {
          }
      
          public boolean isValid(B b, ConstraintValidatorContext constraintContext) {
      
              boolean valid = true;
      
              // Get active group here
              Set<Class<?>> activeGroups = null;
              if (context instanceof ConstraintValidatorContextImpl) {
                  activeGroups = ((ConstraintValidatorContextImpl) context).getConstraintDescriptor().getGroups();
              } else {
                  activeGroups = Collections.emptySet();
              }
      
              if (activeGroups.contains(Operations.Insert.class)) {
                  // check if b.getName() equals to "John"
              }
              else if (activeGroups.contains(Operations.Update.class)) {
                  // check if b.getName() equals to "Doe"
              }
      
              return valid;
          }
      }
      

      【讨论】:

      • 这不是 OP 要求的。在您的实现中,activeGroups 将包含注释中传递的所有组,而不是由@Validated 注释设置的当前活动的验证组
      【解决方案3】:

      Hibernate 验证器使用为自定义约束配置的组来验证当前活动的组,因此我们无需编写逻辑来验证它。但是没有办法找到当前活跃的组。

      原因:'valueContext' 持有当前活动的组,但没有传递给 'isValid' 方法。

      https://github.com/hibernate/hibernate-validator/blob/master/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintTree.java

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-30
        • 2020-09-06
        • 1970-01-01
        • 2016-01-01
        • 2020-07-08
        • 1970-01-01
        • 2023-04-09
        相关资源
        最近更新 更多