Spring Boot validation message is not being resolved
It looks like you are missing LocalValidatorFactoryBean
definition in your application configuration. Below you can find an example of Application
class that defines two beans: LocalValidatorFactoryBean
and MessageSource
that uses messages.properties
file.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
@SpringBootApplication
public class Application {
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource());
return bean;
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Having LocalValidatorFactoryBean
bean defined you can use custom validation message like:
@NotEmpty(message = "{validation.mail.notEmpty}")
@Email
private String email;
and messages.properties:
validation.mail.notEmpty=E-mail cannot be empty!
and Thymeleaf template file with:
<p th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Name Error</p>
Sample application
https://github.com/wololock/stackoverflow-answers/tree/master/45692179
I have prepared sample Spring Boot application that reflects your problem. Feel free to clone it and run it locally. It will display translated validation message if value posted with form does not meet @NotEmpty
and @Email
validation.
WebMvcConfigurerAdapter
configuration
In case of extending WebMvcConfigurerAdapter
you will have to provide validator by overriding getValidator()
method from parent class, e.g.:
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
@Override
public Validator getValidator() {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource());
return bean;
}
// other methods...
}
Otherwise if you define LocalValidatorFactoryBean
bean in other place it will get overridden and there will be no effect.
I hope it helps.
I am using 2.2.7 Release of Spring boot and it worked by just changing the property file name to ValidationMessages.properties and no other config required.
Not sure which version of spring boot you are using. I am using Spring boot 2.0.1.RELEASE
. A clearer solution would be move all your validation messages to ValidationMessages.properties
. This way you don't have to override the auto-configured Validator()
and setting the MessageSource
.