Alexey
Alexey

Reputation: 2582

Getting details of binding errors for a JSON form in Spring MVC

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

Answers (2)

Sotirios Delimanolis
Sotirios Delimanolis

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

Jukka
Jukka

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

Related Questions