Spring Boot(十 三)-- 异常处理

  我们在开发中,碰到异常那就是家常便饭了。那么今天小编就给大家聊一聊 Spring Boot 对异常的处理。

   在小编的上一篇文章:Spring Boot(十 二)-- @ControllerAdvice注解的使用 ,中已经介绍了 SpringMVC 中 @ControllerAdvice 注解是如何处理异常的,但是这种方式是 SpringMVC 中就有的功能,今天小编就说说 Spring Boot 中的异常处理方式。

  通常情况我们在后端出现异常,Spring Boot 默认异常页面是:
在这里插入图片描述
  通过这个页面,我们可以很清楚的看出来,我们这个程序应用没有提供一个明确的 /error 路径,如果开发者提供了 /error 路径,那么这个页面就不会展现出来。注意: 在 Spring Boot 中,提供 /error 路径实际是下下策, Spring Boot 在处理异常时,是在所有的条件都不满足时,才会找到 /error 路径。下面我们就看看在 Spring Boot 中,是如何定义 error 页面的。至于 提供 error 页面也是存在两种方式:一种是静态页面,一种是动态页面。

静态页面异常处理

自定义静态页面异常,也分两种:

  • 第一种:使用 HTTP 响应码来命名的 HTML 页面。如:404.html、500.html
  • 第二种:使用 HTTP 一类响应码的第一个数字为前缀,代表该类的异常处理。如:4xx.html,该页面代表 400~499 状态的异常都使用这个页面显示。

默认是在 classpath:/static/error/ 路径下定义相关页面:
在这里插入图片描述
  启动项目,项目抛出 500 请求错误,就会自动展示 500.html 这个页面,如果发生 404 错误,则会展示 404.html 页面。如果异常页面存在的有 5xx.html ,也存在 500.html,那么抛出 500 错误时,优先展示具体的 500.html 页面。

如:
抛出异常的 Controller 代码如下:

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello() {
        int i = 1 / 0;
        return "hello";
    }
}

500错误页面,就是一个很简单的 html 页面。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>500</h1>
</body>
</html>

启动项目,访问 :http://localhost:8080/hello
在这里插入图片描述


动态页面异常处理

  动态的异常页面定义方式和静态的基本一致,我们可以使用页面模板有: jsp、freemarker、thymeleaf 。这里小编使用的是 thymeleaf 页面模板,所以创建的动态页面异常是以 html 结尾的。动态页面异常处理,也支持具体的异常 如: 404.html ,也支持一类的异常 如:4xx.html。但是,一般情况来说,由于动态页面可以直接展示异常详细信息,所以没有必要挨个枚举错误了,直接定义 4xx.html 或者 5xx.html 即可。

   注意:动态页面模板,不需要开发者自己去定义控制器,直接定义异常页面即可, Spring Boot 中自带的异常处理会自动查找到异常页面。
在这里插入图片描述
5xx.html 页面的内容:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>templates: 5xx</h1>
<div th:text="${error}"></div>
<div th:text="${status}">status</div><br>
<div th:text="${path}">path</div><br>
<div th:text="${timestamp}">timestamp</div><br>
<div th:text="${message}">message</div><br>
</body>
</html>

启动项目,访问:http://localhost:8080/hello
在这里插入图片描述

注意:

  如果静态异常页面、动态异常页面两种方式同时出现,那么该异常如何处理,例如:classpath:/static/error/500.htmlclasspath:/static/error/5xx.htmlclasspath:/templates/error/500.htmlclasspath:/templates/error/5xx.html ,同时出现时,那么完整的错误页面查找的顺序如下:
项目出现500错误:

  • 首先查找动态页面具体异常: classpath:/templates/error/500.html
  • 如果没有,那么就去找静态中的 具体异常页面: classpath:/static/error/500.html
  • 如果没有,那么去动态异常页面找:classpath:/templates/error/5xx.html
  • 如果还没有,则去静态异常页面找:classpath:/static/error/5xx.html
  • 如果以上四种都没有,则返回 Spring Boot 默认页面。

自定义异常数据

  默认情况下,在Spring Boot 中,所有的异常数据其实就是上文所展示出来的5条数据,这5条数据定义在 org.springframework.boot.web.servlet.error.DefaultErrorAttributes 类中,具体定义在 getErrorAttributes方法中 :

	@Override
	public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
		Map<String, Object> errorAttributes = new LinkedHashMap<>();
		errorAttributes.put("timestamp", new Date());
		addStatus(errorAttributes, webRequest);
		addErrorDetails(errorAttributes, webRequest, includeStackTrace);
		addPath(errorAttributes, webRequest);
		return errorAttributes;
	}

  DefaultErrorAttributes 类本身则是在 org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration 异常自动配置类中定义的,如果开发者没有自己提供一个 ErrorAttributes 的实例的话,那么 Spring Boot 将自动提供一个ErrorAttributes 的实例,也就是 DefaultErrorAttributes 。

基于此 ,开发者自定义 ErrorAttributes 有两种方式 :

直接实现 ErrorAttributes 接口
继承 DefaultErrorAttributes(推荐),因为 DefaultErrorAttributes 中对异常数据的处理已经完成,开发者可以直接使用。
具体定义如下:

@Component
public class MyErrorAttributes extends DefaultErrorAttributes {

    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        Map<String, Object> map = super.getErrorAttributes(webRequest, includeStackTrace);
        if ((Integer) map.get("status") == 500) {
            map.put("message","服务器繁忙中,请稍后再访问....");
        }
        return map;
    }
}

启动项目,访问:http://localhost:8080/hello
在这里插入图片描述
附加:如果想要另外添加自己的异常信息,由于该方法中的 getErrorAttributes 方法中的 map 不是hasMap 所以不可以修改,那么我们可以在方法中自定义一个 map2 集合,然后读取 map 中的数据存取到 map2 中,然后想添加自己的异常就可以添加了,最后返回 map2。这里小编就不演示了,有兴趣的朋友可以试试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值