Pergunta

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?

Foi útil?

Solução

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.

Outras dicas

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();

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top