1

I have a Spring Boot REST server which should return specific error codes when invalid input is provided. I don't need any i18n here, just plain English error codes like 'missing' is sufficient.

Using Spring Boot with Hibernate Validator, after validation I get a back Spring Errors object.

For each error I can get the code and defaultMessage. For a @NotBlank constraint this would return NotBlank and may not be null resp.

Basically I want to translate this error to just missing as I'm not interested in i18n translation. Also other constraints I want to more REST friendly error codes.

I though to use use a simple messages.properties or ValidationMessages.properties inside src/main/resources but this wouldn't work unfortunately. Note I tried both adding a general NotBlank=missing and specific NotBlank.entity.field=missing properties.

I'm not sure why it's not working... maybe because resolving i18n messages (in jsp world) does not go directly via Spring Errors but through the MessageCodesResolver implementation (just guessing).

Probably I could get the error code from the Spring Error and do a lookup from the message code resolver. But I wonder why error.getDefaultMessage does not return the appropriate value form the ValidationMessages.properties.

Any suggestion is welcome.

6
  • Because error.getDefaultMessage gets the default message and that is the message as generated by code not from properties files. If you look at the MessageSource.getMessage method you see that the defaultMessage is passed in. The same mechanism is used when using validation. Commented Dec 30, 2014 at 21:51
  • Thx for explanation! What would you suggest to go forward? Commented Dec 30, 2014 at 21:58
  • You can just pass the error (as is) to the MessageSource the errors as returned from the Errors object are all instances of MessageSourceResolvable. So just iterate over the errors, pass them to the MessageSource and get the message you want from the messages.properties. Maybe you could gentrify this logic and put it in a class that generates a response object. Commented Dec 30, 2014 at 22:17
  • Yes as I suggested myself. Thx! Commented Dec 30, 2014 at 22:19
  • Well you suggested to use the code, you don't have to do that, just pass the object as is. Commented Dec 30, 2014 at 22:19

1 Answer 1

1

The default message is the message as stated by the programmer. In the case of those JSR-303 annotations probably the ones as Hibernate thought of them. The default message including the code is passed to the MessageSource.getMessage method, which contains a parameter defaultMessage

When you look at the Errors object or actually the ObjectError method you will see that it implements the MessageSourceResolvable interface. This means you can just pass the error, as is, to the MessageSource, including the Locale if you want.

@RequestMapping public Object foo(@Valid @RequestBody MyObject obj, Errors errors, Locale locale) { for (ObjectError err : errors.getAllErrors()) { String msg = messageSource.getMessage(err, locale); // Do something with msg } } 

Something like the above should resolve the message. The advantage of using the ObjectError itself is that next to the code you also have the parameters (for @Range or @Min) which you can then use in your message with placeholders.

Sign up to request clarification or add additional context in comments.

4 Comments

Ps hibernate validator default messages should be overridden via ValidationMessages.properties but seems not to work (within Spring app at least). See also docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/…
Correct because that overrides that mechanism so that a MessageSource can be used. The ValidationMessages.properties apply in a plain JSR-303. This is explained in the LocalValidatorFactoryBean javadoc.
Hmm would it be possible to change this behavior in Spring? So to use ValidationMessages.properties?
Are we able to auto resolve the error message without injecting message source and locale in every of the controllers? This is really troublesome, because I can do it in hibernate annotation but why Spring validator is not working.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.