I'm trying to override default ResourceBundleLocator in hibernate validation 4.1. So far it works perfectly, but the only examples of its usage include java code to instantiate ValidationFactory.
When using a web application with spring hibernate validation is automatically configured (only the suitable hibernate validation *.jar file should exist and it is automatically used). How can i substitute ResourceBundleLocator in that scenario? I do not see any way of specyfing my custom ResourceBundleLocator in any properties or applicationContext.xml file.
The magic method that does the required job is LocalValidatorFactoryBean#setValidationMessageSource(MessageSource messageSource).
First of all, contract of the method:-
Specify a custom Spring MessageSource for resolving validation messages, instead of relying on JSR-303's default "ValidationMessages.properties" bundle in the classpath. This may refer to a Spring context's shared "messageSource" bean, or to some special MessageSource setup for validation purposes only.
NOTE: This feature requires Hibernate Validator 4.1 or higher on the classpath. You may nevertheless use a different validation provider but Hibernate Validator's ResourceBundleMessageInterpolator class must be accessible during configuration.
Specify either this property or "messageInterpolator", not both. If you would like to build a custom MessageInterpolator, consider deriving from Hibernate Validator's ResourceBundleMessageInterpolator and passing in a Spring MessageSourceResourceBundleLocator when constructing your interpolator.
You can specify your custom message.properties(or .xml) by invoking this method... like this...
my-beans.xml
<bean name="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource">
<ref bean="resourceBundleLocator"/>
</property>
</bean>
<bean name="resourceBundleLocator" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>META-INF/validation_errors</value>
</list>
</property>
</bean>
validation_errors.properties
javax.validation.constraints.NotNull.message=MyNotNullMessage
Person.java
class Person {
private String firstName;
private String lastName;
@NotNull
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
BeanValidationTest.java
public class BeanValidationTest {
private static ApplicationContext applicationContext;
@BeforeClass
public static void initialize() {
applicationContext = new ClassPathXmlApplicationContext("classpath:META-INF/spring/webmvc-beans.xml");
Assert.assertNotNull(applicationContext);
}
@Test
public void test() {
LocalValidatorFactoryBean factory = applicationContext.getBean("validator", LocalValidatorFactoryBean.class);
Validator validator = factory.getValidator();
Person person = new Person();
person.setLastName("dude");
Set<ConstraintViolation<Person>> violations = validator.validate(person);
for(ConstraintViolation<Person> violation : violations) {
System.out.println("Custom Message:- " + violation.getMessage());
}
}
}
Outupt: Custom Message:- MyNotNullMessage
Thank you @Lu55, based on your answer I solved my problem!!
I just converted to a Configuration class, and I am posting here just in case anyone else need:
Import detail: it worked for me with ReloadableResourceBundleMessageSource, but it did not work using ResourceBundleMessageSource. I am not sure why.
@Configuration
public class ErrorConfig {
@Bean
public Validator validatorFactory (MessageSource messageSource) {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource);
return validator;
}
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
bean.addBasenames("classpath:org.hibernate.validator.ValidationMessages","classpath:message");
bean.setDefaultEncoding("UTF-8");
return bean;
}
}
Inside my resource folder I have message.properties file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With