3

I'm using Spring MVC with Hibernate validator 4.2.0. have a ValidationMessages.properties on my class path in /WEB-INF/classes/ValidationMessages.properties:

typeMismatch.java.lang.Integer=Must specify an integer value.
typeMismatch.int=Invalid number entered
typeMismatch=Invalid type entered

This is made available as a bean in javaconfig:

@Configuration
@EnableWebMvc
public class WebApplicationConfiguration extends WebMvcConfigurerAdapter {
...

@Bean
public ReloadableResourceBundleMessageSource messageSource() {
    ReloadableResourceBundleMessageSource resourceBundleMessageSource = new ReloadableResourceBundleMessageSource();
    resourceBundleMessageSource.setBasename("ValidationMessages");
    return resourceBundleMessageSource;
}
...

which is loading ValidationMessages.properties from the class path fine. My Controller:

@Controller
public class myController {
...

@InitBinder("myForm")
protected void initUserBinder(WebDataBinder binder) {
    binder.setValidator(new CustomValidator());
}
...

@ResponseBody
@RequestMapping(value = "/ajax/myRequest", method = RequestMethod.POST)
public CustomResponse ProcessAjaxRequest(
        @Valid @ModelAttribute final MyForm myForm,
        final BindingResult bindingResult)
                throws Exception {

    if (bindingResult.hasErrors()) {
        return new CustomResponse(bindingResult.getAllErrors());
    } else {
        ..
    }
}
...

And a custom validator:

public class CustomValidator implements Validator {

@Override
public boolean supports(Class c) {
    return MyForm.class.equals(c);
}

@Override
public void validate(Object obj, Errors errors) {
..

Validation with my CustomValidator works fine (I insert the error messages manually, not using the message source), however for binding typeMismatch errors I get the exception:

Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Integer' for property 'myField'; nested exception is java.lang.NumberFormatException: For input string: "A"

rather than the code from ValidationMessages.properties, so it looks as though the DataBinder (?) is not using my messageSource. I want the typeMismatch codes from my properties file rather than the exception message. I have also tried with ResourceBundleMessageSource instead of ReloadableResourceBundleMessageSource but that didn't make any difference. Any ideas?

JimJay
  • 349
  • 2
  • 8
  • 17

1 Answers1

1

How do you get the error message? Is this work for you?

@Autowired
private MessageSource messageSource;
...

FieldError error = bindingResult.getFieldError("fieldName");
String errorMessage = messageSource.getMessage(error, Locale.getDefault());
Shinichi Kai
  • 4,415
  • 2
  • 21
  • 25
  • I'm using constructor injection rather than Autowired, but I get: Failed to convert property value of type java.lang.String to required type java.lang.Integer for property fieldName; nested exception is java.lang.NumberFormatException: For input string: "A" – JimJay May 20 '13 at 16:29
  • Looks like a problem with my bean definition? – JimJay May 20 '13 at 16:31
  • Your bean definition seems fine. Do you use getDefaultMessage() to get the error message? – Shinichi Kai May 20 '13 at 23:28
  • If you use getDefaultMessage(), you are not able to get your customized error message. Seems that Spring default implementation ([DefaultBindingErrorProcessor](https://github.com/SpringSource/spring-framework/blob/master/spring-context/src/main/java/org/springframework/validation/DefaultBindingErrorProcessor.java)) does not use MessageSource when it sets the default error message to the BindingResult object. – Shinichi Kai May 20 '13 at 23:33
  • Yes, this was the cause - DefaultBindingErrorProcessor does not use MessageSource when it sets the error message for binding errors. So I created my own custom DefaultBindingErrorProcessor with my MessageSource, and set WebDataBinder.setBindingErrorProcessor in my controller. – JimJay May 21 '13 at 13:34