Hurry! Try our new Interactive Courses for FREE. 🥳   🚀

Spring Boot Global Exception Handling

In this tutorial, we will discuss about the customized exception handling provided by spring boot. In Java, exception handling is done by try, catch blocks but spring boot also allows us to provide customized global exception handling where we need not to add try catch block everwhere, we can create a separate class for handling exceptions and it also separates the exception handling code from businesss logic code.

Global Exception Handling in Spring Boot:

We need to create some classes to implement spring boot exception handling. Our ResourceController.java file has many end points which we tested in our previous tutorials using Rest client. One of such end points allows us to get the Teacher details on the basis of Id which is passed as the PathVariable. In some cases, if the Id is not stored in our java.util.HashMap (which is used in our repository layer), it returns null reference with a 200 Ok status. Let us return the response status of 404 Not Found with a customized exception message when the Teacher is not found.

Create the below classes in the com.tutorial.studytonight.exception package.

TeacherNotFoundException.java class: This is a user-defined class extending the java.lang.RuntimeException class.

public class TeacherNotFoundException extends RuntimeException {
    // Exception class 
}

ExceptionResponse.java class: This class attributes will be returned to the client as a part of customized exception handling.

public class ExceptionResponse {

    private String message;
    private LocalDateTime dateTime;
    
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public LocalDateTime getDateTime() {
        return dateTime;
    }
    public void setDateTime(LocalDateTime dateTime) {
        this.dateTime = dateTime;
    }    
}

CustomizedExceptionHandling.java class: This class is annotated with @ControllerAdvice which means that this class will be able to handle the exceptions occured from any of the Controllers(not only limited to the ResourceController.java). It extends the class ResponseEntityExceptionHandler which exposes the functionality required to implement this feature. The @ExceptionHandler annotation is required to handle the type of exceptions which are thrown and the corresponding method will be able to handle the exceptions.

@ControllerAdvice
public class CustomizedExceptionHandling extends ResponseEntityExceptionHandler {

    @ExceptionHandler(TeacherNotFoundException.class)
    public ResponseEntity<Object> handleExceptions( TeacherNotFoundException exception, WebRequest webRequest) {
        ExceptionResponse response = new ExceptionResponse();
        response.setDateTime(LocalDateTime.now());
        response.setMessage("Not found");
        ResponseEntity<Object> entity = new ResponseEntity<>(response,HttpStatus.NOT_FOUND);
        return entity;
    }
}

Spring boot provides classes such as ResponseEntity and HttpResponse which are used to set the response codes and can send the exception entity as the message to the client. In the above code the method annotated with @ExceptionHandler is capable enough to handle the TeacherNotFoundException. The ResponseEntity object was created and the ExceptionResponse and HttpStatus were passed which will be reflected in the customized message.

Let us test the getTeacherDetails service method which we have created previously, Notice the below code in Controller, Service and Repository layers respectively.

@RestController
public class ResourceController {
    
    @Autowired
    ResourceService resourceService;

    @GetMapping("/getTeacherDetails/{id}")
    public Teacher getTeacherDetails(@PathVariable("id") int id){
        Teacher teacher = resourceService.getTeacherDetails(id);
        if(teacher == null)
            throw new TeacherNotFoundException();
        
        return teacher;
    }
}
    

@Service
public class ResourceService {

    @Autowired
    ResourceRepository repository;
    
    public Teacher getTeacherDetails(int id){
        return repository.getTeacherDetails(id);
    }
}    

@Repository
public class ResourceRepository {

    private Map<Integer,Teacher> teacherMap = new HashMap<Integer,Teacher>();
    
    public Teacher getTeacherDetails(int id){
        Teacher teacher = teacherMap.get(id);
        return teacher;
    }
}

Run the application and test the API using POSTMAN.

custom exception handling in spring boot

It can be seen in the above figure that the response received contains the ExceptionResponse fields with status code as 404 Not Found. We did not save any details for now with ID 1001 so, the above response has been returned to the client.

Conclusion: In this tutorial, we have seen about the customized exception handling using spring-boot with the usage of annotations.