What are the advantages of @ControllerAdvice over @ExceptionHandler or HandlerExceptionResolver for handling exceptions? What are the advantages of @ControllerAdvice over @ExceptionHandler or HandlerExceptionResolver for handling exceptions? spring spring

What are the advantages of @ControllerAdvice over @ExceptionHandler or HandlerExceptionResolver for handling exceptions?


@ExceptionHandler

@ExceptionHandler works at the Controller level and it is only active for that particular Controller, not globally for the entire application.

HandlerExceptionResolver

This will resolve any exception thrown by the application. It is used to resolve standard Spring exceptions to their corresponding HTTP Status Codes. It does not have control over the body of the response, means it does not set anything to the body of the Response.It does map the status code on the response but the body is null.

@ControllerAdvice

@ControllerAdvice used for global error handling in the Spring MVC application.It also has full control over the body of the response and the status code.


A @ExceptionHandler is local to a controller : only exceptions from this controller is routed to his @ExceptionHandler

But a @ControllerAdvice is global : you can have a centralized way to handle exceptions, binding, etc. it applies to all the defined controller.


Here is the difference:If I need to configure the exception handling code then I need to use @ExceptionHandler annotation in my project which can be used in two diff.ways: 1)To use the annotation and handle the exception in the same controller locally in each controller class. for eg:

@RestControllerpublic class WSExposingController{@GetMapping("/getAllDetails/{/id}")public UserDetails myMethod(@PathVariable int id){UserDetails user = UserDetailsService.getUser(id);return user;}//To handle the exceptions which are resulting from this controller, I can declare an exceptionHandler specifically in the same class@ExceptionHandler(Exception.class)public ResponseEntity handlerSameControllerExceptions(){return new ResponseEntity(null,HttpStatus.INTERNAL_SERVER_ERROR);}

}

2)If I create a new class which extends ResponseEntityExceptionHandler(SpringBoot class) and if I ANNOTATE IT WITH @ControllerAdvice then that class becomes globalexceptionhandler meaning to say that any exception which is resulting in any controller class can be handled here. And it can be present in any package in the same project.

@RestController@ControllerAdvicepublic class GlobalJavaExceptionHandler extends ResponseEntityExceptionHandler{    @ExceptionHandler(Exception.class)    public ResponseEntity handleDiffControllerExceptions(){        return new ResponseEntity(null,HttpStatus.INTERNAL_SERVER_ERROR);    }

If both are present in the code then the local with take precedence over the global one. Ideally the second option is a better one as we need not add the code in each and every controller class and this class with @ControllerAdvice can be a one stop solution for all the exceptions arising due to the code beginning from the controller to the dao throughout the length of the code.