Spring Boot validation message is not being resolved

Viewed 51443

I am having trouble getting my validation message to be resolved.

I have been searching and reading through the web and SO for some hours now, I want to relate the question with the marked answer of Customize spring validation error

I do have a MessageSource bean defined and the messages.properties it getting read correctly, as I also use it for regular text to be displayed with th:text="#{some.prop.name}, which does work absolutely fine. It is just the validation error that won't work the way it should. I'm sure it's a stupid mistake I just overlook... The validation itself works fine.

Constraint:

@NotEmpty(message="{validation.mail.notEmpty}")
@Email()
private String mail;

messages.properties:

# Validation
validation.mail.notEmpty=The mail must not be empty!

Template part:

<span th:if="${#fields.hasErrors('mail')}" th:errors="*{mail}"></span>

The displayed text:

{validation.mail.notEmpty}

I tried a lot of variation, all without success.

@NotEmpty(message="validation.mail.notEmpty")
@NotEmpty(message="#{validation.mail.notEmpty}")

Will just show the exact value of the messages string, no parsing.

<span th:if="${#fields.hasErrors('mail')}" th:errors="${mail}"></span>
<span th:if="${#fields.hasErrors('mail')}" th:errors="#{mail}"></span>
<span th:if="${#fields.hasErrors('mail')}" th:errors="#{*{mail}}"></span>
<span th:if="${#fields.hasErrors('mail')}" th:errors="#{__*{mail}__}"></span>

Will result in an error.


EDIT:

After debugging, I stumbled up on this:

Class: org.springframework.context.support.MessageSourceSupport

Method: formatMessage(String msg, Object[] args, Locale locale)

will be called with

formatMessage("{validation.mail.notEmpty}", null, locale /*German Locale*/)

And it will run into if (messageFormat == INVALID_MESSAGE_FORMAT) {

So... my message format is not correct. This is way out of my scope/knowledge. Anyone knows what that means?

8 Answers

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.

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.

I had the same issue and after reading the answers here I found out that the file name should only be 'ValidationMessages.properties'. I first named it something else and it wasn't working for me either. until I renamed it to ValidationMessages.properties

regarding to the answer of Wais Shuja and Ramesh Singh I confirm with it because I think this is the proper solution you looking for. I expand their answer:

In folder /resources/ you can create as much files as languages you are support. In my web app I use German and English. Therefore, I create these two files:

 - ValidationMessages_en.properties
 - ValidationMessages_de.properties

Then, thanks to Spring magic, you can do this:

@NotNull(message = "{error.mandatory}")
@Size(min = 1, message = "{error.mandatory}")
private String forname;

Depending on the language stored in the CookieLocaleResolver Spring chooses appropriate file and inserts the text.

For rest controllers you will then have to add @Valid annotation on method parameter's request body. e.g

@PostMapping
public User create(@Valid @RequestBody User user){
  //...
}
@Configuration
public class LocalizationMessageSource {

    @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;
    }
}

And you should validation anotation with blank beyween message parameter like this ;

public class User{
  private @NotNull(message = "{serviceNumber.required}") String serviceNumber;

}

This usage is wrong one.

public class User{
  private @NotNull(message="{serviceNumber.required}") String serviceNumber;  
}

after struggling with this problem ,i just reboot the computer and everything works fine i am using spring boot version 2.4.2

Related