Difference Between @ExceptionHandler and @ControllerAdvice Annotations in SpringBoot with Example?

@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.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *