springboot系列十三: 异常处理

在这里插入图片描述

基本介绍

1.默认情况下,SpringBoot 提供 /error 处理所有错误的映射,当出现错误时,SpringBoot 底层会请求转发到 /error 这个映射。

2.浏览器访问不存在的接口 http://localhost:8084/abc,响应 whitelabel 的错误试图,以 HTML 格式呈现给用户。

注意: 配置登录拦截器时,先登录, 再测试

在这里插入图片描述

3.SpringBoot底层默认由 DefaultErrorViewResolver 处理错误。debug->

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

默认找类路径下的 /error/404.html页面

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

不管你请求什么, 都去找类路径下的 /error/4xx.html页面

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

拦截器VS过滤器

1.使用范围不同.
1)过滤器 实现的是 javax.servlet.Filter 接口, 而这个接口是在Servlet规范中定义的, 也就是说过滤器 Filter 的使用要依赖于 Tomcat 等容器, Filter 只能在 web 程序中使用.
2)拦截器(Interceptor) 它是一个 Spring 组件, 并由 Spring 容器管理, 并不依赖 Tomcat 等容器, 是可以单独使用的, 不仅能应用在web程序中, 也可以用于 Application 等程序中.

2.过滤器 和 拦截器的触发时机也不同, 如下图

在这里插入图片描述

1)过滤器Filter是在请求进入容器后, 但是在进入servlet之前进行预处理, 请求结束是在servlet处理完以后.

2)拦截器Interceptor是在请求进入servlet后, 在进入Controller之前进行预处理的, Controller中渲染了对应的视图之后请求结束.

3.说明:过滤器不会处理请求转发, 拦截器会处理请求转发. 因为请求转发是sevlet内部的事。

4.回顾过滤器和拦截器的原理和机制.

默认异常页面

文档:https://docs.spring.io/spring-boot/docs/current/reference/html/index.html

应用实例

需求: 自定义404.html, 500.html, 4xx.html, 5xx.html. 当发生相应错误时, 显示自定义的页面信息

1.创建4个页面, 拷贝即可

1)创建src/main/resources/templates/error/404.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
    <h1>404 Not Found</h1>
    <a href='#' th:href="@{/}">返回主页面</a>
    状态码: <h1 th:text="${status}"></h1>
    错误信息: <h1 th:text="${error}"></h1><br/>
</div>
<hr/>
<img src="images/logo.png"/>
</body>
</html>

2)创建src/main/resources/templates/error/4xx.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
    <h1>4xx 发生错误了:)</h1><br/>
    错误状态码: <h1 th:text="${status}"></h1><br/>
    错误信息: <h1 th:text="${error}"></h1><br/>
    <a href='#' th:href="@{/}">返回主页面</a>
</div>
<hr/>
<img src="images/logo.png"/>
</body>
</html>

3)创建src/main/resources/templates/error/500.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
    <h1>500 内部服务器出现了问题</h1><br/>
    状态码: <h1 th:text="${status}"></h1><br/>
    错误信息: <h1 th:text="${error}"></h1>
    <a href='#' th:href="@{/static}">返回主页面</a>
</div>
<hr/>
<img src="images/logo.png"/>
</body>
</html>

4)创建src/main/resources/templates/error/5xx.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
    <h1>5xx 发生错误了:)</h1><br/>
    错误状态码: <h1 th:text="${status}"></h1><br/>
    错误信息: <h1 th:text="${error}"></h1><br/>
    <a href='#' th:href="@{/static}">返回主页面</a>
</div>
<hr/>
<img src="images/logo.png"/>
</body>
</html>

在这里插入图片描述

2.测试, 登陆后访问 http://localhost:8080/err/eeee

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.创建src/main/java/com/zzw/springboot/controller/MyErrorController.java

@Controller
public class MyErrorController {

    //模拟一个服务器内部错误, 500错误
    @GetMapping("/err")
    public String err() {
        int i = 10 / 0;
        return "manage";
    }

    //配置post方式, 用get请求 /error2, 会出现405错误
    @PostMapping("/err2")
    public String error2() {
        return "manage";
    }
}

4.注意: 配置登录拦截器时,先登录, 再测试

5.访问 /err, 生成500错误, 可以看到 500.html.

6.访问 /err2, 生成405错误, 可以看到4xx.html.

7.访问 http://localhost:8084/abc, 生成404错误, 可以看到 404.html

debug取出状态码和错误信息

src/main/resources/templates/error/500.html

<div style="text-align: center">
    <h1>500 内部服务器出现了问题</h1><br/>
    状态码: <h1 th:text="${status}"></h1><br/>
    错误信息: <h1 th:text="${error}"></h1>
    <a href='#' th:href="@{/static}">返回主页面</a>
</div>

1.请求 http://localhost:8084/err

在这里插入图片描述

全局异常

基本说明

1.@ControllerAdvice + @ExceptionHandler 处理全局异常.
2.底层是 ExceptionHandlerExceptionResolver 支持.

应用实例

需求: 演示springboot全局异常使用, 当发生ArithmeticException时, 不使用默认异常机制.

1.新建src/main/java/com/zzw/springboot/exception/GlobalExceptionHandler.java

@Slf4j
//使用这个注解可以标识一个全局异常处理器/对象, 会注入到ioc容器中
@ControllerAdvice
public class GlobalExceptionHandler {

    //编写方法, 处理指定异常, 可以指定多个异常
    //Exception ex: 表示传递的异常对象
    //Model model: 将异常信息, 放入model, 传递到下一个页面
    @ExceptionHandler({ArithmeticException.class})
    public String catchGlobalException(Exception ex, Model model) {
        log.info("异常信息={}", ex.getMessage());
        //将异常信息, 放入model, 传递到下一个页面
        model.addAttribute("eror", ex.getMessage());
        return "error/global";
    }
}

2.新建src/main/resources/templates/error/global.html

<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>全局异常-显示页面</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
    <h1>全局异常/错误 发生了:)</h1><br/>
    异常/错误信息: <h1 th:text="${error}"></h1><br/>
    <a href='#' th:href="@{/}">返回主页面</a>
</div>
<hr/>
<img src="images/logo.png"/>
</body>
</html>

3.注意: 配置登录拦截器时,先登录, 再测试.
访问 /err, 抛出ArithmeticException异常, 被全局异常处理器的catchArithGlobalException方法捕获

在这里插入图片描述

注意:
1.全局异常处理器优先级大于默认异常处理机制. 所以会进入global.html, 而不是根据状态码进入500.html
2.默认异常处理机制是按照状态码寻找错误页面的.

Debug处理流程

在这里插入图片描述
在这里插入图片描述

放行

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

获取异常发生的方法

在这里插入图片描述

自定义异常

基本说明

1.如果Spring Boot提供的异常不能满足开发需求,可以自定义异常。

2.@ResponseStatus + 自定义异常

3.底层是 ResponseStatusExceptionResolver, 底层调用 response.sendError(statusCode, resolvedReason);

4.但抛出自定义异常后, 仍然会根据状态码, 去匹配使用 xxx.html 显示, 当然也可以将自定义异常, 放在全局异常处理器去处理

应用实例

需求说明
1.自定义一个异常 ZzwAccessException, 当用户访问某个无权访问的路径时, 抛出该异常, 显示自定义异常状态码,

2,访问 http://localhost:8080/err3, 效果

代码实现
1.新建src/main/java/com/zzw/springboot/exception/ZzwAccessException.java

/**
 * 自定义异常
 * value = HttpStatus.FORBIDDEN: 表示发生ZzwAccessException异常时, 通过http协议返回的状态码
 * 这个状态码和自定义异常的对应关系由程序员决定
 */
public class ZzwAccessException extends RuntimeException {

    //构造器
    public ZzwAccessException(String message) {
        super(message);
    }

    //显式定义无参构造器
    public ZzwAccessException() {
    }
}

2.修改src/main/java/com/zzw/springboot/controller/MyErrorController.java

//编写方法, 模拟ZzwAccessException
@GetMapping("/err3")
public String err3(String name) {
    //如果用户不是zzw, 判定-无权访问
    if (!"zzw".equals(name)) {
        throw new ZzwAccessException();
    }

    return "manage";//thymeleaf视图解析器

    //return "redirect:/manage";//重定向 manage.html映射
}

3.测试 http://localhost:8084/err3

在这里插入图片描述

Debug处理流程

在这里插入图片描述
在这里插入图片描述

抛出自定义异常,会先走全局异常的逻辑,全局异常没有指定这个异常

在这里插入图片描述

根据你指定的状态码寻找对应的 403.html
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

注意事项和细节

1.如果把自定义异常类型,放在全局异常处理器,仍然会走全局异常处理机制。

2.Debug看显示效果,也可自定义异常信息。

指定自定义异常 ZzwAccessException 为全局异常
在这里插入图片描述

会走全局异常的逻辑,不会根据自定义异常状态码去寻找对应的错误页面。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
`
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~ 小团子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值