I'm trying to get Hibernate Validator setup to use messages from a Spring MessageSource. I have the following setup in my messages-context.xml
:
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>WEB-INF/messages/messages</value>
<value>WEB-INF/messages/exceptions</value>
<value>WEB-INF/messages/fields</value>
<value>WEB-INF/messages/buttons</value>
<value>WEB-INF/messages/validation_errors</value>
</list>
</property>
</bean>
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource" ref="messageSource" />
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en_GB" />
</bean>
I've tried a variety of approaches to how to pass the message key to the hibernate validator (both with and without enclosing {} and also without specificying a custom key - just using the default one:
@NotEmpty(message="validation.required.field")
@Length(max=255, message="{validation.too.long}")
private String firstName;
@NotEmpty(message="{validation.required.field}")
@Length(max=255, message="{validation.too.long}")
private String lastName;
@NotNull
@Past(message="{validation.must.be.past}")
private Date dateOfBirth;
@NotEmpty(message="{validation.required.field}")
@Length(max=255, message="{validation.too.long}")
private String email;
My validation_errors_en_GB.properties
looks like this:
validation.required.field=this is a required field
validation.too.long=this field can only take {0} characters
validation.must.be.past=this date has to be in the past
javax.validation.constraints.NotNull.message=Custom message
However, when the empty fields are validated, the messages displayed are this:
First name validation.required.field
Last name {validation.required.field}
Date of birth may not be null
Email {validation.required.field}
For whatever reason, the key of the message is always used - the actual message is never looked up. Any idea where I'm going wrong?
Thanks,
Russell
Hibernate Validator is looking in a different place for the locale. Try this:
LocaleContextHolder.setLocale(locale);
This had me stumped for a while, but the problem is that you need to register with Spring the Validator used to validate @Controller methods (thanks to this answer for that insight!)
So if you are using XML config do something along these lines:
And if you are using javaconfig, do something like this:
(see Spring Web MVC framework documentation)
It's because Hibernate validator is looking at another place for the error message resolver.
For the easiest thing to make it works, I think you can create a file name "
ValidationMessages.properties
" and put it in your classpath folder. Then put the error messages into that file (got fromvalidation_errors_en_GB.properties
)By the way, the brackets are required when specifying error messages in model classes (
message="{validation.too.long}"
)This has worked for me.
Hibernate Validation is not aware of Spring's MessageSource. You will need to implement a MessageInterpolator. It may look something like below: