This is possible if you use the Spring message bundles (i.e. message.properties
) instead of ValidationMessages.properties
to localize messages.
Using your example, Spring will (in a first pass) try to localize the field name using the following message keys (or codes) in messages.properties
:
[RegistrationForm.email,email]
falling back to the field name if nothing is found.
Spring then looks up the localized error message itself using the following keys:
[NotEmpty.RegistrationForm.email,NotEmpty.email,NotEmpty.java.lang.String,NotEmpty]
Note here that NotEmpty
has higher priority than java.lang.String,NotEmpty
so don't get fooled if you want to customize the message based on the field type.
So if you put the following content in your messages.properties
, you'll get the desired behavior:
# for the localized field name (or just email as the key)
RegistrationForm.email=Registration Email Address
# for the localized error message (or use another specific message key)
NotEmpty={0} must not be empty!
From the javadoc of SpringValidatorAdapter#getArgumentsForConstraint()
:
Return FieldError arguments for a validation error on the given field.
Invoked for each violated constraint.
The default implementation returns a first argument indicating the field name
(of type DefaultMessageSourceResolvable, with "objectName.field" and "field" as codes).
Afterwards, it adds all actual constraint annotation attributes (i.e. excluding
"message", "groups" and "payload") in alphabetical order of their attribute names.
Can be overridden to e.g. add further attributes from the constraint descriptor.
While with ValidationMessages.properties
you would use {max}
to refer to the max
attribute of a @Size
annotation, with Spring message bundles you would use {1}
(because max
is the first attribute of @Size
when ordered alphabetically).
For more information, you can also see my feature request to ease field name localization.
Appendix: how to find this info?
By stepping in code unfortunately (and this post now!).
To find out which keys are used for localizing the fields the errors, inspect the value of your BindingResult
. In your example, you would get this error:
Field error in object 'RegistrationForm' on field 'email': rejected value []; codes [NotEmpty.RegistrationForm.email,NotEmpty.email,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [RegistrationForm.email,email]; arguments []; default message [email]]; default message [may not be empty]
SpringValidatorAdapter#getArgumentsForConstraint()
takes care of making the validation annotation attributes values and the field name available for the error message.