How to handle exceptions in Spring MVC Framework?
Handling exceptions in a Spring MVC application is crucial for providing a robust user experience and maintaining application stability. Spring provides several ways to handle exceptions effectively. Here are some common approaches:
@ControllerAdvice
@ControllerAdvice
is a powerful annotation that allows you to handle exceptions globally across all controllers. You can define a class annotated with @ControllerAdvice
and use @ExceptionHandler
to specify which exceptions to handle.
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<String> handleResourceNotFound(ResourceNotFoundException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGenericException(Exception ex) {
return new ResponseEntity<>("An error occurred: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@ResponseStatus
You can annotate your custom exception classes with @ResponseStatus
to specify the HTTP status code that should be returned when the exception is thrown.
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
@ExceptionHandler
in ControllersYou can also define exception handling methods directly within your controller classes using the @ExceptionHandler
annotation.
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class MyController {
@GetMapping("/resource")
public String getResource() {
// Some logic that may throw an exception
throw new ResourceNotFoundException("Resource not found");
}
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<String> handleResourceNotFound(ResourceNotFoundException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
}
You can create a custom error response object to return more structured error information.
public class ErrorResponse {
private String message;
private int status;
public ErrorResponse(String message, int status) {
this.message = message;
this.status = status;
}
// Getters and setters
}
Then, modify your exception handler to return this custom response:
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {
ErrorResponse errorResponse = new ErrorResponse(ex.getMessage(), HttpStatus.NOT_FOUND.value());
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
@RestControllerAdvice
If you are using Spring Boot, you can use @RestControllerAdvice
, which is a convenience annotation that combines @ControllerAdvice
and @ResponseBody
. This is particularly useful for REST APIs.
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalRestExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {
ErrorResponse errorResponse = new ErrorResponse(ex.getMessage(), HttpStatus.NOT_FOUND.value());
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
}
By using these techniques, you can effectively manage exceptions in your Spring MVC application, providing meaningful error messages and appropriate HTTP status codes to the client. Choose the method that best fits your application's architecture and requirements.