2

I'm creating a simple Spring REST application and following is my spring configuration class;

@Configuration
@EnableWebMvc
@ComponentScan( basePackages = "com.example.spring" )
public class AppConfig {    
    @Bean
    public ReloadableResourceBundleMessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:/messages");
        return messageSource;
    }   
}

And this is what i have done in my controller class;

@RequestMapping(value = "/create", method = RequestMethod.POST)
    public ResponseEntity<Map<String, String>> createEmployee(@Valid @RequestBody EmployeeModel employeeModel, BindingResult result) {
        if (result.hasErrors()) {
            System.out.println("Errors: " + result.getAllErrors());
            Map<String, String> response = new HashMap<>();
            response.put("status", "failure");
            return new ResponseEntity<>(response, HttpStatus.OK);
        }
        employeeService.createEmployee(employeeModel);
        Map<String, String> response = new HashMap<>();
        response.put("status", "success");
        return new ResponseEntity<>(response, HttpStatus.OK);
    }

I have annotated my name field in EmployeeModel as below;

@NotEmpty
@Column(name = "name")
private String name;

And this is my messages.properties file which is in the src/main/resources folder.

NotEmpty.employeeModel.name = Employee name is required.

But i'm not able to read this error message i'm getting only the default message for @NotEmpty.

I even tried with the following configuration;

@Bean
public MessageSource messageSource() {
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setBasename("classpath:/messages");
    return messageSource;
}

Kindly help me with this!

karthi
  • 549
  • 3
  • 15
  • 26
  • 1
    did you ever get an answer to this? I have the exact same problem and none of the suggestions below fix it. – szxnyc Mar 26 '18 at 22:04

5 Answers5

3

Well, maybe a little late, but this definitely worked for me.

Try to change your MessageSource config for this one:

@Bean
public MessageSource messageSource() {
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    messageSource.setBasenames("classpath:/messages");
    messageSource.setUseCodeAsDefaultMessage(false);
    messageSource.setCacheSeconds((int) TimeUnit.HOURS.toSeconds(1));
    messageSource.setFallbackToSystemLocale(false);
    return messageSource;
}

And your LocalValidatorFactoryBean should be the same as you've already defined it.

@Bean
public LocalValidatorFactoryBean validator() {
    final LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
    localValidatorFactoryBean.setValidationMessageSource(messageSource());
    return localValidatorFactoryBean;
}

I tested using Spring 5.0.1.Final and Hibernate Validator 5.4.2.Final versions.

Jose-Rdz
  • 539
  • 6
  • 14
  • This does not work. If you have it running somehow can you share the entire code somewhere like github? – szxnyc Mar 26 '18 at 22:06
  • This works, you might want to inspect the configuration in this [working project](https://github.com/Jose-Rdz/spingere/tree/master/spingere). Before casting a negative vote perhaps you should make an effort on testing and sharing your results and not to expect others to try for you. – Jose-Rdz Apr 10 '18 at 17:51
  • 1
    I did. [Here](https://stackoverflow.com/questions/49499891/spring-boot-mapping-validation-codes-to-messagesource-message) and [Here](https://github.com/JahnelGroup/spring-boot-samples/tree/master/spring-boot-validation). I came to conclusion that this only applies to Spring MVC (just like your example). This does NOT apply for regular Json payload's (i.e., REST API). In order to make that I work I had to write my own code, see [here](https://github.com/JahnelGroup/jts-auction/tree/3-validations/src/main/java/com/jahnelgroup/auctionapp/exception/message). – szxnyc Apr 10 '18 at 19:05
  • Well if I'm getting your point from _regular JSON payloads_... you can find a working validation example for JSON payloads [here](https://github.com/Jose-Rdz/spingere/blob/master/spingere/src/main/java/com/spingere/controller/UsuariosController.java) on methods using `@RequestBody`... there's no such difference about Spring MVC and REST API... btw if you consider your code the right approach maybe you could post your answer so others can benefit from it... – Jose-Rdz Apr 11 '18 at 15:28
  • 1
    This helped me! I experienced issue reported in the question after upgrading spring (and sprig security) from 3 to 5 and hibernate from 5 to 6 and much more minor upgrades.... messages from properties file started not being found and not being displayed (before the upgrade it worked) THANKS! – supertramp Oct 30 '18 at 22:58
1

Might help if still open. Bumped on this for a similar case where i solved it by using the Interpolator explicitly:

 <!-- Messagesource for locales -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
            <util:list>
                <value>classpath:locales/messages/validation</value>
            </util:list>
        </property>
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>

    <bean id="resourceBundleMessageInterpolator"
          class="org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator">
        <constructor-arg index="0">
            <bean class="org.springframework.validation.beanvalidation.MessageSourceResourceBundleLocator">
                <constructor-arg index="0" ref="messageSource"/>
            </bean>
        </constructor-arg>
    </bean>

    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="messageInterpolator" ref="resourceBundleMessageInterpolator"/>
    </bean>

    <mvc:annotation-driven validator="validator" />

as opposite to what also suggested in other threads given the supposed automatic injection via:

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="validationMessageSource" ref="messageSource"/>
</bean>

With the above i managed to use placeholders in the validation property files by using brackets as well: i.e.:

@NotNull(message = "{message.notnull}")

Also the following threads hints were a must to me:

Why Spring Message Interpolation Argument Replacement using Hibernate Validator don't work? How to use annotation validation in Spring with error message gotten from properties file?

TheSees
  • 21
  • 1
0

You need to tell validator to use your messageSource.

@Bean
public javax.validation.Validator validator() {
    final LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();
    factory.setValidationMessageSource(messageSource());
    return factory;
}

@Bean
public ReloadableResourceBundleMessageSource messageSource() {
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    messageSource.setBasename("classpath:/messages");
    return messageSource;
}

And specify the message key on your model:

@NotEmpty(message = "{NotEmpty.employeeModel.name}")
private String name;
Bohdan Levchenko
  • 3,411
  • 2
  • 24
  • 28
0

old question, but this worked for me:

    @Bean
    public LocalValidatorFactoryBean localValidatorFactoryBean(final MessageSource messageSource) {
        final LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
        localValidatorFactoryBean.setValidationMessageSource(messageSource);
        return localValidatorFactoryBean;
    }
John Tribe
  • 1,407
  • 14
  • 26
0

After doing everything right, applying all the fixes mentioned on Stack Overflow and spending hours just to get it to work, I was finally able to fix it by adding below on my messages.properties file

"# suppress inspection "UnusedProperty" for whole file"

Note I am using intellij and for some weird reason it was not reading my messages.

Rahul
  • 11
  • 2
  • https://www.jetbrains.com/help/idea/resource-bundle.html we need to disassociate the bundle folder from intellij. follow this your issue will be resolved. – Manigandan Saravanan Aug 11 '23 at 07:38