Search code examples
javaspringjspinternationalizationhibernate-validator

Form validation using Hibernate Validator


I'm using Hibernate Validator to validate the input fields in my form. Ideally I'd want to show an error message next to each field when there is a problem with that field.

In the register form I ask for a password and to repeat the password and I want to make sure they match. Using this question I was able to implement this. The problem with this is of course that the validation happens at the class level which means the error message is only shown when I do:

<form:errors path="*" />

I thought this would be fine, I'll be doing validation client-side as well and I can do the inline approach there, if people have turned off JS, it's not that bad that I have a group element to show the errors. The problem with this approach is that I have to be able to say for instance:

'Name' field cannot be empty
'Email' field is invalid

As I am making this application with i18n in mind, I can't hard code the field names like 'Email' and 'Name' so I have the following in my User entity for validation ({fieldEmpty} is just a string that says 'cannot be empty'):

@Email(message = "{register_EmailInvalid}")
@NotBlank(message = "\"{register_EmailField}\" {fieldEmpty}")
private String email;
@NotBlank(message = "\"{register_NameField}\" {fieldEmpty}")
private String name;
@NotBlank(message = "\"{register_FirstNameField}\" {fieldEmpty}")
private String firstName;
@NotBlank(message = "\"{register_PasswordField}\" {fieldEmpty}")
private String password;
@NotBlank(message = "\"{register_PasswordRepeatField}\" {fieldEmpty}")
private String passwordRepeat;

This picks up the correct value for the field name according to the locale setting of the user but it also means I have to duplicate the register_EmailField, register_NameField, ... in my regular messages.properties and my ValidationMessages.properties.

The field names are at the moment all in the ValidationMessages.properties and they are not being used when the page loads, so the form shows the labels always as my default locale.

In the picture below you can see that everything is in Dutch, except for the labels of my form. How should I approach this, am I missing a much easier way to accomplish this? Can I link the class-level validation message to a specific field?

enter image description here

If I put the form label messages in my messages_nl.properties as well then it works of course but I don't want to have those messages duplicated.


Solution

  • You only need to configure the LocalValidationFactoryBean

    <mvc:annotation-driven validator="validator" />
    
    <bean id="validator"
      class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
         <property name="validationMessageSource" ref="messageSource" />
    </bean>
    
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>WEB-INF/i18n/messages</value>
                <value>WEB-INF/i18n/application</value>     
                <value>classpath:ValidationMessages</value>
                               ....
            </list>
        </property>
        <property name="fallbackToSystemLocale" value="false"/>
    </bean>