Reputation: 1637
I'd like to make Java Bean Validation constraints configurable by Spring, possibly by using properties. An example:
class Pizza {
@MaxGramsOfCheese(max = "${application.pizza.cheese.max-grams}")
int gramsOfCheese;
}
I haven't been able to get this to work or find much documentation about this.
Is something like this even possible? I know that messages are configurable in a Validationmessages.properties file, so I'm hoping something similar is possible for constraint values.
Upvotes: 4
Views: 4069
Reputation: 354
In addition to @Madhu Bhat you can configure your ConstraintValidator
class to read properties from Spring's 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;
}
}
Thus you can use @MaxGramsOfCheese
annotation on different fields with different parameters which may be more appropriate in your case.
class Pizza {
@MaxGramsOfCheese(max = "${application.pizza.cheddar.max-grams}")
int gramsOfCheddar;
@MaxGramsOfCheese(max = "${application.pizza.mozerella.max-grams}")
int gramsOfMozerella;
}
Upvotes: 4
Reputation: 15253
For any custom validation, you need to implement a custom validator by implementing the ConstraintValidator
interface, and then provide that custom validator to the custom validation annotation that you create.
The custom validator:
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;
}
}
The custom validation annotation:
@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 {};
}
Using the custom validation annotation:
class Pizza {
@MaxGramsOfCheese
int gramsOfCheese;
}
Note that if you want the value for the annotation to be accessed from the properties file, you'll have to provide that in the custom validator as shown.
Upvotes: 3