Spring Validation custom messages - field name

12,481

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.

Share:
12,481
Greyshack
Author by

Greyshack

Updated on June 14, 2022

Comments

  • Greyshack
    Greyshack almost 2 years

    Problem: how to get field name in validation messages in Spring

    Is there a way I can access the field name in the ValidationMessages.properties file, for example below I tried using {0} but it doesn't work, I've seen it somewhere. I want Spring to dynamically put the field name there so I don't have to repeat it for every class.

    public class RegistrationForm {
    
        @NotEmpty(message = "{NotEmpty}")
        private String email;
    
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    }
    

    ValidationMessages.properties

    NotEmpty={0} TEST
    
  • Greyshack
    Greyshack over 8 years
    That makes sense. Thanks I'll do that. However, don't I need to use the ${} syntax?
  • joshaidan
    joshaidan over 6 years
    Would the key map to RegistrationForm.email or registrationForm.email? In my tests it seems to match to the lowercase version. I'll try to step through the code like you said to get a better idea of what's going on. Thanks for the info though!