【问题标题】:Create custom hibernate Validator based on existing Hibernate Validator基于现有的 Hibernate Validator 创建自定义的 Hibernate Validator
【发布时间】:2012-07-08 13:19:41
【问题描述】:

我想基于 Hibernates @Length 约束创建一个自定义约束 @LengthIfNotBlank(min=,max=):

@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = LengthIfNotBlankValidator.class)
@Documented
public @interface LengthIfNotBlank {
    String message() default "{com.mycompany.LengthIfNotBlank}";
    Class<? extends Payload>[] payload() default {};
    int max() default Integer.MAX_VALUE;
    Class<?>[] groups() default {};
    int min() default 0;
}

public class LengthIfNotBlankValidator extends LengthValidator {
    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
        return StringUtils.isBlank(value) || super.isValid(value, constraintValidatorContext);
    }
}

例外:

[java] javax.validation.ValidationException: Unable to initialize com.example.constraints.LengthIfNotBlankValidator
[java] Caused by: java.lang.ClassCastException: $Proxy32 cannot be cast to org.hibernate.validator.constraints.Length

更新

仍然得到这个异常:-(

public class LengthIfNotBlankValidator extends LengthValidator {
    public void initialize(LengthIfNotBlank parameters) {
        Map<String,Object> elements = new HashMap<String,Object>();
        elements.put("message", parameters.message());
        elements.put("payload", parameters.payload());
        elements.put("groups", parameters.groups());
        elements.put("min", parameters.min());
        elements.put("max", parameters.max());

        AnnotationDescriptor<Length> descriptor = AnnotationDescriptor.getInstance(Length.class, elements);
        Length length = AnnotationFactory.create(descriptor);
        super.initialize(length);
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
        return StringUtils.isBlank(value) || super.isValid(value, constraintValidatorContext);
    }
}

【问题讨论】:

    标签: java hibernate hibernate-validator


    【解决方案1】:

    我认为你不应该为此烦恼:Hibernate 的LengthValidator 非常简单,无论你做什么,你最终都会得到更多的代码,如果你只是像这样自己重新实现代码:

    public class LengthIfNotBlankValidator implements ConstraintValidator<LengthIfNotBlank, String> {
        private int min;
        private int max;
    
        public void initialize(LengthIfNotBlank parameters) {
            min = parameters.min();
            max = parameters.max();
            validateParameters();
        }
    
        public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
            if ( StringUtils.isBlank(value) ) {
                return true;
            }
            int length = value.length();
            return length >= min && length <= max;
        }
    
        private void validateParameters() {
            if ( min < 0 ) {
                throw new IllegalArgumentException( "The min parameter cannot be negative." );
            }
            if ( max < 0 ) {
                throw new IllegalArgumentException( "The max parameter cannot be negative." );
            }
            if ( max < min ) {
                throw new IllegalArgumentException( "The max cannot be less than the min." );
            }
        }
    }
    

    (这只是 Hibernate 为您的特定情况改编的代码)。

    另外,我认为在实现 ConstraintValidator&lt;LengthIfNotBlank, String&gt; 的同时扩展 LengthValidator 是不可能的,这对于您的验证器来说是强制性的。

    但是请注意,如果您想重用未参数化的验证器(或具有常量参数的验证器),您可以简单地用重用的验证器注释您的验证器(也可以添加 @ReportAsSingleViolation)

    【讨论】:

    • 我同意,但是当重复的代码如此简单时,我不确定使用反射来避免它真的更好。反射代码可能更难理解和维护……
    • +1 看到这个超过 6 年的答案并且在一个有 6K 视图的问题上没有一个赞成票,真的很惊讶,这是一种更简单、更好的方法。仅仅因为某事是可能的并不意味着它应该完成。
    【解决方案2】:

    由于注解类型不能被继承,你应该重写initialize()并将Length类型的实际实例传递给super.initialize()。

    请注意,您不能直接创建注释类型的实例,因此您必须使用 AnnotationFactory 之类的东西。

    此外,由于类型安全约束,我不确定编译器是否允许您这样做。如果没有,请使用组合而不是继承(即创建LengthValidator 类型的字段)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-10
      • 1970-01-01
      相关资源
      最近更新 更多