According to DefaultMessageCodesResolver
In case of code "typeMismatch", object name "user", field "age"
- typeMismatch.user.age
- typeMismatch.age
- typeMismatch.int
- typeMismatch
So you should get (I suppose your commandName is called command and your property is age) Adapt according to your code
typeMismatch.command.age
typeMismatch.age
typeMismatch.java.lang.Integer
typeMismatch
Notice The third code
typeMismatch.java.lang.Integer
It will solve what you want
UPDATE
I have created a Person command class
public class Person implements Serializable {
private Integer age;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
And a person controller
public class PersonController extends SimpleFormController {
public PersonController() {
setCommandClass(Person.class);
setValidator(new Validator() {
public boolean supports(Class clazz) {
return clazz.isAssignableFrom(Person.class);
}
public void validate(Object command, Errors errors) {
rejectIfEmpty(errors, "age", "Age is required");
}
});
}
@Override
protected ModelAndView onSubmit(Object command) throws Exception {
return new ModelAndView();
}
}
Here goes my myMessages.properties (root of the classpath)
typeMismatch.command.age=typeMismatch.command.age
typeMismatch.age=typeMismatch.age
typeMismatch.java.lang.Integer=typeMismatch.java.lang.Integer
typeMismatch=typeMismatch
So, i have done the following test
public class PersonControllerTest {
private PersonController personController;
private MockHttpServletRequest request;
private MessageSource messageSource;
@Before
public void setUp() {
request = new MockHttpServletRequest();
request.setMethod("POST");
personController = new PersonController();
messageSource = new ResourceBundleMessageSource();
((ResourceBundleMessageSource) messageSource).setBasename("myMessages");
}
@Test
public void failureSubmission() throws Exception {
/**
* Ops... a bindException
*
* Age can not be a plain String, It must be a plain Integer
*/
request.addParameter("age", "not a meaningful age");
ModelAndView mav = personController.handleRequest(request, new MockHttpServletResponse());
BindingResult bindException = (BindingResult) mav.getModel().get(BindingResult.MODEL_KEY_PREFIX + "command");
for (Object object : bindException.getAllErrors()) {
if(object instanceof FieldError) {
FieldError fieldError = (FieldError) object;
assertEquals(fieldError.getField(), "age");
/**
* outputs typeMismatch.command.age
*/
System.out.println(messageSource.getMessage((FieldError) object, null));
}
}
}
}
If you want the second one, you must get rid of typeMismatch.command.age key resource bundle
typeMismatch.age=typeMismatch.age
typeMismatch.java.lang.Integer=typeMismatch.java.lang.Integer
typeMismatch=typeMismatch
Or write your own implementation of MessageCodesResolver
public class MyCustomMessageCodesResolver implements MessageCodesResolver {
private DefaultMessageCodesResolver defaultMessageCodesResolver = new DefaultMessageCodesResolver();
public String [] resolveMessageCodes(String errorCode, String objectName) {
if(errorCode.equals("age"))
/**
* Set up your custom message right here
*/
return new String[] {"typeMismatch.age"};
return defaultMessageCodesResolver.resolveMessageCodes(String errorCode, String objectName);
}
public void String[] resolveMessageCodes(String errorCode, String objectName, String field, Class fieldType) {
if(errorCode.equals("age"))
/**
* Set up your custom message right here
*/
return new String[] {"typeMismatch.age"};
return defaultMessageCodesResolver.resolveMessageCodes(String errorCode, String objectName, String field, Class fieldType);
}
}
And set up your PersonController
public class PersonController extends SimpleFormController {
public PersonController() {
setMessageCodesResolver(new MyCustomMessageCodesResolver());
setCommandClass(Person.class);
setValidator(new Validator() {
public boolean supports(Class clazz) {
return clazz.isAssignableFrom(Person.class);
}
public void validate(Object command, Errors errors) {
rejectIfEmpty(errors, "age", "Age is required");
}
});
}