根据现有的Hibernate Validator创建自定义的Hibernate Validator

dtr*_*unk 5 java hibernate hibernate-validator

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

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

例外:

[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
Run Code Online (Sandbox Code Playgroud)

更新

仍然出现此异常:-(

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

axt*_*avt 2

由于注释类型无法继承,因此您应该覆盖initialize()类型的实际实例并将其传递Lengthsuper.initialize().

请注意,您无法直接创建注释类型的实例,因此您必须使用类似AnnotationFactory.

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