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

Spring 3.2 introduces the @ControllerAdvice annotation for handling exceptions in a Spring MVC application. But prior to this version, Spring had @ExceptionHandler or HandlerExceptionResolver exception handling in a Spring MVC application. Then why did Spring 3.2 introduce the @ControllerAdvice annotation for exception handling? I strongly believe Spring 3.2 introduced the @ControllerAdvice annotation to remove @ExceptionHandler or HandlerExceptionResolver or simplify exception handling.

Can @ControllerAdvice explain the benefits of @ControllerAdvice over @ExceptionHandler or HandlerExceptionResolver for handling exceptions?

+5
source share
4 answers

@ExceptionHandler

@ExceptionHandler works at the controller level and is active only for this particular controller, not for the entire application.

HandlerExceptionResolver

This will resolve any exception thrown by the application. It is used to resolve standard Spring exceptions in their respective HTTP status codes . He has no control over the body of the response, which means he does not install anything in the body of the Response . It displays the status code in the response, but the body is null .

@ControllerAdvice

@ControllerAdvice used to globally handle errors in a Spring MVC application. It also has full control over the response body and status code.

+14
source

A @ExceptionHandler is local to the controller: only exceptions from this controller are routed to its @ExceptionHandler

But a @ControllerAdvice is global: you can have a centralized way to handle exceptions, bindings, etc., it applies to the whole specific controller.

+5
source

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

 @RestController public 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 that extends ResponseEntityExceptionHandler (SpringBoot class), and if I ANNOTATION @ControllerAdvice, then this class becomes a globalexceptionhandler, which means that any exception that leads to any controller class can be handled here. And he can be present in any package in the same project.

@RestController @ControllerAdvice Public 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. 
+1
source

@ExceptionHandler can be used locally or globally. The local level will mean the use of this annotation inside the controller itself to handle exceptions only in this controller. All errors caused by this controller will be detected by this @ExceptionHandler. But this will mean that if there is a similar exception in the other controller, you will have to rewrite the corresponding code in this controller locally again.

To prevent this exception handling style from repeating to the controller, we can write @ExceptionHanlder globally with another annotation called @ControllerAdvice.

@ControllerAdvice does not apply to exception handling, and is also used to handle property bindings, validation, or formatting globally. @ControllerAdvice in the context of exception handling is another way to handle exceptions globally using the @Exceptionhandler annotation.

Now moving to HandlerExceptionResolver is a lower level interface. Spring provides 2 implementations of this:

  • ResponseStatusExceptionResolver: supports @ResponseStatus annotation support
  • ExceptionHandlerExceptionResolver: supports @ExceptionHandler annotation

Example. Therefore, when you want to handle exceptions and choose an exception handling strategy, you need to think about choosing between using local or global exception handling using annotations. How do you need to provide HTTP status codes, how to wrap it in an @Response object, etc., How do you want to redirect to handler pages, transfer data using flash attributes or get parameters, etc. Etc. Or perhaps skip annotations and use SimpleMappingExceptionResolver and start mapping specific exceptions to the URLs of the error handler page

Here we will not consider the lower level that underlies the HandlerExceptionResolver at this stage, since we are dealing with its implementation at a higher level and create a strategy based on these parameters.

In the context above, to respond to your request - @ControllerAdvice was not introduced to handle exceptions, it is a mechanism that you can use to handle exceptions globally with @ExceptionHandler. HandlerExceptionResolver is an interface whose implementation helps support @ResponseStatus and @Exceptionhandler annotations. Unless you want to handle MVC-related exceptions, as the Spring framework does not provide proper exception handling. Therefore, if you need to pass e problems related to incorrect @Requestmapping, etc., which would not be caught by the controller, since it would not even reach it in the 1st place, then it would be useful to implement HandlerExceptionResolver

0
source

Source: https://habr.com/ru/post/1242723/


All Articles