Bean Validation Message with dynamic parameter
Asked Answered
L

3

14

I am getting started with bean validation, and I'm trying to compose a constraint. My constraint is to validate a CPF(personal document in Brazil). My constraint is working, but I need the message to contain a dynamic parameter.

I'm using ValidationMessages.properties. My code:

@Constraint(validatedBy=CpfValidator.class)
@Size(min=11, max=14)
@Documented
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Cpf {

    String message() default "{cpf.validation.message}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

}

My ValidationMessages.properties:

cpf.validation.message=Cpf {cpf} é inválido

My Validator: i'm using a context.buildConstraintViolationWithTemplate to customiza my message.

@Override
public boolean isValid(String value, ConstraintValidatorContext context) {

    String cpf = value;

    boolean result = ValidationUtil.validaCpf(cpf);
    if (result) {
        return true;
    }

    context.disableDefaultConstraintViolation();
    context.buildConstraintViolationWithTemplate("pf.validation.message}")
           .addConstraintViolation();
    return false;

}

How can I pass the validated value(cpf) by parameter when the message is created?

Lonilonier answered 31/1, 2014 at 17:21 Comment(0)
O
14

When working with Hibernate Validator >= 4.2 you can reference the validated value via ${validatedValue} in your messages (in Bean Validation 1.1 that's standardized in the spec):

cpf.validation.message=Cpf ${validatedValue} é inválido

Btw. Hibernate Validator already comes with a @CPF constraint, you can find out more in the reference guide. Would be very glad to hear about how that works for you.

Orlena answered 31/1, 2014 at 20:27 Comment(1)
Thank's for your help Gunnar, but I can't use annotations that are not JPA specification.Lonilonier
L
11

I found the solution, i think i can improve that solution, but for now it's good. I did this changes in my code:

String message() default "Cpf %s é inválido";

String msgDefault = context.getDefaultConstraintMessageTemplate();
String msgFormatada = String.format(msgDefault, cpf);

context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(msgFormatada).addConstraintViolation();
Lonilonier answered 3/2, 2014 at 10:43 Comment(0)
T
8

if we want to provide other parameter instead of the validated value to the message:

cpf.validation.message=Cpf {cpf} é inválido 

We can use HibernateConstraintValidatorContext as follows:

@Override
public boolean isValid(String value, ConstraintValidatorContext context) {

    String cpf = value;

    boolean result = ValidationUtil.validaCpf(cpf);
    if (result) {
        return true;
    }

    HibernateConstraintValidatorContext hibernateContext = context.unwrap(HibernateConstraintValidatorContext.class);
    hibernateContext.disableDefaultConstraintViolation();
    hibernateContext
           .addMessageParameter( "cpf", cpf )
           .buildConstraintViolationWithTemplate("pf.validation.message}")
           .addConstraintViolation();

    return false;

}

As is mentioned above, is in hibernate documentation

Tungusic answered 14/11, 2018 at 18:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.