Search code examples
springbean-validationjersey-2.0hibernate-validator

Hibernate validation with custom messages in property file


Hi am using hibernate validator in jersey rest service. Here how can we pass value to the property file message as follows

empty.check= Please enter {0} 

here in {0} i need to pass the value from annotation

@EmptyCheck(message = "{empty.check}") private String userName

here in the {0} i need to pass "user name", similarly i need to reuse message

please help me out to solve this.


Solution

  • You can do this by altering your annotation to provide a field description and then exposing this in the validator.

    First, add a description field to your annotation:

    @Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
    @Retention(RetentionPolicy.RUNTIME)
    @Constraint(validatedBy = EmptyCheckValidator.class)
    @Documented
    public @interface EmptyCheck {
        String description() default "";
        String message() default "{empty.check}";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }
    

    Next, change your message so that it uses a named parameter; this is more readable.

    empty.check= Please enter ${description} 
    

    Since you're using hibernate-validator, you can get the hibernate validator context within your validation class and add a context variable.

    public class EmptyCheckValidator 
                 implements ConstraintValidator<EmptyCheck, String> {
        String description;
        public final void initialize(final EmptyCheck annotation) {
            this.description = annotation.description();
        }
    
        public final boolean isValid(final String value, 
                                     final ConstraintValidatorContext context) {
            if(null != value && !value.isEmpty) {
                return true;
            }
            HibernateConstraintValidatorContext ctx = 
                context.unwrap(HibernateConstraintValidatorContext.class);
            ctx.addExpressionVariable("description", this.description);
            return false;
        }
    }
    

    Finally, add the description to the field:

    @EmptyCheck(description = "a user name") private String userName
    

    This should produce the following error when userName is null or empty:

    Please enter a user name