接下来学习我们的异常处理。
一、错误处理
1、看官网和理解

 
(1)默认处理
- 默认情况下,Spring Boot提供/error处理所有错误的映射
- 对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据。
  
以刚才的分析的啊,可以发现走正常的是可以的,比如我们做个不存在的页面用postman测试就会报错。
 
(2)自定义
- 要对其进行自定义,添加View解析为error
- 要完全替换默认行为,可以实现 ErrorController 并注册该类型的Bean定义,或添加ErrorAttributes类型的组件以使用现有机制但替换其内容。
- error/下的4xx,5xx页面会被自动解析;
  
  
2、错误处理底层组件功能分析
(1)自动配置原理

-  这个类型的组件(满足什么的条件后才生效) 
  
-  它还配置了controller(它能处理我们的JSON和错误的html) 
  
  
-  响应一个ModelAndView 
  
-  View中有一个id为error的组件 
  
-  这里也有了个解析器 
  
-  这里就是个默认的错误页 
  
-  可以响应的类型就html和JSON的类型 
  
-  再来看一下它的解析器 
  
  
 这里就有http的状态码作为视图页地址进行判断。
  
-  小总结:如果要返回错误页面,就会error视图(staticView)的一个默人的一个白页。 
-  再来详细看看这个 
  
  
 上面分析了我们的经过一系列后,会确定到底响应JSON啊或者html,这里就会显示到底显示什么内容,比如状态码啊等。
3、看看异常处理的流程
(1) 模拟一个异常

(2)执行目标方法

-  此时会有异常的话,就会被Cath掉,并且被dispatchException封装。 
  
 进入上面个方法后直接放行,然后来到这里
  
-  然后来到这里 
  
  
 标记当前请求结束。
-  这里就会拿到异常信息 
  
(3)进入视图解析流程

(4)处理方法异常

 就算你发生里异常,返回值都是ModelAndView
(5)异常解析器(又是解析器)

 遍历所有的handlerException
 
 看到我们的DefaultErrorAttributes
 
	@Nullable
	ModelAndView resolveException(
			HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);
- 系统默认的DefaultErrorAttributes它会将数据进行保存
  
- 上面判断后,会轮到其他的异常解析器判断处理。默认的没有任何处理异常的就会抛出异常。经过异常解析器后来到这里
  
  
(6)如果放行就发/error请求
如果没有任何处理机制,最终就会发送/error请求。
 
 自然而然的来到这里(我们刚刚分析的BasicErrorController)
 
 这里就可以拿到一些信息了,状态码等信息。
- 然后遍历所有的ErrorViewResolver看谁能解析
  
- 最后后DefaultErrorViewResolver的作用是把状态码作为错误页的地址进行拼接。
4、几种异常处理原理
(1)自定义错误页
在这里我们访问一个不存在的地址,模拟了404的错误,就发现了我们的4XX.html页面,如果模拟传过去的参数错误,同样的页面。【我们也可以单独写404.html,400.html等,它默认优先是按着精确匹配的】
 
(2)@ControllerAdvice + @ExceptionHandler处理全局异常
- 定义一个处理controller
  
 不难发现他也是一个controller
  
  
- 启动测试
  
 而且此时我们的error目录也没有删除,说明这个controller的优先级高于error目录
  
- 这种原理其实就是调用底层的ExceptionHandlerExceptionResolver进行处理的。
(3)@ResponseStatus + 自定义异常
-  比如定义一个UserManyException 
  
-  抛出异常 
  
-  启动测试 
  
 首先他来到默认的页面,说明它的优先级还是比较低的。
-  它底层就在这里 
  
 ResponseStatusExceptionResolver,把responseStatus的信息拿到就返回一个ModelAndView(它的底层会调用sendError方法,会直接结束)进行处理。给我们的现象是error目录的优先级高于这一层配置的,原因是因为我们的请求后,底层又相当于我们之前分析的了,发送了一次error请求。
(4)String底层的异常
- 比如参数类型转换异常
- 它底层就是我们的DefaultHandlerExceptionResolver来进行处理框架底层的异常,底层也是有调用这个response.sendError()方法进行处理。
(5)自定义我们的异常解析器
所有的异常解析器都是HandlerExceptionResolver的子类,我们也可以自定义我们的异常解析器
 
 经过上面的定以后,是没有生效的,如果再下上Order设置优先级,数字越小,优先级越高。
 
 只要没人处理的异常,它都能捕获,










