Reputation: 2582
I use Spring MVC 3.2.4. I have a controller method that receives data from an HTML form. The method has the following signature:
@RequestMapping(...)
public String updateProduct(@Valid Product product, BindingResult bindingResult)
In the method, I can get information about both data binding (e.g., a non-integer value in an integer field) and validation (JSR-303) errors in the following way:
if (bindingResult.hasErrors()) {
List<FieldError> errors = bindingResult.getFieldErrors();
for (FieldError error : errors) {
System.out.println(error.getObjectName() + " - " + error.getCode());
}
}
I want to change this method so that it could receive data in JSON format instead of application/x-www-form-urlencoded
. I added @RequestBody
annotation to the method signature:
@RequestMapping(...)
public String updateProduct(@Valid @RequestBody Product product, BindingResult bindingResult)
In the updated method I still can get all validation errors in the same way. However, data binding errors generate an HttpMessageNotReadableException
. The exception seems to have no properties for accessing things like the error code and field/object name. Besides, the exception prevents the JSR-303 validation, and the user does not receive any JSR-303 validation messages till the next data submission.
How can I get the information about data binding errors when I implement a controller method that receives JSON?
UPDATE:
One workaround that I can think of is changing all fields in the Product
class to String
and then validating them with JSR-303. This way, no data binding errors will ever happen. But I will have to create a clone of the Product
class with proper data types.
Upvotes: 6
Views: 6219
Reputation: 279910
Don't get confused, HttpMessageNotReadableException
has nothing to do with validation errors. It gets thrown when an HttpMessageConverter
cannot read an HttpInputMessage
. With JSON, that probably means MappingJackson2HttpMessageConverter
. It will throw that exception if something goes wrong while deserializing the JSON into an instance of whatever type you specified, Product
in this case. This can happen if the JSON is malformed.
You cannot catch those errors in a BindingResult
.
Upvotes: 4
Reputation: 4663
You ought to be using @RequestBody there. With that, validation errors will throw MethodArgumenNotValidException which you can handle in an @ExceptionHandler annotated method and return the validation error(s) in e.g. a JSON error object.
Upvotes: 1