简体   繁体   English

Spring Boot 验证:从属性文件中获取最大大小

[英]Spring Boot validation: get max size from property file

I have got a spring boot server and would like to validate my values by spring.我有一个 spring 启动服务器,想在 spring 之前验证我的值。 Using the @Size validation I can set the max size.使用@Size 验证我可以设置最大尺寸。 But i would like to get this max size from my application.property file.但我想从我的 application.property 文件中获取这个最大大小。

I have already tried to load this value by "@Value(...)" but I can not use this value in the "@Size" field.我已经尝试通过“@Value(...)”加载这个值,但我不能在“@Size”字段中使用这个值。

 @Value("${max.size.in.properties}")
 private int MAX_SIZE;

@Size(max = 10)
private String description;

你可以像这个帖子一样按照 Java 反射https://www.baeldung.com/java-reflection-change-annotation-params

This is not possible as annotations require constant expressions ( static final ) and @Value cannot be used to inject values into static final fields.这是不可能的,因为注释需要常量表达式( static final )并且@Value不能用于将值注入静态 final 字段。

Maybe this project might help you out: https://github.com/jirutka/validator-spring .也许这个项目可以帮到你: https : //github.com/jirutka/validator-spring It allows you to use Spring Expression Language together with bean validation.它允许您将 Spring 表达式语言与 bean 验证一起使用。

We can programmatically specify constraints using Hibernate Validator , which is already available in the classpath when using spring-boot-starter-web .我们可以使用 Hibernate Validator 以编程方式指定约束,当使用spring-boot-starter-web时,它已经在类路径中可用。

Given:鉴于:

 class MyObject {
     private String description;
     ...
 }

We can setup constraints like this:我们可以这样设置约束:

@Value("${max.size.in.properties}")
private int MAX_SIZE;

HibernateValidatorConfiguration configuration = Validation
                .byProvider( HibernateValidator.class )
                .configure();
ConstraintMapping constraintMapping = configuration.createConstraintMapping();

constraintMapping.type( MyObject.class )
                 .property( "description", FIELD )
                 .constraint( new SizeDef().min( 1 ).max( MAX_SIZE ) );

and validate an instance of the object with:并使用以下方法验证对象的实例:

Validator validator = configuration.addMapping( constraintMapping )
                      .buildValidatorFactory()
                      .getValidator();

Set<ConstraintViolation<MyObject>> constraintViolations =
    validator.validate( myObjectInstance );

if (constraintViolations.size() > 0) {
   ... // handle constraint violations
}

The bad news : there's no way to do what you want with standard annotations from Java Validation API.坏消息:Java Validation API 的标准注释无法满足您的需求。

The good news : you can easily create a custom annotation that does exactly what you want.好消息:您可以轻松地创建一个完全符合您要求的自定义注释。

You need to create a custom validation annotation (let's call it @ConfigurableSize ) that takes as parameters two strings, one for the name of the property holding the min size and one for the name of the property holding the max size.您需要创建一个自定义验证注释(我们称之为@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();
    }

}

The validator will retrieve the property values upon initialization, then it will perform the exact same validation checks as the @Size constraint.验证器将在初始化时检索属性值,然后将执行与@Size约束完全相同的验证检查。 Even the constraint violation will have the exact same message.即使违反约束也会有完全相同的消息。 Please notice that if the property name is omitted the min and max will default respectively to 0 and Integer.MAX_VALUE , ie the same defaults for @Size .请注意,如果省略属性名称,则minmax将分别默认为0Integer.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;
        }
    }

}

You apply the custom annotation in your bean您在 bean 中应用自定义注释

public class SomeBean {

    @ConfigurableSize(maxProperty = "max.size.in.properties")
    private String description;

}

Then finally in your application.properties you'll define the property最后在application.properties定义属性

max.size.in.properties=10

And that's it.就是这样。 You can find more details and a full example in this blog post: https://codemadeclear.com/index.php/2021/03/22/easily-configure-validators-via-properties-in-a-spring-boot-project/您可以在此博客文章中找到更多详细信息和完整示例: https : //codemadeclear.com/index.php/2021/03/22/easily-configure-validators-via-properties-in-a-spring-boot-项目/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM