是否可以将 validatedBy 属性作为参数传递给注释?

Is it possible to pass validatedBy attribute to the annotation as a parameter?

我将 validatedBy 值硬编码如下。

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

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

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

这将使我能够为所有 class 验证创建 1 个注释。我将为注释提供不同的验证器 classes 以验证不同的 classes。有没有可能做这样的事情?

让我知道这是否是您可以接受的解决方案 -

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

Object can be any other class as well, you have to handle this in individual static validator.

仅供参考 - 这只是一个想法,实际实施可能会因您的用例而异。

您可以在 @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> {
...