Message parameters not resolved in localized Sprin

2020-07-30 09:59发布

问题:

I am building a project using Spring Boot 2.1.8, I have spring-boot-starter-web in my POM and I can see Maven pulling hibernate-validator 6.0.17 onto the classpath.

I have my messages in the resource folder and they appear to be looked up correctly so that when I change the locale Spring loads the message from the correct file.

The relevant method in my @RestController takes a @Valid and @RequestBody annotated DTO. It triggers the ResponseEntityExceptionHandler#handleMethodArgumentNotValid() to fire in my controller advice when the DTO fails validation.

My DTO has a field annotated in the following manner:

My messages.properties has the following entries:

This is how my message is written to the response:

As you can see the message parameters are not interpolated, instead the curly braces are stripped - the same happens when I use {0} instead of {min} or when I let the Size annotation use the default message - javax.validation.constraints.Size.message.

Can you please advise?

回答1:

This answer helped me a lot to understand where the issue was.

The gist is that Hibernate resolved messages end up as a default message in BindingResult.

Therefore one should either:

  1. Remove braces from custom defined messages and then use:
  String msg = messageSource.getMessage(e.getDefaultMessage(), e.getArguments(), locale);

To correctly lookup the messages interpolating all arguments.

OR

  1. Give up on custom defined messages altogether and rely on Spring message codes - e.g. for the Size annotation use Size.model.field in message.properties and the code to do the lookup e.g:
String msg = messageSource.getMessage(e, locale);

My expectation was that the default message from BindingResult would have a fully interpolated text but it appears that if the message is in braces Hibernate looks up the message in the bundle but does not interpolate parameters, instead sanitizing the string and stripping off any curly braces.