我想根据Hibernates @LengthIfNotBlank(min=,max=)
约束创建自定义约束@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);
}
}
例外:
[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);
}
}
答案 0 :(得分:2)
由于无法继承注释类型,因此应覆盖initialize()
并将Length
类型的实际实例传递给super.initialize()
。
请注意,您无法直接创建注释类型的实例,因此您必须使用AnnotationFactory
之类的内容。
此外,由于类型安全限制,我不确定编译器是否会允许您这样做。如果没有,请使用组合而不是继承(即创建类型为LengthValidator
的字段)。
答案 1 :(得分: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代码)。
此外,我认为在实施LengthValidator
时可能会延长ConstraintValidator<LengthIfNotBlank, String>
,这对验证者来说是强制性的。
请注意,如果您想重新使用未参数化的验证器(或具有常量参数的验证器),您只需使用重新使用的验证器注释验证器(并且可以添加@ReportAsSingleViolation
)