@ExceptionHandler
and @ControllerAdvice
both annotations are used in Exception handling in SpringBoot. SpringBoot Makes the exception handling easily.
@ControllerAdvice: It is an Informer to Spring Controller saying that it has the ExceptionHandler methods so that the methods can be scanned and used across the application to handle the exception properly.
@ExceptionHandler: It is a Global Exception Handler, capture the Exceptions and translate it as HTTP responses. It also represents what types of Exceptions are to be handled. it has arguments through which it accepts the exception instances and the request
@ControllerAdvice Annotation in Spring Boot :
In the default mechanism, @ControllerAdvice
will be applied in all the classes, those are marked with @controller
annotation
package com.cms.common.exception; @ControllerAdvice public class CustomExceptionHandler { //code goes here }
To apply only to specific packages
package com.cms.common.exception; @ControllerAdvice @ControllerAdvice(value = "com.cms.common") @ControllerAdvice(basePackages = "com.cms.common") public class CustomExceptionHandler { //code goes here }
If you want to apply the @ControllerAdvice
only to the specific class then use the parameter assignableTypes
.
package com.cms.common.exception; @ControllerAdvice @ControllerAdvice(assignableTypes = SampleClass.class) public class CustomExceptionHandler { //code goes here }
In the above example, the ControllerAdvice will apply only to the class SampleClass
.
To apply the @ControllerAdvice
basis on the Class hierarchy, mention the parameter as basePackageClasses
, this means the spring-boot looks for the Controller Classes where SampleClass
is linked in.
package com.cms.common.exception; @ControllerAdvice @ControllerAdvice(basePackageClasses = SampleClass.class) public class CustomExceptionHandler { //code goes here }
Well, after all, @ControllerAdvice has great support to apply the exception control over the annotations, for example, if you mention the annotation name, the handlers will be supported wherever the annotation is being used across the application.
package com.cms.common.exception; @ControllerAdvice @ControllerAdvice(annotations = RestController.class) public class CustomExceptionHandler { //code goes here }
The above example applies to all the classes containing the annotation @RestController
@ExceptionHandler Annotation in Spring Boot :
ExceptionHandler is the implementation of @ControllerAdvice
annotation. It is used to define the method with the annotation
of @ExceptionHandler
. and the job of this method is used to catch the exceptions and do the necessary actions over it.
@ExceptionHandler(Exception.class) public final ResponseEntity(Object) handleAllExceptions(Exception ex, WebRequest request) { }
Below are the example of using @ExceptionHandler
and @ControllerAdvice
package com.cms.common.exception; import java.util.HashMap; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; 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.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; @ControllerAdvice public class CustomExceptionHandler extends ResponseEntityExceptionHandler { /** The env. */ @Autowired private Environment env; private static Logger exceptionlogger = LoggerFactory.getLogger(CustomExceptionHandler.class); @ExceptionHandler(CustomException.class) public final ResponseEntity<Object> handleCustomExceptions(CustomException ex, WebRequest request) { exceptionlogger.error("handleCustomExceptions:"); logger.error("CustomException: {}", ex); exceptionlogger.error("handleCustomExceptions: {}::{}::{}::{}", ex.getStackTrace()[0].getFileName(), ex.getStackTrace()[0].getClassName(), ex.getStackTrace()[0].getMethodName(), ex.getStackTrace()[0].getLineNumber()); return new ResponseEntity<>(responseBuilder(ex.getContext(), ex.getErrorCode()), HttpStatus.OK); } @ExceptionHandler(Exception.class) public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) { exceptionlogger.error("handleAllExceptions:"); logger.error("CustomException: {}", ex); ex.printStackTrace(); exceptionlogger.error("{}::{}::{}::{}", ex.getStackTrace()[0].getFileName(), ex.getStackTrace()[0].getClassName(), ex.getStackTrace()[0].getMethodName(), ex.getStackTrace()[0].getLineNumber()); return new ResponseEntity<>(responseBuilder(new HashMap<>(), "0"), HttpStatus.OK); } private Map<String, Object> responseBuilder(Map<String, Object> context, String errorCode) { Map<String, Object> output = new HashMap<>(); context.put("status", "FAILURE"); context.put("ERROR_CODE", errorCode); context.put("errorMessage", errorCode); return output; } }
Conclusion :
@ExceptionHandler
and @ControllerAdvice
annotations usually work together, These two annotations are used to control the content and handle the varieties of exceptions and send back a response with proper status codes.