Spring Boot默认异常处理

Spring Boot默认异常处理


在日常的 Web 开发中,会经常遇到大大小小的异常,此时往往需要一个统一的异常处理机制,来保证客户端能接收较为友好的提示。Spring Boot 同样提供了一套默认的异常处理机制,本节将对它进行详细的介绍。
Spring Boot 默认异常处理机制
Spring Boot 提供了一套默认的异常处理机制,一旦程序中出现了异常,Spring Boot 会自动识别客户端的类型(浏览器客户端或机器客户端),并根据客户端的不同,以不同的形式展示异常信息。 1. 对于浏览器客户端而言,Spring Boot 会响应一个“ whitelabel”错误视图,以 HTML 格式呈现错误信息,如图 1;

图1:Spring Boot 默认错误白页
2. 对于机器客户端而言,Spring Boot 将生成 JSON 响应,来展示异常消息。{ "timestamp": "2021-07-12T07:05:29.885+00:00", "status": 404, "error": "Not Found", "message": "No message available", "path": "/m1ain.html" }
Spring Boot 异常处理自动配置原理
Spring Boot 通过配置类 ErrorMvcAutoConfiguration 对异常处理提供了自动配置,该配置类向容器中注入了以下 4 个组件。
●ErrorPageCustomizer:该组件会在在系统发生异常后,默认将请求转发到“/error”上。
●BasicErrorController:处理默认的“/error”请求。
●DefaultErrorViewResolver:默认的错误视图解析器,将异常信息解析到相应的错误视图上。
●DefaultErrorAttributes:用于页面上共享异常信息。
下面,我们依次对这四个组件进行详细的介绍。
ErrorPageCustomizer
ErrorMvcAutoConfiguration 向容器中注入了一个名为 ErrorPageCustomizer 的组件,它主要用于定制错误页面的响应规则。


ErrorPageCustomizer 通过 registerErrorPages() 方法来注册错误页面的响应规则。当系统中发生异常后,ErrorPageCustomizer 组件会自动生效,并将请求转发到 “/error”上,交给 BasicErrorController 进行处理,其部分代码如下。


BasicErrorController
ErrorMvcAutoConfiguration 还向容器中注入了一个错误控制器组件 BasicErrorController,代码如下。


BasicErrorController 的定义如下。


Spring Boot 通过 BasicErrorController 进行统一的错误处理(例如默认的“/error”请求)。Spring Boot 会自动识别发出请求的客户端的类型(浏览器客户端或机器客户端),并根据客户端类型,将请求分别交给 errorHtml() 和 error() 方法进行处理。

返回值类型

方法声明

客户端类型

错误信息返类型

ModelAndView

errorHtml(HttpServletRequest request, HttpServletResponse response)

浏览器客户端

text/html(错误页面)

ResponseEntity<Map<String, Object>>

error(HttpServletRequest request)

机器客户端(例如安卓、IOS、Postman 等等)

JSON

换句话说,当使用浏览器访问出现异常时,会进入 BasicErrorController 控制器中的 errorHtml() 方法进行处理,当使用安卓、IOS、Postman 等机器客户端访问出现异常时,就进入error() 方法处理。
在 errorHtml() 方法中会调用父类(AbstractErrorController)的 resolveErrorView() 方法,代码如下。


从上述源码可以看出,在响应页面的时候,会在父类的 resolveErrorView 方法中获取容器中所有的 ErrorViewResolver 对象(错误视图解析器,包括 DefaultErrorViewResolver 在内),一起来解析异常信息。
DefaultErrorViewResolver
ErrorMvcAutoConfiguration 还向容器中注入了一个默认的错误视图解析器组件 DefaultErrorViewResolver,代码如下。


当发出请求的客户端为浏览器时,Spring Boot 会获取容器中所有的 ErrorViewResolver 对象(错误视图解析器),并分别调用它们的 resolveErrorView() 方法对异常信息进行解析,其中自然也包括 DefaultErrorViewResolver(默认错误信息解析器)。 DefaultErrorViewResolver 的部分代码如下。


DefaultErrorViewResolver 解析异常信息的步骤如下:
1根据错误状态码(例如 404、500、400 等),生成一个错误视图 error/status,例如 error/404、error/500、error/400。
2尝试使用模板引擎解析 error/status 视图,即尝试从 classpath 类路径下的 templates 目录下,查找 error/status.html,例如 error/404.html、error/500.html、error/400.html。
3若模板引擎能够解析到 error/status 视图,则将视图和数据封装成 ModelAndView 返回并结束整个解析流程,否则跳转到第 4 步。
4依次从各个静态资源文件夹中查找 error/status.html,若在静态文件夹中找到了该错误页面,则返回并结束整个解析流程,否则跳转到第 5 步。
5将错误状态码(例如 404、500、400 等)转换为 4xx 或 5xx,然后重复前 4 个步骤,若解析成功则返回并结束整个解析流程,否则跳转第 6 步。
6处理默认的 “/error ”请求,使用 Spring Boot 默认的错误页面(Whitelabel Error Page)。
DefaultErrorAttributes
ErrorMvcAutoConfiguration 还向容器中注入了一个组件默认错误属性处理工具 DefaultErrorAttributes,代码如下。


DefaultErrorAttributes 是 Spring Boot 的默认错误属性处理工具,它可以从请求中获取异常或错误信息,并将其封装为一个 Map 对象返回,其部分代码如下。

public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver, Ordered {

......

@Override

public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {

Map<String, Object> errorAttributes = getErrorAttributes(webRequest, options.isIncluded(Include.STACK_TRACE));

if (!options.isIncluded(Include.EXCEPTION)) {

errorAttributes.remove("exception");

}

if (!options.isIncluded(Include.STACK_TRACE)) {

errorAttributes.remove("trace");

}

if (!options.isIncluded(Include.MESSAGE) && errorAttributes.get("message") != null) {

errorAttributes.remove("message");

}

if (!options.isIncluded(Include.BINDING_ERRORS)) {

errorAttributes.remove("errors");

}

return errorAttributes;

}

private 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;

}

......

}


在 Spring Boot 默认的 Error 控制器(BasicErrorController)处理错误时,会调用 DefaultErrorAttributes 的 getErrorAttributes() 方法获取错误或异常信息,并封装成 model 数据(Map 对象),返回到页面或 JSON 数据中。该 model 数据主要包含以下属性:
●timestamp:时间戳;
●status:错误状态码
●error:错误的提示
●exception:导致请求处理失败的异常对象
●message:错误/异常消息
●trace: 错误/异常栈信息
●path:错误/异常抛出时所请求的URL路径
所有通过 DefaultErrorAttributes 封装到 model 数据中的属性,都可以直接在页面或 JSON 中获取。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值