当前位置: 首页 > article >正文

SpringBoot异常处理原理分析

springboot默认机制

错误处理的自动配置都在ErrorMvcAutoConfiguration中,两大核心机制:

    1. SpringBoot 会自适应处理错误,响应页面或JSON数据
    1. SpringMVC的错误处理机制依然保留,MVC处理不了,才会交给boot进行处理

在这里插入图片描述

  • 发生错误以后,转发给/error路径,SpringBoot在底层写好一个 BasicErrorController的组件,专门处理这个请求
	@RequestMapping(produces = MediaType.TEXT_HTML_VALUE) //返回HTML
	public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
		HttpStatus status = getStatus(request);
		Map<String, Object> model = Collections
			.unmodifiableMap(getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML)));
		response.setStatus(status.value());
		ModelAndView modelAndView = resolveErrorView(request, response, status, model);
		return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
	}

	@RequestMapping  //返回 ResponseEntity, JSON
	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);
	}
  • 错误页面是这么解析到的
//1、解析错误的自定义视图地址
ModelAndView modelAndView = resolveErrorView(request, response, status, model);
//2、如果解析不到错误页面的地址,默认的错误页就是 error
return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);

容器中专门有一个错误视图解析器

@Bean
@ConditionalOnBean(DispatcherServlet.class)
@ConditionalOnMissingBean(ErrorViewResolver.class)
DefaultErrorViewResolver conventionErrorViewResolver() {
    return new DefaultErrorViewResolver(this.applicationContext, this.resources);
}

SpringBoot解析自定义错误页的默认规则

	@Override
	public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
		ModelAndView modelAndView = resolve(String.valueOf(status.value()), model);
		if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
			modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
		}
		return modelAndView;
	}

	private ModelAndView resolve(String viewName, Map<String, Object> model) {
		String errorViewName = "error/" + viewName;
		TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName,
				this.applicationContext);
		if (provider != null) {
			return new ModelAndView(errorViewName, model);
		}
		return resolveResource(errorViewName, model);
	}

	private ModelAndView resolveResource(String viewName, Map<String, Object> model) {
		for (String location : this.resources.getStaticLocations()) {
			try {
				Resource resource = this.applicationContext.getResource(location);
				resource = resource.createRelative(viewName + ".html");
				if (resource.exists()) {
					return new ModelAndView(new HtmlResourceView(resource), model);
				}
			}
			catch (Exception ex) {
			}
		}
		return null;
	}

容器中有一个默认的名为 error 的 view; 提供了默认白页功能

@Bean(name = "error")
@ConditionalOnMissingBean(name = "error")
public View defaultErrorView() {
    return this.defaultErrorView;
}

封装了JSON格式的错误信息

	@Bean
	@ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
	public DefaultErrorAttributes errorAttributes() {
		return new DefaultErrorAttributes();
	}

规则:

  1. 解析一个错误页
    1. 如果发生了500、404、503、403 这些错误
      1. 如果有模板引擎,默认在 classpath:/templates/error/**精确码.html**
      2. 如果没有模板引擎,在静态资源文件夹下找 **精确码.html**
    2. 如果匹配不到精确码.html这些精确的错误页,就去找5xx.html4xx.html模糊匹配
      1. 如果有模板引擎,默认在 classpath:/templates/error/5xx.html
      2. 如果没有模板引擎,在静态资源文件夹下找 5xx.html
  2. 如果模板引擎路径templates下有 error.html页面,就直接渲染

springboot异常处理步骤流程

1、执行目标方法,目标方法运行期间有任何异常都会被catch、而且标志当前请求结束;并且用 **dispatchException **
2、进入视图解析流程(页面渲染?)
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
3、**mv **= processHandlerException;处理handler发生的异常,处理完成返回ModelAndView;

  • 1、遍历所有的 handlerExceptionResolvers,看谁能处理当前异常【HandlerExceptionResolver处理器异常解析器】
  • image.png
  • 2、系统默认的 异常解析器;
  • image.png
    • 1、DefaultErrorAttributes先来处理异常。把异常信息保存到rrequest域,并且返回null;
    • 2、默认没有任何人能处理异常,所以异常会被抛出
      • 1、如果没有任何人能处理最终底层就会发送 /error 请求。会被底层的BasicErrorController处理
      • 2、解析错误视图;遍历所有的 ErrorViewResolver 看谁能解析。
      • image.png
      • **3、默认的 DefaultErrorViewResolver ,作用是把响应状态码作为错误页的地址,error/500.html **
      • **4、模板引擎最终响应这个页面 error/500.html **

最佳实战

  • 前后分离
    • 后台发生的所有错误,**@ControllerAdvice + @ExceptionHandler**进行统一异常处理。
  • 服务端页面渲染
    • 不可预知的一些,HTTP码表示的服务器或客户端错误
      • **classpath:/templates/error/**下面,放常用精确的错误码页面。**500.html****404.html**
      • **classpath:/templates/error/**下面,放通用模糊匹配的错误码页面。 **5xx.html****4xx.html**
    • 发生业务错误
      • 核心业务,每一种错误,都应该代码控制,跳转到自己定制的错误页。
      • 通用业务,**classpath:/templates/error.html**页面,显示错误信息。

页面,JSON,可用的Model数据如下
image.png


http://www.kler.cn/news/284692.html

相关文章:

  • JMeter 工具安装以及简单使用
  • 人工智能再次进化 善用AI提升营运效率
  • 力扣234题详解:回文链表的多种解法与模拟面试问答
  • scrapy学习笔记0828-下
  • 《自然语言处理》—— 词向量之CountVectorizer方法实现
  • raksmart机云大宽带服务器托管服务内容
  • 安防视频汇聚平台EasyCVR启动后无法访问登录页面是什么原因?
  • PhpStorm2024版设置自动换行(软换行)
  • 2024.8.31 Python,合并区间,用sort通过列表第一个元素给列表排序,三数之和,跳跃游戏
  • AcWing 897. 最长公共子序列
  • JVM 内存参数
  • JetBrains WebStorm 2024.2 (macOS, Linux, Windows) - 最智能的 JavaScript IDE
  • 合宙LuatOS开发板使用手册——Air700EAQ
  • 图像边缘检测Canny
  • HTTP 之 Web Sockets处理恶意的Payload的策略(十一)
  • const、inline、nullptr的使用
  • Android Activity 的启动模式(Launch Mode)
  • Vue 2 vs Vue 3:v-if 和 v-for 的差异
  • 物流需求回复势头稳定,目前全国社会物流总额达197.7万亿元
  • 从零开学C++:vector类
  • 【MySQL索引】4索引优化
  • Django Compressor压缩静态文件(js/css)
  • 搭建双主四从的MySQL集群
  • 【大模型】LangChain基础学习
  • 某大厂前端面试题
  • 自然语言处理与深度学习的结合
  • Eureka简介与开发
  • Axure RP实战:打造高效文字点选验证码
  • 销冠大模型案例
  • (一) 初入MySQL 【认识和部署】