Where are the Spring MVC validation error codes resolved?

James McMahon picture James McMahon · Dec 10, 2009 · Viewed 24.7k times · Source

I am attempting to write validators under the Spring MVC framework, but there is a glaring omission in the documentation. When calling passing an error to the Errors object most of the methods expect an String parameter named errorCode. These errorCodes, if I understand correctly serve as stand ins for specific error messages. But I can't for the life figure out where these codes are mapped to.

Here is an example of what I am referring to from Spring MVC's Javadoc;

 public class UserLoginValidator implements Validator {

    private static final int MINIMUM_PASSWORD_LENGTH = 6;

    public boolean supports(Class clazz) {
       return UserLogin.class.isAssignableFrom(clazz);
    }

    public void validate(Object target, Errors errors) {
       ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userName", "field.required");
       ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "field.required");
       UserLogin login = (UserLogin) target;
       if (login.getPassword() != null
             && login.getPassword().trim().length() < MINIMUM_PASSWORD_LENGTH) {
          errors.rejectValue("password", "field.min.length",
                new Object[]{Integer.valueOf(MINIMUM_PASSWORD_LENGTH)},
                "The password must be at least [" + MINIMUM_PASSWORD_LENGTH + "] characters in length.");
       }
    }
 }

Can anyone enlighten me?

Answer

Jacob Mattison picture Jacob Mattison · Dec 10, 2009

I'm using the default message resolver.

In my dispatcher-servlet.xml, I have

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename" value="messages" />
</bean>

and then in the top level of my classes directory I have a text file called "messages.properties" that contains mappings like this:

error.firstname.null=Please enter your first name.
error.lastname.null=Please enter your last name.

If you wanted to use a custom MessageCodesResolver you can implement the MessageCodeResolver interface and then define your resolver for a given controller like this:

<bean id="myController">
  <property name="messageCodesResolver" ref="myMessageCodesResolver" />
</bean>

There isn't currently a way to define a custom MessageCodeResolver globally; there's an enhancement request for that here. One approach using bean inheritance to make all controller beans inherit from one controller bean definition, is described here.