Spring Boot2 系列教程(十三)Spring Boot 中的全局异常处理

此时,启动项目,如果项目抛出 500 请求错误,就会自动展示 500.html 这个页面,发生 404 就会展示 404.html 页面。如果异常展示页面既存在 5xx.html,也存在 500.html ,此时,发生500异常时,优先展示 500.html 页面。

动态异常页面


动态的异常页面定义方式和静态的基本 一致,可以采用的页面模板有 jsp、freemarker、thymeleaf。动态异常页面,也支持 404.html 或者 4xx.html ,但是一般来说,由于动态异常页面可以直接展示异常详细信息,所以就没有必要挨个枚举错误了 ,直接定义 4xx.html(这里使用thymeleaf模板)或者 5xx.html 即可。

注意,动态页面模板,不需要开发者自己去定义控制器,直接定义异常页面即可 ,Spring Boot 中自带的异常处理器会自动查找到异常页面。

页面定义如下:

页面内容如下:

Title

5xx

path error message timestamp status

默认情况下,完整的异常信息就是这5条,展示 效果如下 :

如果动态页面和静态页面同时定义了异常处理页面,例如 classpath:/static/error/404.htmlclasspath:/templates/error/404.html 同时存在时,默认使用动态页面。即完整的错误页面查找方式应该是这样:

发生了 500 错误–>查找动态 500.html 页面–>查找静态 500.html --> 查找动态 5xx.html–>查找静态 5xx.html。

自定义异常数据


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

@Override

public Map<String, Object> getErrorAttributes(ServerRequest request,

boolean includeStackTrace) {

Map<String, Object> errorAttributes = new LinkedHashMap<>();

errorAttributes.put(“timestamp”, new Date());

errorAttributes.put(“path”, request.path());

Throwable error = getError(request);

HttpStatus errorStatus = determineHttpStatus(error);

errorAttributes.put(“status”, errorStatus.value());

errorAttributes.put(“error”, errorStatus.getReasonPhrase());

errorAttributes.put(“message”, determineMessage(error));

handleException(errorAttributes, determineException(error), includeStackTrace);

return errorAttributes;

}

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

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

  1. 直接实现 ErrorAttributes 接口

  2. 继承 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;

}

}

定义好的 ErrorAttributes 一定要注册成一个 Bean ,这样,Spring Boot 就不会使用默认的 DefaultErrorAttributes 了,运行效果如下图:

自定义异常视图


异常视图默认就是前面所说的静态或者动态页面,这个也是可以自定义的,首先 ,默认的异常视图加载逻辑在 org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController 类的 errorHtml 方法中,这个方法用来返回异常页面+数据,还有另外一个 error 方法,这个方法用来返回异常数据(如果是 ajax 请求,则该方法会被触发)。

@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)

public ModelAndView errorHtml(HttpServletRequest request,

HttpServletResponse response) {

HttpStatus status = getStatus(request);

Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(

request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));

response.setStatus(status.value());

ModelAndView modelAndView = resolveErrorView(request, response, status, model);

return (modelAndView != null) ? modelAndView : new ModelAndView(“error”, model);

}

在该方法中 ,首先会通过 getErrorAttributes 方法去获取异常数据(实际上会调用到 ErrorAttributes 的实例 的 getErrorAttributes 方法),然后调用 resolveErrorView 去创建一个 ModelAndView ,如果这里创建失败,那么用户将会看到默认的错误提示页面。

Ending

Tip:由于文章篇幅有限制,下面还有20个关于MySQL的问题,我都复盘整理成一份pdf文档了,后面的内容我就把剩下的问题的目录展示给大家看一下

如果觉得有帮助不妨【转发+点赞+关注】支持我,后续会为大家带来更多的技术类文章以及学习类文章!(阿里对MySQL底层实现以及索引实现问的很多)

吃透后这份pdf,你同样可以跟面试官侃侃而谈MySQL。其实像阿里p7岗位的需求也没那么难(但也不简单),扎实的Java基础+无短板知识面+对某几个开源技术有深度学习+阅读过源码+算法刷题,这一套下来p7岗差不多没什么问题,还是希望大家都能拿到高薪offer吧。

赞+关注】支持我,后续会为大家带来更多的技术类文章以及学习类文章!**(阿里对MySQL底层实现以及索引实现问的很多)

[外链图片转存中…(img-veLUismd-1723550833995)]

[外链图片转存中…(img-5SUgeVLp-1723550833996)]

吃透后这份pdf,你同样可以跟面试官侃侃而谈MySQL。其实像阿里p7岗位的需求也没那么难(但也不简单),扎实的Java基础+无短板知识面+对某几个开源技术有深度学习+阅读过源码+算法刷题,这一套下来p7岗差不多没什么问题,还是希望大家都能拿到高薪offer吧。

  • 25
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值