I have a Spring controller annotated with @RestController
and it is returning JSON. I also have a class annotated with @ControllerAdvice
with @ExceptionHandler
s related to some custom exceptions. I am using Tomcat to serve this RESTful API. I'd like to have any non-custom exception such as one coming from a 3rd party library or a NullPointerException be caught and returned with status 500 - Internal Server Error as JSON with a message instead of an HTML page showing the error.
If I use an @ExceptionHandler(Exception.class)
in the controller advice it takes over all of Spring exceptions like MissingPathVariableException.class, which is not ideal. I've tried extending Spring's ResponseEntityExceptionHandler but this class is not annotated with @ResponseBody so does not return JSON.
Spring MVC Framework provides following ways to help us achieving robust exception handling. Controller Based - We can define exception handler methods in our controller classes. All we need is to annotate these methods with @ExceptionHandler annotation. This annotation takes Exception class as argument.
The differences between @RestControllerAdvice and @ControllerAdvice is : @RestControllerAdvice = @ControllerAdvice + @ResponseBody . - we can use in REST web services. @ControllerAdvice - We can use in both MVC and Rest web services, need to provide the ResponseBody if we use this in Rest web services.
Spring MVC provides exception handling for your web application to make sure you are sending your own exception page instead of the server-generated exception to the user. The @ExceptionHandler annotation is used to detect certain runtime exceptions and send responses according to the exception.
The @RestControllerAdvice annotation is specialization of @Component annotation so that it is auto-detected via classpath scanning. It is a kind of interceptor that surrounds the logic in our Controllers and allows us to apply some common logic to them.
For returning JSON on uncaught exceptions you can use this code:
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
@ControllerAdvice
@RestController
public class GlobalExceptionHandler {
private class JsonResponse {
String message;
public JsonResponse() {
}
public JsonResponse(String message) {
super();
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
@ExceptionHandler(value = Exception.class)
public ResponseEntity<JsonResponse> handleException(Exception e) {
return new ResponseEntity<JsonResponse>(new JsonResponse(e.getMessage()), HttpStatus.BAD_REQUEST);
}
}
JSON result if exception is throwing:
{
"message": "Something wrong!"
}
You can use this link for more detailed information about Spring exception handling (with code examples).
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