When there are exceptions in our back-end application, we usually wrap the exceptions and return them to the caller or the front-end. In the actual project, it is impossible to handle exceptions everywhere, and then elegant code may throw exceptions. So how can we handle these exceptions gracefully in Spring project?
This article will introduce a global exception handling method, mainly including the following knowledge points
- @ Controller Advice Controller Enhancement
- @ Exception Handler exception capture
- @ ResponseStatus return status code
- NoHandler FoundException Processing (404 exception capture)
Right-click to view the original text: Global exception handling in SpringBook series of tutorials
<!-- more -->
I. Environmental Construction
First, we need to build a web application in order to continue the follow-up testing. It is relatively simple to build a web application with SpringBook.
Create a maven project with the following pom file
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.7</version> <relativePath/> <!-- lookup parent from update --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-cloud.version>Finchley.RELEASE</spring-cloud.version> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.45</version> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </pluginManagement> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
It's still a normal process. After the pom dependencies are settled, write a program entry
/** * Created by @author yihui in 15:26 19/9/13. */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class); } }
II. Exception handling
1. @ControllerAdvice
We usually use @Controller Advice with annotation @ExceptionHandler to achieve global exception capture processing.
- @ Controller Advice weaves enhancements for all Controllers
- @ The ExceptionHandler tag in the method indicates that when a corresponding exception is thrown to the upper layer (that is, it is not caught by the business), the method will be triggered.
Next, we demonstrate the functionality through an example.
a. Exception capture
We define two exception capture case s, one is divided by 0, and the other is array crossover exception.
@Slf4j @ControllerAdvice public class GlobalExceptionHandler { public static String getThrowableStackInfo(Throwable e) { ByteArrayOutputStream buf = new ByteArrayOutputStream(); e.printStackTrace(new java.io.PrintWriter(buf, true)); String msg = buf.toString(); try { buf.close(); } catch (Exception t) { return e.getMessage(); } return msg; } @ResponseBody @ExceptionHandler(value = ArithmeticException.class) public String handleArithmetic(HttpServletRequest request, HttpServletResponse response, ArithmeticException e) throws IOException { log.info("divide error!"); return "divide 0: " + getThrowableStackInfo(e); } @ResponseBody @ExceptionHandler(value = ArrayIndexOutOfBoundsException.class) public String handleArrayIndexOutBounds(HttpServletRequest request, HttpServletResponse response, ArrayIndexOutOfBoundsException e) throws IOException { log.info("array index out error!"); return "aryIndexOutOfBounds: " + getThrowableStackInfo(e); } }
In the above test, we returned the exception stack to the caller
b. Example services
Add several test methods
@Controller @RequestMapping(path = "page") public class ErrorPageRest { @ResponseBody @GetMapping(path = "divide") public int divide(int sub) { return 1000 / sub; } private int[] ans = new int[]{1, 2, 3, 4}; @ResponseBody @GetMapping(path = "ary") public int ary(int index) { return ans[index]; } }
c. Test instructions
Examples are tested as follows. Above, we declare that the two exceptions captured are intercepted and the corresponding stack information is output.
But it's worth noting.
- SpringBoot default error pages are displayed for 404 and 500 uncovered exceptions.
- In addition, the http status code we captured and returned is 200
2. @ResponseStatus
The status code returned by the exception captured in the case above is 200, but in some cases, it may be preferable to return a more appropriate http status code, which can be specified using ResponseStatus.
It's easy to use, just add a comment.
@ResponseBody @ExceptionHandler(value = ArithmeticException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public String handleArithmetic(HttpServletRequest request, HttpServletResponse response, ArithmeticException e) throws IOException { log.info("divide error!"); return "divide 0: " + getThrowableStackInfo(e); }
3. 404 treatment
With @Controller Advice and @ExceptionHandler, 500 exceptions can be intercepted. What can I do if I want 404 exceptions to be intercepted as well?
First, modify the configuration file application.properties to throw out NoHandler FoundException
# When an error occurs, throw an exception directly spring.mvc.throw-exception-if-no-handler-found=true # Set the static resource mapping access path, and choose one of the following two options. spring.mvc.static-path-pattern=/statics/** # spring.resources.add-mappings=false
Next is the definition of exception capture
@ResponseBody @ExceptionHandler(value = NoHandlerFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public String handleNoHandlerError(NoHandlerFoundException e, HttpServletResponse response) { return "noHandlerFound: " + getThrowableStackInfo(e); }
Test again as follows, 404 was captured by us and returned to the stack information.
II. other
0. project
web series blog posts
- 404, 500 Exceptional Page Configuration of 190930-SpringBook Series Tutorial web Papers
- Reorientation of 190929-SpringBoot Series Tutorial web Papers
- Posture of Returning Text, web Page and Picture in the 190913-SpringBook Series
- Solution of Chinese Scrambling Problem in web Papers of 190905-SpringBook Series
- How to Customize Parametric Parsers in the 190831-SpringBook Series of Tutorials web Papers
- Post Request Parameters Analytical Posture Summary in the 190828-SpringBook Series of Tutorials web Papers
- Analytical Posture Summary of Get Request Parameters in the 190824-SpringBook Series of Tutorials web Papers
- Establishment of Beetl Environment for 190822-SpringBook Series Tutorial web Papers
- Thymeleaf Environment Construction of 190820-SpringBook Series Tutorial web Papers
- Freemaker Environment Construction of 190816-SpringBoot Series Tutorial web Papers
- 190421-SpringBoot Advanced WEB websocket User Description
- Full-range Analysis of urlencode Parametric Anomalies in 190327-Spring-RestTemplate
- 190317-Spring MVC web Application Construction Based on java config without xml Configuration
- Construction of web Application Based on xml Configuration in 190316-Spring MVC
- The temporary upload location xxx is not valid
Project source code
- Works: https://github.com/liuyueyi/spring-boot-demo
- Item: https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/209-web-error
1. Grey Blog
Letters are not as good as letters. The above contents are purely family statements. Due to limited personal abilities, there are inevitably omissions and errors. If you find bug s or have better suggestions, you are welcome to criticize and correct them. Thank you very much.
Below is a grey personal blog, which records all the blogs about study and work. Welcome to visit it.
- A Grey Blog Personal Blog https://blog.hhui.top
- A Grey Blog-Spring Thematic Blog http://spring.hhui.top