To understand InvalidValue it will help to run the
demo. So do that right now. You should see output that looks something
like this:
26 [main] INFO org.hibernate.validator.Version - Hibernate Validator 3.1.0.GA
45 [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 length must be between 0 and 20
message=length must be between 0 and 20
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 {zip.length}
message={zip.length}
propertyName=zip
propertyPath=address.zip
value=QWERTY
========
zip must match "[0-9]+"
message=must match "[0-9]+"
propertyName=zip
propertyPath=address.zip
value=QWERTY
If you look at the source code for Demo.validateUser()
you'll see that we're printing out each InvalidValue
instance itself (the first line) as well as the values of
the message, propertyName, propertyPath
and value properties (the rest of the lines). When we
print out the instance itself, we get Hibernate Validator's attempt at
a user-friendly validation eror message. It starts with the property name and then appends the message; examples include
email not a well-formed e-mail addresspassword may not be null or emptyzip must match "[0-9]+"Each message value (such as may not be null or
empty) is a default associated with a validation annotation
(such as @NotEmpty). Note that in the case of the length
violation for the zip property, we're seeing not the
default length message, but instead the new message key name
(namely, zip.length) we specified in listing 2. We'll see
how to map zip.length to an actual message using a
resource bundle in a little bit. For now we're seeing just the key
name because we haven't yet associated a message with the key.
The propertyName property specifies the name of the
bean property whose value is invalid. For example, if we provide a bad
ZIP code, then propertyName
is zip.
The propertyPath property is similar
to propertyName property, except that
with propertyPath we get to see the path from the
top-level bean down to the invalid property. You can see the
difference, for instance, with the invalid ZIP
code: propertyName is zip
but propertyValue is address.zip.
Finally, value is just the bad value that violated the
validation constraint in the first place.
While we can use InvalidValue itself as a source of
semi-user-friendly messages, it's clear that the defaults leave
something to be desired. After all, zip must match
"[0-9]+" wouldn't be what most users would consider
user-friendly. We can however provide a resource bundle to improve the
error messages and that's what we'll look at now.