java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot全局异常处理机制和配置拦截器

SpringBoot全局异常处理机制和配置拦截器方式

作者:勇敢流流

这篇文章主要介绍了SpringBoot全局异常处理机制和配置拦截器方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

SpringBoot全局异常处理机制和配置拦截器

关于SpringBoot的全局异常处理,其实十分简单。

首先,要新建一个SpringBoot项目添加两个依赖,spring-boot-starter-web和spring-boot-starter-thymeleaf。

这个时候,我们便可以把异常信息展示在thymeleaf页面。

编写接口:

以往的SpringMVC配置在SpringBoot项目中依然生效。

所以可以通过实现HandlerExceptionResolver接口或者添加@ExceptionHandler注解来处理全局异常。

@ControllerAdvice
public class GlobalExceptionHandler implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ModelAndView mv = new ModelAndView("01");
        mv.addObject("error",ex.getMessage());
        return mv;
    }
}
@ControllerAdvice
public class GlobalExceptionHandler2 {
    @ExceptionHandler(ArithmeticException.class)
    public ModelAndView resolveException( Exception ex) {
        ModelAndView mv = new ModelAndView("01");
        mv.addObject("error",ex.getMessage());
        return mv;
    }
}

thymeleaf视图必须放在/resources/templates文件夹下,此时需要新建一个01.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试页面</title>
</head>
<body>
<h4>异常信息显示:</h4>
<div th:text="${error}"></div>
</body>
</html>

注意:SpringBoot项目里面freemarker页面和thymeleaf页面不需要配置视图解析器,Spring会自动帮我们识别并渲染ftlh和html页面。

测试:

 以上是SpringMVC配置在SpringBoot中依然适用。

但是基于SpringBoot项目的异常配置,SpringBoot自己也有一套全局异常处理机制。

SpringBoot异常处理

默认方案,在静态页面里面展示异常信息:

但是,必须要在静态资源文件夹下新建error文件夹,里面放自己的错误页面信息,4xx和5xx为模糊查询,SpringBoot支持4xx和5xx的状态错误。

这里为了省事,我就在页面里放了一个div输出一句话。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>4xx</title>
</head>
<body>
<div>4xx-static-html</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5xx</title>
</head>
<body>
<div>5xx-static-html</div>
</body>
</html>

测试结果为页面显示5xx-static-html,在这里还有一个小细节,假如我们定义了一个精确的状态码页面,例如数学算术错误为500,定义了一个500.html,那么是优先显示500的页面还是5xx的页面呢,这就涉及一个优先级的问题。

在这里先埋下一个伏笔,继续往下走。

我们知道thymeleaf实际上是一个动态页面,所以同样的,我们在templates文件下新建error文件夹放两个html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>4xx</title>
</head>
<body>
<div>这是动态展示错误的页面:</div>
<table border="1">
    <tr>
        <td>出错路径</td>
        <td th:text="${path}"></td>
    </tr>
    <tr>
        <td>出错时间</td>
        <td th:text="${timestamp}"></td>
    </tr>
    <tr>
        <td>错误信息</td>
        <td th:text="${error}"></td>
    </tr>
    <tr>
        <td>状态</td>
        <td th:text="${status}"></td>
    </tr>
</table>
</body>
</html>

当我们在url地址请求一个不存在的页面时触发,

测试:

 好了,到这里要开始进入正题。

由于我们的错误是数学算术错误,返回的是java.lang.ArithmeticException,这样显然是很难交代的。

首先SpringBoot为我们额外提供了三个异常信息。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5xx</title>
</head>
<body>
<div>这是动态展示错误的页面:</div>
<table border="1">
    <tr>
        <td>出错路径</td>
        <td th:text="${path}"></td>
    </tr>
    <tr>
        <td>出错时间</td>
        <td th:text="${timestamp}"></td>
    </tr>
    <tr>
        <td>错误信息</td>
        <td th:text="${error}"></td>
    </tr>
    <tr>
        <td>状态</td>
        <td th:text="${status}"></td>
    </tr>
    <tr>
        <td>异常</td>
        <td th:text="${exception}"></td>
    </tr>
    <tr>
        <td>堆栈</td>
        <td th:text="${trace}"></td>
    </tr>
    <tr>
        <td>异常信息</td>
        <td th:text="${message}"></td>
    </tr>
</table>
</body>
</html>

exception、trace和message。

假如我们配置完5xx.html便急着去测试,结果如下:

 这三个东西结果为空,那么小伙伴们肯定很想知道这三个东西究竟显示的是什么玩意儿。

别急,我们可以在application.properties中配置三个东西。

server.error.include-exception=true
server.error.include-message=always
server.error.include-stacktrace=always

这三个是什么东西呢,想深究的同学可以回去看看底层。从字面意思理解,便是开启这三个东西,默认为不展示。

测试:

 

原本是测试显示的是java.lang.ArithmeticException,在这里只需要进行全局异常处理即可。

/**
 * 将该类注册到 Spring 容器中,此时,默认的 DefaultErrorAttributes 就会失效
 */
@Component
public class MyErrorAttributes extends DefaultErrorAttributes {
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
        //这是默认的异常数据
        Map<String, Object> map = super.getErrorAttributes(webRequest,options);
        //获取异常
        String exception = (String) map.get("exception");
        if ("java.lang.ArithmeticException".equals(exception)){
            map.put("exception","数学算术异常");
        }
        return map;
    }
}

注意:状态页面先找精确,再找模糊,其次是先动态后静态。

SpringBoot配置拦截器

SpringBoot的拦截器配置也是十分简单,只需要把往Spring注册一个拦截器即可。

为了方便演示,小编自定义一个拦截器,在控制台打印了三句话。

随后新建一个config包把该类注册到Spring容器中。

 大功告成,进入测试环节:

 

这里打印了两次的原因是,第一次拦截的是happy请求,第二次拦截的是404页面错误,因此打印了两次。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文