if I define the following validation messages,
@Size(min = 3, message = "{validation.account.name}")
private String name;
I expect spring boot would read from messages*.properties
from classpath and find the validation.account.name
key to interpolate the message, but it just shows {validation.account.name}
on the page.
This https://github.com/Zane-XY/springboot-i18n-problem demos the problems.
Comment From: snicoll
We don't support that. Spring Framework does support it but only with the Hibernate validator implementation. That's interesting.
Comment From: php-coder
IMHO it should be easy to implement, like this:
public class MvcConfig extends WebMvcConfigurerAdapter {
@Inject
private MessageSource messageSource;
@Override
public Validator getValidator() {
LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();
factory.setValidationMessageSource(messageSource);
return factory;
}
}
Comment From: Zane-XY
Why this isn't part of https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/MessageSourceAutoConfiguration.java? at least Springboot documentation/references should mention what MessageSourceAutoConfiguration
has done, and how to enable reading from message sources.
Comment From: ghost
Good question. Is there an answer? And how do you make use of the MessageSourceAutoConfiguration?
Comment From: bigfatsea
I believe it's still an open issue https://jira.spring.io/browse/SPR-6380
Comment From: philwebb
Possibly relates to #7598
Comment From: selimok
It works.
To get it worked I have to move validation keys into the file ValidationMessages.properties while all oder messages reside in messages.properties.
FYI.
Comment From: snicoll
@selimok thanks for the feedback! FYI, you can remove all that code in 1.5 as we do that automatically.
Comment From: selimok
@snicoll removed :)
Comment From: ben3000
@snicoll I have upgraded my app to Spring Boot 1.5.1.RELEASE, but my validator messages are still only interpolated if I follow @selimok's solution. Have I missed something?
Comment From: snicoll
@ben3000 that the issue is still open?
Comment From: ben3000
OK, I thought as much. What does "FYI, you can remove all that code in 1.5 as we do that automatically." refer to?
Comment From: snicoll
A comment that, unfortunately, @selimok has removed (the creation of the validator if I remember) after I told him it was no longer necessary.
Comment From: JWebDev
I use Spring Boot 1.5.1.RELEASE and have the same problem. Tell me please, where I can look at a working solution? Thanks.
Comment From: jackstevenson
Overriding the auto-configured Validator
and setting the MessageSource
works for me.
ValidationConfig.java
@Configuration
public class ValidationConfig {
@Bean
public Validator validator(MessageSource messageSource) {
LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();
factory.setValidationMessageSource(messageSource);
return factory;
}
}
Person.java
public class Person {
@NotNull
private String name;
}
messages.properties
NotNull.person.name=Name must not be null
Comment From: philwebb
I have a feeling #8223 may have improved the MVC support but we probably still don't pick up messages.properties
. The docs for LocalValidatorFactoryBean
state that you can't specify both a validationMessageSource
and a messageInterpolator
. With #7598 we added a custom MessageInterpolator
so we can't just set the messageSource
directly.
Comment From: snicoll
Argh, that's quite bad news isn't it?
Comment From: gemunet
it work! in messages.properties
NotNull.person.name=Name must not be null
the class name (ex. person) must start with lowercase
Comment From: AaricChenLegacy
Solved by add ValidationMessages.properties
in classpath. this file is used by JSR303 implementation.
Comment From: szgaljic
@gemunet or @jackstevenson can you provide a full example of showing that this actually works? LocalValidatorFactoryBean does not help map the Spring Valdaiton codes (i.e., NotNull.*), it will only allow mapping to full javax.validation constraints default message (i.e., javax.validation.constraints.NotNull.message)
SO: https://stackoverflow.com/questions/49499891/spring-boot-mapping-validation-codes-to-messagesource-message
Comment From: juanalvarez123
If you are using the WebMvcConfigurerAdapter
see this post: https://stackoverflow.com/questions/45692179/spring-boot-validation-message-is-not-being-resolved
It says:
In case of extending WebMvcConfigurerAdapter you will have to provide validator by overriding getValidator() method from parent class:
@Configuration
@EnableWebMvc
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
@Bean(name = "validationMessageResource")
public MessageSource getReloadableResourceBundleValidationMessageSource() {
ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource = new ReloadableResourceBundleMessageSource();
reloadableResourceBundleMessageSource.setBasename("classpath:exceptionmessages");
reloadableResourceBundleMessageSource.setDefaultEncoding("UTF-8");
return reloadableResourceBundleMessageSource;
}
@Bean(name = "validator")
@Override
public LocalValidatorFactoryBean getValidator() {
final LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setValidationMessageSource(getReloadableResourceBundleValidationMessageSource());
return localValidatorFactoryBean;
}
}
This is super important. Previously I was defining the validator
in a different bean. That was causing that the validator
that I wanted to use never was setting as default. Then, I moved the validator
bean where the WebMvcConfigurerAdapter
was extending, overridden the getValidator()
method, and it worked.
Comment From: wilkinsona
@juanalvarez123 Thanks for trying to help people out. One word of caution, though. It's unusual to have @EnableWebMvc
in a Spring Boot application as it will switch off all of Boot's auto-configuration of Spring MVC. A WebMvcConfigurer
without @EnableWebMvc
is much more common.
Comment From: drenda
Hi, I'm trying to figure out what is the current situation about this issue. I'm using Spring Boot 2.1.4 and I'm struggling on this topic. I'm using this config right now:
@Configuration
@EnableRetry
@EnableTransactionManagement
@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
public class CustomConfiguration {
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasenames("classpath:/i18n/messages");
messageSource.setUseCodeAsDefaultMessage(false);
messageSource.setCacheSeconds((int) TimeUnit.HOURS.toSeconds(1));
messageSource.setFallbackToSystemLocale(false);
return messageSource;
}
@Bean
public MessageSourceAccessor messageSourceAccessor() {
return new MessageSourceAccessor(messageSource());
}
@Bean
public Validator validator() {
LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
factoryBean.setValidationMessageSource(messageSource());
return factoryBean;
}
and
@Configuration
@EnableHypermediaSupport(type = {HypermediaType.HAL})
public class WebMvcConfiguration implements WebMvcConfigurer {
private Validator validator;
@Autowired
public WebMvcConfiguration(Validator validator) {
this.validator = validator;
}
@Override
public Validator getValidator() {
return validator;
}
but still I've to follow @selimok hint: I have to move all validation keys in ValidationMessages.properties
and all other keys in messages.properties
.
Is this the indented behaviour? Can someone point out what is the "right" way to do this right now, until this issues is not resolved? Thanks
Comment From: Muyangmin
I'm using SpringBoot 2.1.6.RELEASE
and met this problem too. It only works with @selimok 's solution(use hardcoded ValidationMessages.properties
file).
What I'm very confused is that: why messageSource.getMessage("{prop}")
is OK but @Min(message="{prop}")
not ?
Thanks for any advise or explaination.
Comment From: spc16670
My problem was with parameter interpolation:
https://stackoverflow.com/questions/58257635/message-parameters-not-resolved-in-localized-spring-boot-validation-messages/58277267
Is lack of parameter interpolation in BindingResult's default message the expected behaviour?
Comment From: farukonfly
I'm using SpringBoot
2.1.6.RELEASE
and met this problem too. It only works with @selimok 's solution(use hardcodedValidationMessages.properties
file).What I'm very confused is that: why
messageSource.getMessage("{prop}")
is OK but@Min(message="{prop}")
not ?Thanks for any advise or explaination.
only works with @selimok 's solution Is there any other better solution in the new version?
Comment From: wilkinsona
Closing in favor of #17530.
Comment From: onlinefavorites
If someone still has the same issue, you can override Hibernate's validator configuration as following:
@Configuration
public class CustomBeanConfiguration {
@Bean
public Validator getValidator() {
return Validation.byDefaultProvider()
.configure()
.messageInterpolator(
new ResourceBundleMessageInterpolator(
new AggregateResourceBundleLocator(
Arrays.asList(
"messages",
"config/error-messages",
"config/another-error-messages"
)
)
)
)
.buildValidatorFactory()
.getValidator();
}
}
Comment From: onlinefavorites
I'm using SpringBoot
2.1.6.RELEASE
and met this problem too. It only works with @selimok 's solution(use hardcodedValidationMessages.properties
file).What I'm very confused is that: why
messageSource.getMessage("{prop}")
is OK but@Min(message="{prop}")
not ?Thanks for any advise or explaination.
messageSource.getMessage("{prop}")
is inside spring configuration context, when you are using hibernate Validator to validate @Min(message="{prop}")
you have to configure Hibernate's validator as described above.