详解Spring Boot默认异常处理,java程序员面试宝典第五版

ErrorPageCustomizer

ErrorMvcAutoConfiguration 向容器中注入了一个名为 ErrorPageCustomizer 的组件,它主要用于定制错误页面的响应规则。

@Bean

public ErrorPageCustomizer errorPageCustomizer(DispatcherServletPath dispatcherServletPath) {

return new ErrorPageCustomizer(this.serverProperties, dispatcherServletPath);

}

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

@Override

public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {

//将请求转发到 /errror(this.properties.getError().getPath())上

ErrorPage errorPage = new ErrorPage(this.dispatcherServletPath.getRelativePath(this.properties.getError().getPath()));

// 注册错误页面

errorPageRegistry.addErrorPages(errorPage);

}

BasicErrorController

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

@Bean

@ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)

public BasicErrorController basicErrorController(ErrorAttributes errorAttributes,

ObjectProvider errorViewResolvers) {

return new BasicErrorController(errorAttributes, this.serverProperties.getError(),

errorViewResolvers.orderedStream().collect(Collectors.toList()));

}

BasicErrorController 的定义如下。

//BasicErrorController 用于处理 “/error” 请求

@Controller

@RequestMapping(“KaTeX parse error: Expected '}', got 'EOF' at end of input: …ver.error.path:{error.path:/error}}”)

public class BasicErrorController extends AbstractErrorController {

/**

  • 该方法用于处理浏览器客户端的请求发生的异常

  • 生成 html 页面来展示异常信息

  • @param request

  • @param response

  • @return

*/

@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)

public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {

//获取错误状态码

HttpStatus status = getStatus(request);

//getErrorAttributes 根据错误信息来封装一些 model 数据,用于页面显示

Map<String, Object> model = Collections

.unmodifiableMap(getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML)));

//为响应对象设置错误状态码

response.setStatus(status.value());

//调用 resolveErrorView() 方法,使用错误视图解析器生成 ModelAndView 对象(包含错误页面地址和页面内容)

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

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

}

/**

  • 该方法用于处理机器客户端的请求发生的错误

  • 产生 JSON 格式的数据展示错误信息

  • @param request

  • @return

*/

@RequestMapping

public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {

HttpStatus status = getStatus(request);

if (status == HttpStatus.NO_CONTENT) {

return new ResponseEntity<>(status);

}

Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));

return new ResponseEntity<>(body, status);

}

}

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() 方法,代码如下。

protected ModelAndView resolveErrorView(HttpServletRequest request, HttpServletResponse response, HttpStatus status,

Map<String, Object> model) {

//获取容器中的所有的错误视图解析器来处理该异常信息

for (ErrorViewResolver resolver : this.errorViewResolvers) {

//调用错误视图解析器的 resolveErrorView 解析到错误视图页面

ModelAndView modelAndView = resolver.resolveErrorView(request, status, model);

if (modelAndView != null) {

return modelAndView;

}

}

return null;

}

从上述源码可以看出,在响应页面的时候,会在父类的 resolveErrorView 方法中获取容器中所有的 ErrorViewResolver 对象(错误视图解析器,包括 DefaultErrorViewResolver 在内),一起来解析异常信息。

DefaultErrorViewResolver

ErrorMvcAutoConfiguration 还向容器中注入了一个默认的错误视图解析器组件 DefaultErrorViewResolver,代码如下。

@Bean

@ConditionalOnBean(DispatcherServlet.class)

@ConditionalOnMissingBean(ErrorViewResolver.class)

DefaultErrorViewResolver conventionErrorViewResolver() {

return new DefaultErrorViewResolver(this.applicationContext, this.resources);

}

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

DefaultErrorViewResolver 的部分代码如下。

public class DefaultErrorViewResolver implements ErrorViewResolver, Ordered {

private static final Map<HttpStatus.Series, String> SERIES_VIEWS;

static {

Map<HttpStatus.Series, String> views = new EnumMap<>(HttpStatus.Series.class);

views.put(Series.CLIENT_ERROR, “4xx”);

views.put(Series.SERVER_ERROR, “5xx”);

SERIES_VIEWS = Collections.unmodifiableMap(views);

}

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

面试资料整理汇总

成功从小公司跳槽进蚂蚁定级P7,只因刷了七遍这些面试真题

成功从小公司跳槽进蚂蚁定级P7,只因刷了七遍这些面试真题

这些面试题是我朋友进阿里前狂刷七遍以上的面试资料,由于面试文档很多,内容更多,没有办法一一为大家展示出来,所以只好为大家节选出来了一部分供大家参考。

面试的本质不是考试,而是告诉面试官你会做什么,所以,这些面试资料中提到的技术也是要学会的,不然稍微改动一下你就凉凉了

在这里祝大家能够拿到心仪的offer!

!(备注Java)**
[外链图片转存中…(img-cGfnUt2k-1710433624502)]

面试资料整理汇总

[外链图片转存中…(img-9CBitnmO-1710433624502)]

[外链图片转存中…(img-dfG5RUbL-1710433624502)]

这些面试题是我朋友进阿里前狂刷七遍以上的面试资料,由于面试文档很多,内容更多,没有办法一一为大家展示出来,所以只好为大家节选出来了一部分供大家参考。

面试的本质不是考试,而是告诉面试官你会做什么,所以,这些面试资料中提到的技术也是要学会的,不然稍微改动一下你就凉凉了

在这里祝大家能够拿到心仪的offer!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值