什么是异常处理

异常处理

介绍

  1. 默认情况下,Spring Boot 提供/error 处理所有错误的映射
  2. 对于机器客户端,它将生成JSON 响应,其中包含错误,HTTP 状态和异常消息的详细信息。对于浏览器客户端,响应一个"whitelabel"错误视图,以HTML 格式呈现相同的数据

image-20230816111320819

自定义异常页面

文档:

https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.developing-web-applications.spring-mvc.error-handling.error-pages

自定义异常页面说明

1、如何找到这个文档位置, 看下面一步步的指引
https://docs.spring.io/spring-boot/docs/current/reference/html/index.html => a single HTML page=> 8.web => servlet web application => The “Spring Web MVC Framework” => ErrorHandling => Custom Error Pages

image-20230816105738031

image-20230816105919758

自定义异常页面-应用实例

image-20230816110118721

需求:

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

image-20230816110154061

image-20230816110205804

image-20230816110218051

代码实现
  1. 创建4 个页面, 这几个页面拷贝即可(这里使用Thymeleaf需要引入命名空间)

image-20230816110251053

创建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>
        错误状态码: <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>

创建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>4o4 Not Found</h1>
        <a href='#' th:href="@{/}">返回主页面</a><br/>
        状态码: <h1 th:text="${status}"></h1><br/>
        错误信息: <h1 th:text="${error}"></h1>
    </div>
    <hr/>
    <img src="images/logo.png"/>
</body>
</html>

创建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="@{/}">返回主页面</a>
    </div>
    <hr/>
    <img src="images/logo.png"/>
</body>
</html>

创建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><br/>
        <a href='#' th:href="@{/}">返回主页面</a>
    </div>
    <hr/>
    <img src="images/logo.png"/>
</body>
</html>
  1. 创建com/nlc/usersys/controller/MyErrorController.java , 用于模拟错误
@Controller
public class MyErrorController {

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

    //这里我们配置的是Post方式请求 /err2
    //一会使用 get方式来请求 /err2 , 这样就会出现一个405开头的客户端错误
    @PostMapping("/err2")
    public String err2() {
        //..
        return "manage";
    }
}
  1. 完成测试
    ● 需要先登录,再进行测试,否则会被拦截器打回登录页面
    ● 对于/err2 , 使用get 方式去请求,就会生成400 错误, 可以看到4xx.html
    浏览器输入:http://localhost:8080/xx

image-20230816111601624

浏览器输入:http://localhost:8080/err2
image-20230816111631586

浏览器输入:http://localhost:8080/err

image-20230816111735723

全局异常

说明

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

全局异常-应用实例

需求:
  1. 演示全局异常使用, 当发生ArithmeticException、NullPointerException 时,不使用默认异常机制匹配的xxx.html , 而是显示全局异常机制指定的错误页面

image-20230816111927257

代码实现
  1. 创建com/nlc/usersys/exception/GlobalExceptionHandler.java
/**
 * @ControllerAdvice: 使用它可以标识一个全局异常处理器/对象
 * 会注入到spring容器
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    //1、编写方法,处理指定异常, 比如我们处理算术异常和空指针异常, 可以指定多个异常
    //2. 这里要处理的异常,由程序员来指定
    //3. Exception e : 表示异常发生后,传递的异常对象
    //4. Model model: 可以将我们的异常信息,放入model,并传递给显示页面

    @ExceptionHandler({ArithmeticException.class, NullPointerException.class})
    public String handleAritException(Exception e, Model model, HandlerMethod handlerMethod) {

        log.info("异常信息={}", e.getMessage());
        //这里将发生的异常信息放入到model,可以再错误页面取出显示
        model.addAttribute("msg", e.getMessage());
        //得到异常发生的方法是哪个
        log.info("异常发生的方法是={}", handlerMethod.getMethod());
        return "/error/global"; //视图地址
    }
}
  1. 创建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="${msg}"></h1><br/>
            <a href='#' th:href="@{/}">返回主页面</a>
        </div>
        <hr/>
        <img src="images/logo.png"/>
    </body>
</html>
完成测试

浏览器输入:http://localhost:8080/err

image-20230816112455904

自定义异常

说明

  1. 如果Spring Boot 提供的异常不能满足开发需求,程序员也可以自定义异常.
  2. @ResponseStatus+自定义异常
  3. 底层是ResponseStatusExceptionResolver ,底层调用response.sendError(statusCode,resolvedReason);
  4. 当抛出自定义异常后,仍然会根据状态码,去匹配使用x.html 显示

自定义异常-应用实例

需求:

自定义一个异常AccessException, 当用户访问某个无权访问的路径时,抛出该异常,显示自定义异常状态码

代码实现
  1. 创建com/nlc/usersys/exception/AccessException.java
/**
 * AccessException : 我们自定义的一个异常
 * value = HttpStatus.FORBIDDEN: 表示发生AccessException异常,我们通过http协议返回的状态码 403
 * 这个状态码和自定义异常的对应关系是由程序员来决定[尽量合理来设置]
 * 光标在HttpStatus.FORBIDDEN上CTRL+B可以查看源码看它的状态码
 */
//自定义异常,也会根据状态码,匹配到对应的错误页面显示
@ResponseStatus(value = HttpStatus.FORBIDDEN)
public class AccessException extends RuntimeException {
    
    //提供一个构造器,可以指定信息
    public AccessException(String message) {
        super(message);
    }

    //显示的定义一下无参构造器

    public AccessException() {
    }
}

  1. 修改MyErrorController.java
@Controller
public class MyErrorController {

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

    //这里我们配置的是Post方式请求 /err2
    //一会使用 get方式来请求 /err2 , 这样就会出现一个405开头的客户端错误
    @PostMapping("/err2")
    public String err2() {
        //..
        return "manage";
    }

    //编写方法,模拟一个AccessException
    @GetMapping("/err3")
    public String err3(String name) {
        //如果用户不是tom,我们就认为,无权访问-模拟
        if(!"tom".equals(name)) {
            //throw new AccessException();
            throw new AccessException("自定义的AccessException..");
        }
        return "manage";//视图地址, 请求转发
    }
}

完成测试

浏览器http://localhost:8080/err3

image-20230816115843163

注意事项

1.如果我们将自定义异常放入全局异常处理器,会走全局异常处理机制。

2.放入全局异常就是按照Java的异常类型机制处理,不会按照状态码进行处理。

3.可以自己看看显示效果并Debug,也可以自己设置异常信息。

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    //1、编写方法,处理指定异常, 比如我们处理算术异常和空指针异常, 可以指定多个异常
    //2. 这里要处理的异常,由程序员来指定
    //3. Exception e : 表示异常发生后,传递的异常对象
    //4. Model model: 可以将我们的异常信息,放入model,并传递给显示页面

    @ExceptionHandler({ArithmeticException.class, NullPointerException.class,AccessException.class})
    public String handleAritException(Exception e, Model model, HandlerMethod handlerMethod) {

        log.info("异常信息={}", e.getMessage());
        //这里将发生的异常信息放入到model,可以再错误页面取出显示
        model.addAttribute("msg", e.getMessage());
        //得到异常发生的方法是哪个
        log.info("异常发生的方法是={}", handlerMethod.getMethod());
        return "/error/global"; //视图地址
    }
}
完成测试

浏览器http://localhost:8080/err3

(Exception e, Model model, HandlerMethod handlerMethod) {

    log.info("异常信息={}", e.getMessage());
    //这里将发生的异常信息放入到model,可以再错误页面取出显示
    model.addAttribute("msg", e.getMessage());
    //得到异常发生的方法是哪个
    log.info("异常发生的方法是={}", handlerMethod.getMethod());
    return "/error/global"; //视图地址
}

}


#### 完成测试

 浏览器http://localhost:8080/err3

![image-20230816115335703](https://img-blog.csdnimg.cn/img_convert/3aa3a4c9680d246ae99362a27eb69830.png)
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

晨犀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值