I have an controller that returns JSON. It takes a form, which validates itself via spring annotations. I can get FieldError list from BindingResult, but they don't contain the text that a JSP would display in the tag. How can I get the error text to send back in JSON?
@RequestMapping(method = RequestMethod.POST) public @ResponseBody JSONResponse submit(@Valid AnswerForm answerForm, BindingResult result, Model model, HttpServletRequest request, HttpServletResponse response) { if (result.hasErrors()) { response.setStatus(HttpServletResponse.SC_BAD_REQUEST); JSONResponse r = new JSONResponse(); r.setStatus(JSONResponseStatus.ERROR); //HOW DO I GET ERROR MESSAGES OUT OF BindingResult??? } else { JSONResponse r = new JSONResponse(); r.setStatus(JSONResponseStatus.OK); return r; } }
JSONREsponse class is just a POJO
public class JSONResponse implements Serializable { private JSONResponseStatus status; private String error; private Map<String,String> errors; private Map<String,Object> data; ...getters and setters... }
Calling BindingResult.getAllErrors() returns an array of FieldError objects, but it doesn't have the actual errors.
Disclaimer: I still do not use Spring-MVC 3.0
But i think the same approach used by Spring 2.5 can fullfil your needs
for (Object object : bindingResult.getAllErrors()) { if(object instanceof FieldError) { FieldError fieldError = (FieldError) object; System.out.println(fieldError.getCode()); } if(object instanceof ObjectError) { ObjectError objectError = (ObjectError) object; System.out.println(objectError.getCode()); } }
I hope it can be useful to you
UPDATE
If you want to get the message provided by your resource bundle, you need a registered messageSource instance (It must be called messageSource)
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames" value="ValidationMessages"/> </bean>
Inject your MessageSource instance inside your View
@Autowired private MessageSource messageSource;
And to get your message, do as follows
for (Object object : bindingResult.getAllErrors()) { if(object instanceof FieldError) { FieldError fieldError = (FieldError) object; /** * Use null as second parameter if you do not use i18n (internationalization) */ String message = messageSource.getMessage(fieldError, null); } }
Your Validator should looks like
/** * Use null as fourth parameter if you do not want a default message */ errors.rejectValue("<FIELD_NAME_GOES_HERE>", "answerform.questionId.invalid", new Object [] {"123"}, null);
I met this problem recently, and found an easier way (maybe it's the support of Spring 3)
List<FieldError> errors = bindingResult.getFieldErrors(); for (FieldError error : errors ) { System.out.println (error.getObjectName() + " - " + error.getDefaultMessage()); }
There's no need to change/add the message source.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With