Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making javax validation error message more specific

Sorry if this question has been covered somewhere before. If it has please link me to it, I haven't been able to find a satisfactory answer as yet.

I've been looking around trying to find a way to have the error messages provided by my javax validation more specific.

The message I currently have for my @Min annotation is specified in the ValidationMessages.properties file:

javax.validation.constraints.Min.message=The value of this variable must be less than {value}.

and this prints out as would be expected

The value of this variable must be less than 1

What I would like to have is the message also include the name of the variable (and class) that has failed the validation as well as the value of the variable that failed. So more like.

The value of class.variable was 0 but not must be less than 1

Any help would be greatly appreciated.

Klee

like image 757
Klee Avatar asked Mar 07 '11 23:03

Klee


2 Answers

Hmmm. Annoying! As I see it you have 3 options:

  1. You could write a custom MessageInterpolator and substitute it into your validation configuration, but that's seems really brittle.

  2. You could declare your own custom annotation in-the-style of @Min (see how to do a custom validator here) ...

  3. .. But the information you need is actually held within the ConstraintViolation object that comes out of the Validator instance. It's just that it doesn't get put into the default message.

I'm guessing you're currently using some kind of web framework to validate a form. If that's the case, it should be quite straightforward to override the validation and do something like this (quick hacky version, you should be able to make this very tidy by using an external properties file):

  Set<ConstraintViolation<MyForm>> violations = validator.validate(form);
  for (ConstraintViolation<MyForm> cv : violations) {
    Class<?> annoClass = cv.getConstraintDescriptor().getAnnotation().getClass();
    if (Min.class.isAssignableFrom(annoClass)) {
      String errMsg = MessageFormat.format(
        "The value of {0}.{1} was: {2} but must not be less than {3}",
        cv.getRootBeanClass(),
        cv.getPropertyPath().toString(), 
        cv.getInvalidValue(),
        cv.getConstraintDescriptor().getAttributes().get("value"));
            // Put errMsg back into the form as an error 
    }
  }
like image 135
millhouse Avatar answered Oct 12 '22 15:10

millhouse


I believe you need to create a custom constraint.
You haven't mentioned which implementation of the spec you are using, but there is good documentation on how to create a custom constraint for the Hibernate Validator here.

Part of the process will involve creating your own ValidationMessages.properties file

like image 42
Sean Avatar answered Oct 12 '22 15:10

Sean