Exception handling is a problem that every Java programmer needs to face. In Spring, multiple mechanisms are provided to handle exceptions thrown by the controller to ensure that the application can respond gracefully when facing various error situations. In this article, we will analyze in detail several elegant ways to handle exceptions in Spring MVC.
1. Annotate with @ExceptionHandler
@ExceptionHandler
Annotations allow methods to handle specific exceptions to be defined in a single controller. When the Controller method throws the specified exception, Spring will call the corresponding processing method.
The following example shows how to handle exceptions gracefully in the Controller layer:
@Controller public class MyController { @RequestMapping("/example") public String example() { // Business logic that may throw exceptions if (1/0) { throw new CustomException("Custom exception occurs"); } return "success"; } @ExceptionHandler() public ModelAndView handleCustomException(CustomException ex) { ModelAndView mav = new ModelAndView(); ("message", ()); ("errorPage"); return mav; } }
advantage:Simple and intuitive, suitable for exception handling of a single controller.
shortcoming:If multiple controllers require the same exception handling logic, it needs to be repeatedly defined in each controller.
2. Annotate with @ControllerAdvice
@ControllerAdvice
is a global exception handling method that can be applied to all controllers. By concentrating exception handling logic in one place, code duplication can be avoided and maintenance can be improved.
The following example shows how to use it@ControllerAdvice
Handle global exceptions elegantly:
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler() public ModelAndView handleCustomException(CustomException ex) { ModelAndView mav = new ModelAndView(); ("message", ()); ("errorPage"); return mav; } @ExceptionHandler() public ModelAndView handleGeneralException(Exception ex) { ModelAndView mav = new ModelAndView(); ("message", "An error occurred: " + ()); ("errorPage"); return mav; } }
advantage:
- Global unified management of exception handling logic.
- The code is clearer and easy to maintain.
shortcoming:
- Global processing is not suitable for situations where special processing needs are required for certain controllers, and needs to be used in combination with other methods.
3. Implement HandlerExceptionResolver interface
HandlerExceptionResolver
It is a more underlying exception handling mechanism. By implementing this interface, developers can customize exception resolution logic.
The following example shows how to implement itHandlerExceptionResolver
The interface handles exceptions elegantly:
public class MyExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView mav = new ModelAndView(); if (ex instanceof CustomException) { ("message", ()); ("customErrorPage"); } else { ("message", "Unknown Error"); ("errorPage"); } return mav; } }
Configuration:
Register a custom exception resolver in a Spring configuration file:
<bean class=""/>
advantage:
Highly flexible and can handle various complex anomalies.
shortcoming:
- More configuration and implementation work is required.
- It is not as intuitive as the annotation method and has less applicability.
4. Use @ResponseStatus annotation
@ResponseStatus
Annotations can be used to customize the HTTP status code and error information corresponding to the exception. When an exception with the annotation is thrown, Spring will automatically set the corresponding status code.
The following example shows how to use it@ResponseStatus
Annotation elegantly handles exceptions:
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Resource not found") public class ResourceNotFoundException extends RuntimeException { public ResourceNotFoundException(String message) { super(message); } }
use:
@Controller public class MyController { @RequestMapping("/resource") public String getResource() { // Assume that the resource is not found throw new ResourceNotFoundException("Resource ID does not exist"); } }
advantage:
Simple and fast, suitable for exceptions that are mapped directly to specific HTTP status codes.
shortcoming:
Unable to return a custom error page or more complex error message.
5. Use ResponseEntity and @RestControllerAdvice
Commonly used when building RESTful APIsResponseEntity
Returns a custom error response and combines@RestControllerAdvice
Exceptions can be handled globally and error messages in JSON format are returned.
The following example shows how to use itResponseEntity
and@RestControllerAdvice
To handle exceptions of RESTful API:
@RestControllerAdvice public class RestExceptionHandler { @ExceptionHandler() public ResponseEntity<ErrorResponse> handleCustomException(CustomException ex) { ErrorResponse error = new ErrorResponse("CUSTOM_ERROR", ()); return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); } @ExceptionHandler() public ResponseEntity<ErrorResponse> handleGeneralException(Exception ex) { ErrorResponse error = new ErrorResponse("GENERAL_ERROR", "Internal Server Error"); return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR); } } public class ErrorResponse { private String errorCode; private String errorMessage; // Constructor, getter and setter}
advantage:
- Applicable to RESTful services, capable of returning structured error messages (such as JSON).
- Global unified management, easy to maintain.
shortcoming:
Additional error response classes need to be defined.
6. Use @ControllerAdvice and @ExceptionHandler
If you use Spring Boot, you can use it more easily@ControllerAdvice
Combined with automatic configuration, exception handling is implemented.
The following example shows how to use it@ControllerAdvice
and@ExceptionHandler
To handle exceptions:
@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler() public ResponseEntity<ValidationErrorResponse> handleValidationExceptions( MethodArgumentNotValidException ex) { ValidationErrorResponse errors = new ValidationErrorResponse(); ().getAllErrors().forEach((error) -> { (((FieldError) error).getField(), ()); }); return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST); } // Other exception handling methods}
advantage:
- Seamless integration with Spring Boot, reducing configuration.
- It provides many convenient functions, such as automatic handling of verification errors, etc.
7. Summary
In this article, we analyzed several methods and code examples of Spring MVC elegantly handle exceptions, and we can choose the appropriate method according to specific needs:
-
Local controller processing:use
@ExceptionHandler
Annotation, suitable for specific exception handling of a single controller. -
Global processing:use
@ControllerAdvice
or@RestControllerAdvice
, suitable for unified exception handling across multiple controllers. -
Custom parsing:accomplish
HandlerExceptionResolver
Interface, suitable for exception handling logic that requires highly customization. -
Status code annotation:use
@ResponseStatus
Annotation, suitable for simple exception status code mapping. -
RESTful API: Combined
ResponseEntity
and global exception handling, returning structured error response.
From the actual work perspective,@ControllerAdvice
or@RestControllerAdvice
It is the most frequently used method.
This is the end of this article about 6 ways to elegantly handle Spring MVC exceptions. For more related content on Spring MVC exception handling, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!