With Hibernate Validator we can override the default messages
associated with the various validation annotations. We can also
provide highly specific error messages associated with
property/constraint pairs. We do this using resource bundles. Though
it's possible to provide Hibernate Validator with arbitrary resource
bundles, the easiest approach is to create
a ValidatorMessages.properties resource bundle on the
classpath and use that. Hibernate Validator knows to look for that
particular bundle (including any associated localizations) and use it
as a message source. Listing 3 presents a simple example.
ValidatorMessages.properties resource bundle
validator.notEmpty=may not be null or empty!
validator.length=must be {max} or fewer characters.
zip.length=Please enter a {max}-character ZIP code.
The first two lines of listing 3 provide alternatives for
the validator.notEmpty and validator.length
message keys. The key names are defined by the validation annotations
themselves, so consult the Javadocs for the annotations if you need
the key names (though you should be able to figure them out using the
examples above).
Notice the {max} that appears in the message for
the validator.length key. You can reference annotation
elements from messages using the brace syntax. Consult the Javadocs
for the various annotations—or else the Hibernate Validator
reference manual—for a complete list of annotations and
annotation elements.
The third line also specifies a message, but this time we're
associating a message with the zip.length custom key we
defined in listing 2. Note that here we don't use the braces for the
key name. And also note that we can still reference annotation
elements using the brace syntax. The custom message key approach is
useful when you want to be very specific about the error message you
provide to the end user.
Here's what it looks like when you run it:
29 [main] INFO org.hibernate.validator.Version - Hibernate Validator 3.1.0.GA 59 [main] INFO org.hibernate.annotations.common.Version - Hibernate Commons Annotations 3.1.0.GA ======== username may not be null or empty! message=may not be null or empty! propertyName=username propertyPath=username value=null ======== firstName must be 20 or fewer characters. message=must be 20 or fewer characters. propertyName=firstName propertyPath=firstName value=123456789012345678901 ======== lastName may not be null or empty! message=may not be null or empty! propertyName=lastName propertyPath=lastName value=null ======== email not a well-formed email address message=not a well-formed email address propertyName=email propertyPath=email value=aol.com ======== password may not be null or empty! message=may not be null or empty! propertyName=password propertyPath=password value=null ======== street1 may not be null or empty! message=may not be null or empty! propertyName=street1 propertyPath=address.street1 value= ======== zip Please enter a 5-character ZIP code. message=Please enter a 5-character ZIP code. propertyName=zip propertyPath=address.zip value=QWERTY ======== zip must match "[0-9]+" message=must match "[0-9]+" propertyName=zip propertyPath=address.zip value=QWERTY
That wraps it up for this tutorial. It's a good idea to get familiar with Hibernate Validator for a number of reasons:
We haven't explored everything that Hibernate Validator has to offer. For instance, it's possible to configure it such that Hibernate ORM automatically runs Hibernate Validator when performing persistence operations.
One slight annoyance that I've found is that there doesn't seem to be built-in way to substitute the bad value into the message itself. Sometimes I like to have messages like
willie2gmail.com is not a valid e-mail address{1} is not a valid e-mail addressand then perform the substitution when processing
the InvalidValue array, but it would be nice to be able
to do this out of the box. Maybe there's a way to do it after all, but
if so, I haven't found it.
Also, the documentation for Hibernate Validator is a little thin, both with respect to the reference manual and the Javadocs. Hopefully as JSR 303 matures we'll see improvements in this area. In the meantime, this tutorial will be my contribution to helping people understand Hibernate Validator.