Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return error status and validation errors from this Spring MVC controller?

I have an action method defined like this in one of my controllers:

@RequestMapping(method = RequestMethod.POST)
public @ResponseBody Post create(@Valid Post post, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        // how to return an error status + error messages from here?
    } else {
        postRepository.persist(post);
        return post;
    }
}

When the post is persisted successfully, I return the post back to the client. But when it has validation errors, I want to return an Error status code as well as all the validation error messages back to the client.

What's the best way to do this?

like image 594
K Everest Avatar asked Feb 18 '12 01:02

K Everest


People also ask

How do I show error messages in Spring?

Instead of passing a null argument for your error case, pass in a String . Spring is smart enough to see the String and write it as text to the response body. Alternatively, provide a @ExceptionHandler that will handle the exception itself and have your handler throw the exception.


1 Answers

Sine you are desigining a REST api, you need to create your own Pojo (aka. Resource) which will represent odd behaviour or validation errors, as stated by horaceman. I will show you how we do it in our application.

Since we are using JSON as a data representation, we wish to receive following information if unexpected exception occurs.

{ "status" : "EXCEPTION", "exceptionName" : "MyCustomException", "exceptionMsg" : "ex.unsupportedOperation" }

This is an example of course. Nice solution about it is that we can treat exceptionMsg as a key in our frontend to display proper i18n message or display it to the user as it is (in this case we use more descriptive messages).

Now, when everything is OK we do something like this:

{ "status" : "OK", "data" : {(...)} }

Data element is optional. We can send whatever we need to notify the frontend, or skip it totally.

The last scenario would be yours - validation errors. In this case we usually send following content:

{ "status" : "VALIDATION_FAILED", "errors" : [ "fieldName" : "username", "errorCode" : "validation.requiredField", "errorMsg" : "Username is required."] }

So clearly API clients will receive information that validation has failed and in proper fields - exact details about what went wrong. Of course errors is an array (or List), so we always provide as many details as necessary.

How I do it? Easy, those objects are simple POJOS which are translated to JSON using Jackson. This gives me unlimited possibilities of JSON representation. What I do, is I'm preparing POJO representing Validation errors (for instance) and add it as a Model to my ModelAndView instance. Then I just rely on Spring to do proper JSON marshaling.

In your case you have @ResponseBody annotation with your Post instance, so as far as I know you won't be able to do that. Your setup is saying "Well, no matter what happens - always return an instance of Post". What you should do, is to replace it with simple ModelAndView, supply it with proper Model based on validation and return it to the client API.

like image 67
ŁukaszBachman Avatar answered Sep 25 '22 18:09

ŁukaszBachman