Exception Handling in Spring MVC
Exception handling in Spring MVC is a crucial aspect of building robust web applications. It allows developers to manage errors gracefully and provide meaningful feedback to users. Spring MVC provides several ways to handle exceptions, including:
@ControllerAdvice
@ControllerAdvice
is a specialized annotation that allows you to handle exceptions globally across all controllers. You can define a class annotated with @ControllerAdvice
and use @ExceptionHandler
methods to handle specific exceptions.
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ModelAndView handleResourceNotFound(ResourceNotFoundException ex) {
ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("message", ex.getMessage());
return modelAndView;
}
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ModelAndView handleGenericException(Exception ex) {
ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("message", "An unexpected error occurred.");
return modelAndView;
}
}
@ExceptionHandler
in ControllersYou can also define exception handling methods directly within your controller classes using the @ExceptionHandler
annotation.
import org.springframework.web.bind.annotation.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class MyController {
@RequestMapping("/someEndpoint")
public String someMethod() {
// Some logic that may throw an exception
throw new ResourceNotFoundException("Resource not found");
}
@ExceptionHandler(ResourceNotFoundException.class)
public ModelAndView handleResourceNotFound(ResourceNotFoundException ex) {
ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("message", ex.getMessage());
return modelAndView;
}
}
@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);
}
}
You can configure custom error pages in your web.xml
or using Spring Boot's application properties. For example, in application.properties
:
server.error.whitelabel.enabled=false
server.error.path=/error
ResponseEntityExceptionHandler
If you want to handle exceptions in a more RESTful way, you can extend ResponseEntityExceptionHandler
and override its methods to customize the response.
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.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<Object> handleResourceNotFound(ResourceNotFoundException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleGenericException(Exception ex) {
return new ResponseEntity<>("An unexpected error occurred.", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Spring MVC provides a flexible and powerful way to handle exceptions. By using @ControllerAdvice
, @ExceptionHandler
, and custom exception classes, you can create a robust error handling mechanism that improves the user experience and makes your application easier to maintain.