SpringBoot 学习笔记心得异常处理机制
Posted Adorable_Rocy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot 学习笔记心得异常处理机制相关的知识,希望对你有一定的参考价值。
前言:SpringBoot中,异常处理机制是十分完善的,我们在日常开发中遇到的异常问题,都可以进行拦截,并且给出友好界面进行交互。
1.默认规则
- 在SpringBoot中,在搭建完项目之后,访问localhost:8080会来到404空白页。
因为找不到欢迎页,所以来到默认404规则。
疑点:但是为什么在网页上显示的是html界面,在PostMan中显示的却是json数据呢?
2.定制错误处理逻辑
- 自定义错误界面,默认是从资源目录下的error/4xx.html 5xx.html 界面寻找,在都无法找到的情况下则显示白页404页面。
示例:
内容如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>自定义错误404界面</h1>
</body>
</html>
补充:一般将错误界面放置templates/error下,可以借助thymeleaf模板引擎进行信息获取。
3.异常处理机制原理
- ErrorMvcAutoConfiguration自动配置类
1.组件: DefaultErrorAttributes() ; id 为 errorAttributes
功能:包含获取基本错误信息(exception / trace / message / errors)
public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
Map<String, Object> errorAttributes = this.getErrorAttributes(webRequest, options.isIncluded(Include.STACK_TRACE));
if (Boolean.TRUE.equals(this.includeException)) {
options = options.including(new Include[]{Include.EXCEPTION});
}
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.put("message", "");
}
if (!options.isIncluded(Include.BINDING_ERRORS)) {
errorAttributes.remove("errors");
}
return errorAttributes;
}
补充:之前获取错误信息的方法已经过时啦,不建议继续使用了。
@Deprecated
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
Map<String, Object> errorAttributes = new LinkedHashMap();
errorAttributes.put("timestamp", new Date());
this.addStatus(errorAttributes, webRequest);
this.addErrorDetails(errorAttributes, webRequest, includeStackTrace);
this.addPath(errorAttributes, webRequest);
return errorAttributes;
}
- 组件:BasicErrorController ; id 为 basicErrorController (用于响应 json + html 界面)
1.这个组件可以用来解释上面的疑点,既可以响应json数据,又可以响应html界面
原因:
1).定义了修改默认错误访问路径:@RequestMapping({"$ {server.error.path:${error.path:/error}}"}),可通过 server.error.path 设置错误访问路径。
2). 默认处理路径/error , 视图转发.设定的是html响应。
3). 容器中放组件 BeanNameViewResolver(视图解析器), 按照返回的视图名作为组件的id去容器中找View对象。
4). 容器中的组件:类型:DefaultErrorViewResolver -> id:conventionErrorViewResolver- 在DefaultErrorViewResolver 视图解析器中,有resolveErrorView解析方法,在返回值modelAndView,调用了resolve(方法),resolve传入值为HTTP状态码,所以在拼串的时候,errorViewName= error/状态码(404),所以会找到error下的404.html界面,在找不到的情况下,会展示默认写好的404界面。
默认写好的界面:如果发生错误,想要返回界面,就会找视图(StaticView)空白页
- 在DefaultErrorViewResolver 视图解析器中,有resolveErrorView解析方法,在返回值modelAndView,调用了resolve(方法),resolve传入值为HTTP状态码,所以在拼串的时候,errorViewName= error/状态码(404),所以会找到error下的404.html界面,在找不到的情况下,会展示默认写好的404界面。
builder.append("<html><body><h1>Whitelabel Error Page</h1>")
.append("<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>").append("<div id='created'>").append(timestamp)
.append("</div>").append("<div>There was an unexpected error (type=").append(this.htmlEscape(model.get("error")))
.append(", status=").append(this.htmlEscape(model.get("status"))).append(").</div>");
补充:DefaultErrorViewResolver 中的静态代码块
static {
Map<Series, String> views = new EnumMap(Series.class);
views.put(Series.CLIENT_ERROR, "4xx");
views.put(Series.SERVER_ERROR, "5xx");
SERIES_VIEWS = Collections.unmodifiableMap(views);
}
异常处理机制原理思路以及实现都非常完整,关于底层原理还得不断继续学习。源码更新的速度也是十分快的,所以对于整体流程的把握十分重要。
以上是关于SpringBoot 学习笔记心得异常处理机制的主要内容,如果未能解决你的问题,请参考以下文章