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 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.

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 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.

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.