坏消息:无法使用 Java Validation API 的标准注释来做你想做的事。
好消息:您可以轻松创建完全符合您要求的自定义注释。
您需要创建一个自定义验证注释(我们称之为@ConfigurableSize),它将两个字符串作为参数,一个用于保存最小大小的属性名称,另一个用于保存最大大小的属性名称。
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(ConfigurableSize.List.class)
@Constraint(validatedBy = {ConfigurableSizeCharSequenceValidator.class})
public @interface ConfigurableSize {
String message() default "size is not valid";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String minProperty() default "";
String maxProperty() default "";
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
@interface List {
ConfigurableSize[] value();
}
}
验证器将在初始化时检索属性值,然后它将执行与@Size 约束完全相同的验证检查。即使违反约束也会有完全相同的消息。请注意,如果省略属性名称,min 和 max 将分别默认为 0 和 Integer.MAX_VALUE,即 @Size 的默认值相同。
public class ConfigurableSizeCharSequenceValidator implements ConstraintValidator<ConfigurableSize, CharSequence> {
private final PropertyResolver propertyResolver;
private int min;
private int max;
@Autowired
public ConfigurableSizeCharSequenceValidator(PropertyResolver propertyResolver) {
this.propertyResolver = propertyResolver;
}
@Override
public void initialize(ConfigurableSize configurableSize) {
String minProperty = configurableSize.minProperty();
String maxProperty = configurableSize.maxProperty();
this.min = "".equals(minProperty) ? 0 :
propertyResolver.getRequiredProperty(minProperty, Integer.class);
this.max = "".equals(maxProperty) ? Integer.MAX_VALUE :
propertyResolver.getRequiredProperty(maxProperty, Integer.class);
validateParameters();
}
private void validateParameters() {
if (this.min < 0) {
throw new IllegalArgumentException("The min parameter cannot be negative.");
} else if (this.max < 0) {
throw new IllegalArgumentException("The max parameter cannot be negative.");
} else if (this.max < this.min) {
throw new IllegalArgumentException("The length cannot be negative.");
}
}
@Override
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
if (value == null) {
return true;
} else {
int length = value.length();
boolean retVal = length >= this.min && length <= this.max;
if (!retVal) {
HibernateConstraintValidatorContext hibernateContext =
context.unwrap(HibernateConstraintValidatorContext.class);
hibernateContext.addMessageParameter("min", this.min)
.addMessageParameter("max", this.max);
hibernateContext.disableDefaultConstraintViolation();
hibernateContext
.buildConstraintViolationWithTemplate("{javax.validation.constraints.Size.message}")
.addConstraintViolation();
}
return retVal;
}
}
}
您在 bean 中应用自定义注解
public class Device {
@ConfigurableSize(minProperty = "device.name.minsize", maxProperty = "device.name.maxsize")
private String name;
}
最后在application.properties 中定义属性
device.name.minsize=4
device.name.maxsize=8
就是这样。您可以在此博客文章中找到更多详细信息和完整示例:
https://codemadeclear.com/index.php/2021/03/22/easily-configure-validators-via-properties-in-a-spring-boot-project/