Building Dynamic Ignition Limit Error Messages

I wrote a validation annotation done by a custom ConstraintValidator . I also want to generate very specific ConstraintViolation objects that use the values ​​computed during the validation process during message interpolation.

 public class CustomValidator implements ConstraintValidator<CustomAnnotation, ValidatedType> { ... @Override public boolean isValid(ValidatedType value, ConstraintValidatorContext context) { // Figure out that the value is not valid. // Now, I want to add a violation whose error message requires arguments. } } 

Hypothetical error message in my message source:

 CustomAnnotation.notValid = The supplied value {value} was not valid because {reason}. 

The context passed to the isValid method provides an interface for creating a constraint violation and, finally, adding it to the context. However, I cannot figure out how to use it. According to this documention for the version used, I can add bean and property nodes to the violation. This is the only additional data that I can specify to determine the violation, but I do not understand how they can be displayed in the parameters in the error message.

Million-dollar question: how do I pass dynamic parameters to validation error messages using a custom validator? I would like to populate these {value} and {reason} fields using the ConstraintValidatorContext interface for breaking the rules.

Retrieving an instance of the message source and interpolating the message in the user-defined validator is not an option - messages that exit the check receive interpolation regardless of whatsoever, and interpolation inside will cause some messages to be interpolated twice, potentially destroying the shielded ones single quote screens or other characters with special meanings in the definition file of my messages.

+6
source share
2 answers

This is not possible with the standardized Bean API, but there is a way in Hibernate Validator, the reference implementation of BV.

You need to deploy the ConstraintValidatorContext in the HibernateConstraintValidatorContext , which will give you access to the addExpressionVariable() method:

 public class MyFutureValidator implements ConstraintValidator<Future, Date> { public void initialize(Future constraintAnnotation) {} public boolean isValid(Date value, ConstraintValidatorContext context) { Date now = GregorianCalendar.getInstance().getTime(); if ( value.before( now ) ) { HibernateConstraintValidatorContext hibernateContext = context.unwrap( HibernateConstraintValidatorContext.class ); hibernateContext.disableDefaultConstraintViolation(); hibernateContext.addExpressionVariable( "now", now ) .buildConstraintViolationWithTemplate( "Must be after ${now}" ) .addConstraintViolation(); return false; } return true; } } 

The reference guide contains some more details .

+10
source

If you use message codes, you can simply add something like {0} to them.

For example: "Field {0} must not be empty."

And then use hibernateContext.addMessageParameter("0", fieldName); instead of addExpressionVariable(...) .

It worked for me.

0
source

Source: https://habr.com/ru/post/969398/


All Articles