具有可配置约束值的Spring Bean验证

4

我希望能够通过Spring将Java Bean验证约束配置化,可能使用属性。 以下是示例:

class Pizza {

    @MaxGramsOfCheese(max = "${application.pizza.cheese.max-grams}")
    int gramsOfCheese;

}

我无法使其工作并且找不到太多关于此的文档。

这样的事情是否可能?我知道信息可以在Validationmessages.properties文件中配置,因此我希望对于约束值也有类似的设置。

2个回答

3
除了@Madhu Bhat之外,您还可以配置您的ConstraintValidator类以从Spring的Environment中读取属性。
public class MaxGramsOfCheeseValidator implements ConstraintValidator<MaxGramsOfCheese, Integer> {

    @Autowired
    private Environment env;

    private int max;

    public void initialize(MaxGramsOfCheese constraintAnnotation) {
        this.max = Integer.valueOf(env.resolvePlaceholders(constraintAnnotation.max()));
    }

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        return value != null && value <= this.max;
    }

}

因此,您可以在不同的字段上使用@MaxGramsOfCheese注释,并使用不同的参数,在您的情况下可能更为合适。
class Pizza {

    @MaxGramsOfCheese(max = "${application.pizza.cheddar.max-grams}")
    int gramsOfCheddar;

    @MaxGramsOfCheese(max = "${application.pizza.mozerella.max-grams}")
    int gramsOfMozerella;

}

我喜欢这个解决方案,因为它可以通过属性或固定值来保持最大可配置性(尽管需要编程)。不幸的是,这个方法行不通:java.lang.NumberFormatException: For input string: "${application.pizza.cheddar.max-grams}" - Dormouse
我在application.yml文件中定义了属性,但似乎没有被正确读取。当我改成application.properties文件时就可以正常工作了。 - Dormouse
很高兴它能正常工作 :) 这很奇怪,通常应该可以工作。如果你同时有 .properties.yml 文件,并且对于相同的键,.properties 文件会覆盖 .yml 文件。也许这就是问题所在,但我不确定。 - Yavuz Tas
如果我使用自己的属性文件,比如myprops.properties呢?这个文件也在资源文件夹中,如何通过环境访问它?或者需要另一种解决方案吗? - neblaz
然后,我猜你可以通过使用Spring的“Environment”来访问这些属性。 - Yavuz Tas
显示剩余2条评论

3

对于任何自定义验证,您需要通过实现ConstraintValidator接口来实现一个自定义验证器,然后将该自定义验证器提供给您创建的自定义验证注解。

自定义验证器:

public class MaxGramsOfCheeseValidator implements ConstraintValidator<MaxGramsOfCheese, Integer> {

    @Value("${application.pizza.cheese.max-grams}")
    protected int maxValue;

    @Override
    public void initialize(MaxGramsOfCheese constraintAnnotation) {
    }

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        return value != null && value <= maxValue;
    }

}

自定义验证注释:

@Documented
@Constraint(validatedBy = {MaxGramsOfCheeseValidator.class})
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MaxGramsOfCheese {
    String message() default "Some issue here"; //message to be returned on validation failure

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

使用自定义验证注解:

class Pizza {

    @MaxGramsOfCheese
    int gramsOfCheese;

}

请注意,如果您想访问注释的值从属性文件中获取,您需要在自定义验证器中提供该值,如下所示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接