【问题标题】:Is it possible to pass validatedBy attribute to the annotation as a parameter?是否可以将validateBy属性作为参数传递给注释?
【发布时间】:2020-01-13 12:12:03
【问题描述】:

我将validateBy 值硬编码如下。

@Constraint(validatedBy = ReminderValidator.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyValidator{
    String message() default "{error.message}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

我不想将validateBy 值硬编码到我的注释接口中,而是想将其作为类似于以下内容的参数传递。

@MyValidator(validatedBy = "ReminderValidator.class")
public class Reminder {
...
}

这将使我能够为所有类验证创建 1 个注释。我只会为注解提供不同的验证器类来验证不同的类。有可能做这样的事情吗?

【问题讨论】:

  • 我已经尝试过给出一个可能的解决方案。让我知道这是否适合您。似乎是一个有趣的问题。

标签: java spring hibernate-validator


【解决方案1】:

您可以在@Constraint 注释中添加多个验证器,它将根据对象类型选择适当的。

@Constraint(validatedBy = { ReminderValidator.class, PendingValidator.class } )
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyValidator{
    String message() default "{error.message}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

@MyValidator()
public class Reminder {
    ...
}

@MyValidator()
public class Pending {
    ...
}

验证器示例

public class ReminderValidator implements ConstraintValidator<MyValidator, Reminder> {
...

public class PendingValidator implements ConstraintValidator<MyValidator, Pending> {
...

【讨论】:

    【解决方案2】:

    如果这对你来说是一个可以接受的解决方案,请告诉我 -

    @Constraint(validatedBy = CommonValidator.class)
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyValidator{
        // this decides what actual validator we will use
        String validator();
        String message() default "{error.message}";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }
    

    现在在CommonValidator 中,我们可以根据validator 的值来决定实际的验证器。


    静态验证器示例:

    public class SomeValidator {
        public static boolean isValid(Object field, ConstraintValidatorContext context) {
            // your actual validation code
        }
    }
    

    同样,您也可以定义其他验证器。


    这是在实际验证器中使用静态验证器的方法:

    public class CommonValidator implements ConstraintValidator<MyValidator, Object> {
    
        private String validator;
    
        @Override
        public void initialize(MyValidator myValidator) {
            this.validator = myValidator.validator();
            // do other inits as per your requirement
        }
    
        @Override
        public boolean isValid(Object field, ConstraintValidatorContext context) {
            ValidatorFactory.getValidator("someValidator").isValid(field, context)
            // return other validators like above
            return false;
        }
    }
    

    你终于可以像这样使用你的注释了-

    @MyValidator(validator = "someValidator")
    private Object object;
    

    对象也可以是任何其他类,你必须在 单独的静态验证器。

    仅供参考 - 这只是一个想法,实际实施可能会根据您的用例而有所不同。

    【讨论】:

    • 这将要求我在每次创建新验证时向 CommonValidator 类添加一个 if 语句。这就是为什么它不完全是我需要的。感谢您的回答。
    • If 只是一个例子,在这里您可以使用工厂,它将根据验证器名称返回实际的验证器类。
    猜你喜欢
    • 2021-12-30
    • 2010-10-08
    • 1970-01-01
    • 2017-08-01
    • 2011-11-30
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多