当前位置: 首页 > 知识库问答 >
问题:

JSR-303 Bean验证-自定义约束多个注释到一个验证器

黄宏毅
2023-03-14

编写自定义约束时,一个验证器实现可以验证多个注释。例如,我有几个注释,它们规定了不同的@size注释,但我希望它们都指向同一个验证器类,该类执行一些全局检查,即所有注释都必须与某个正则表达式匹配。据我所知,该实现采用了一种注释类型。

一个注释

@Target( { METHOD, FIELD, ANNOTATION_TYPE, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {UCNValidator.class})
@Documented
@Size(min = 9, max = 9, message = "{exactlength}")
public @interface UCN {

    String message() default "{invalidFormat}";

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

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

    String fieldName() default "ucn";

}

验证器

public class UCNValidator implements ConstraintValidator<UCN, String>
{

    private String pattern = "[a-zA-Z].*";
    private String fieldName;

    @Override
    public void initialize( UCN constraintAnnotation )
    {
        this.fieldName = constraintAnnotation.fieldName();
    }

    @Override
    public boolean isValid( String value, ConstraintValidatorContext constraintValidatorContext )
    {

        if ( value != null )
        {
            if ( !value.matches(pattern) )
            {
                //do some stuff
                return false;
            }

        }

        return true;

    }

共有1个答案

冯阳华
2023-03-14

在验证对象的一个属性时,似乎没有办法从对象访问其他值。我使用的解决方案是将注释放在类上,然后验证器将获取整个对象进行验证,您可以访问执行验证所需的信息。

这是我写的一个,用于比较对象的两种不同属性:

@Target(TYPE)
@Retention(RUNTIME)
@Constraint(validatedBy = LessThanValidator.class)
@Documented
public @interface LessThan {

    String message() default "{com.bullethq.constraints.LessThan}";

    String bigValueProperty();

    String littleValueProperty();

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

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

那么验证器类是:

public class LessThanValidator implements ConstraintValidator<LessThan, Object> {

    private LessThan constraint;

    public void initialize(LessThan constraintAnnotation) {
        constraint = constraintAnnotation;
    }

    public boolean isValid(Object object, ConstraintValidatorContext cvc) {
        Object bigValue = getValue(object, constraint.bigValueProperty());
        Object littleValue = getValue(object, constraint.littleValueProperty());

        // If one of the values is null, then we do not perform validation.
        if (bigValue == null || littleValue == null) {
            return true;
        }

        if (bigValue instanceof Comparable && littleValue instanceof Comparable) {
            boolean valid = ((Comparable<Object>) bigValue).compareTo(littleValue) > 0;
            if (!valid) {
                // If the values are not valid, then build a custom violations which has the correct path in it.
                cvc.buildConstraintViolationWithTemplate(cvc.getDefaultConstraintMessageTemplate())
                        .addNode(constraint.littleValueProperty())
                        .addConstraintViolation().disableDefaultConstraintViolation();
            }
            return valid;
        }
        throw new IllegalArgumentException("Properties " + constraint.bigValueProperty() + " and " + constraint.littleValueProperty() + " both need to be comparable in " + object.getClass());
    }
}

getValue()方法只是一个静态方法,使用反射从对象获取值。

 类似资料:
  • 我们正在开发REST服务,并希望使用JSR303进行输入数据验证,但这里的问题是所有模型对象都是从groovy DSL生成的,并将作为jars导入。因此,在对象字段之上编写JSR-303注释没有灵活性。 那么,有没有其他方法可以不用注释使用JSR-303,可以通过XML配置吗?或者在这种情况下,请提供任何验证建议。 谢啦

  • 我在项目中使用bean验证,我想为现有的约束注释编写一个自定义验证器。 例如,我有一个类,它表示一个名为CustomDateTime的日期/时间。在使用此类作为例如出生日期的类中,我想用过去的日期对字段进行注释: 然后,我通过实现ConstraintValidator创建一个自定义验证器 我知道您通常会创建这样的单独注释: 但对我来说,这似乎是双重代码;-) 如何注册要与一起使用的自定义验证器?

  • TLDR:我想要在单独的模块中单独的自定义bean验证定义及其ConstraintValidator实现。为此,我必须使用ConstraintMmap手动注册。它适用于带注释的类。但是定义的绑定不共享/可用于通过validation-constraints.xml.定义的验证如何修复?我试图调试它,以找出它在哪里初始化以及为什么会出现问题,但初始化这些远非易事。 动机: 一) 分离模块:如果API

  • 问题内容: 我刚刚开始测试JSR-303 Bean验证,并且想知道是否有可能。我们的应用程序中有一个用于所有String字段的默认正则表达式。如果我想使用bean验证来应用此功能,我想我需要在表单对象中注释每个字段。 一击是否可以将@Pattern应用于所有字符串(或某些字段)?我们正在WebLogic 10.3.4上使用Hibernate实现,并以JSF2.0为前端。验证应该独立于视图,因为我可

  • 我有一个自定义注释@UniqueModel,它由ConstraintValidator验证: 问题是,我需要在调用存储库的safe()-方法之前进行验证,否则字段注入将无法工作。 因此,我创建了一个带有@Valid注释的委托方法,以便在以下情况之前强制进行唯一验证: 不幸的是,这不起作用,似乎@Valid注释被Spring忽略了。 我如何确保验证的正确时间?

  • 我已经为此斗争了好几天,我已经阅读了这里的所有讨论,但没有解决方案...... 我有一个自定义约束… 独一无二.java 这是由UniqueConstraintValidator使用的.java 现在,我的模型有这个注释,我需要在其中验证字段的唯一性 现在,我知道自定义注释在更新现有对象时不起作用,但是现在我需要了解它是如何工作的。假设我们想要添加一个新对象。 当我试图保存一个已经存在的值时,我得