You can search the wechat official account [Jet and Programming] for more exciting articles
background
One approach to Spring Boot’s global exception handling was introduced in the previous article, but it is a global fault-tolerant mechanism designed to replace Spring Boot’s default ErrorController to more user-friendly display of custom exception information to the client.
Of course, in addition to this global fault tolerance mechanism, sometimes we prefer to handle exceptions specified by the Controller layer in a special way, or even a standard means of exception handling, that is, the business layer of the exception can be directly thrown up, do not need to handle themselves, and then the Controller layer for unified exception handling.
Note: Global exception handling in this article can also be abstractly understood as: global exception handling Controller layer throws
implementation
Spring gives us two ways to do this:
-
Local exception handling: @Controller + @ExceptionHandler
-
Global exception handling: @ControllerAdvice + @ExceptionHandler
The difference between local and global here is:
When a proxy method appears in a class annotated by @Controller, the method proxies for the exception in the Controller.
When a proxy method appears in a class annotated by @ControllerAdvice, this method proxies for all Controller exceptions.
Local exception handling
Local exception handling, we just need to write a custom exception handling method in the @Controller annotation class and add the @ExceptionHandler annotation to this method. The effect is that when a method in this class throws an uncaught exception, The exception is passed to the exception handler as a parameter, and we only need to do the related exception handling in this method.
// Local exception handling (ps: 400 exceptions with mandatory parameters will also be caught by this exception handler)
@ExceptionHandler(Exception.class)
public String exHandler(Exception e) {
if(e instanceof ArithmeticException) {
return "Division by 0 exception - Local capture";
}
if(e instanceof STCRException) {
return "Custom Exception - Local Catch";
}
// Respond to an unknown exception
return "Unknown Exception - Local catch";
}
Copy the code
The above method will handle all exceptions (because the argument is Exception), but we can also write multiple methods to handle each Exception, depending on the Exception (the implementation just needs to pass different types of exceptions).
But we can’t write exception handling in every class, so here are two ideas:
-
Fault: Class inheritance mechanism, in fact, is a kind of conceptual attribute inheritance, here only to obtain a public method to do exception class inheritance, obviously breaks the code elegance. Again, classes can only be inherited once, which can break the design of the code structure.
-
In Java8’s Functional Interface, you can write a default method in the Interface, in which you can write specific implementations. Disadvantages: The environment requirements are somewhat harsh, that is, the JDK version is required at least 1.8, in some applications, obviously not appropriate.
Finally, any implementation that extracts a base class is limited because it requires us to inherit or implement the base class, which is obviously not what we want. We want a one-size-fits all implementation.
Global exception handling
Global exception handling is as simple as writing a configuration class, annotating it with @ControllerAdvice, and putting the exception handling methods in the class as described above.
The effect is that the exception handler in this class automatically handles all exceptions thrown in the Controller, which is what we need.
@ControllerAdvice
public class GlobalExceptionHandler {
// Handle custom exceptions
@ExceptionHandler(STCRException.class)
@ResponseBody
public Object customHandler(STCRException e) {
return "Custom Exception - Global";
}
// Other unhandled exceptions
@ExceptionHandler(Exception.class)
@ResponseBody
public Object exceptionHandler(Exception e) {
return "Other Exceptions - Global"; }}Copy the code
conclusion
Ok, let’s take a look at the exception handling process. The outermost exception handling is taken over by Spring’s global exception ErrorController, which is actually exception handling at the filter level. The inner layer handles all Controller exceptions thrown by @ExceptionHandler.
For example, the 404 exception has not entered the Controller layer, so the exception is captured and processed by the ErrorController.
For example, the required missing (400) exception is handled by ExceptionHandler because it is already in the Controller layer.
Note: Local exceptions take precedence over global exceptions