- ErrorMvcAutoConfiguration 自动配置异常处理规则
-
容器中的组件:类型:DefaultErrorAttributes—>id:errorAttributes
-
public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver
-
用于定义返回的页面中默认包含哪些数据
-
-
容器中的组件:类型BasicErrorController—>id:basicErrorController (json+白页)适配响应
-
处理默认 /error路径的请求 :页面响应 ModelAndView("error", model)
-
或者以json数据写回信息
@RequestMapping({"${server.error.path:${error.path:/error}}"}) public class BasicErrorController extends AbstractErrorController //以视图返回 @RequestMapping( produces = {"text/html"} ) public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) //以json数据写回 @RequestMapping public ResponseEntity -
容器中还会有一个view组件 名字为error(相应的是默认错误页)
@Bean( name = {"error"} ) @ConditionalOnMissingBean( name = {"error"} ) public View defaultErrorView() { return this.defaultErrorView; } -
为了解析视图,容器中还放了组件BeanNameViewResolver(视图解析器);按照返回的视图名为id去容器中找到view对象
@Bean @ConditionalOnMissingBean public BeanNameViewResolver beanNameViewResolver() { BeanNameViewResolver resolver = new BeanNameViewResolver(); resolver.setOrder(2147483637); return resolver; }
**总结**:如果想要返回页面,就会找error视图【StaticView】(而error视图是白页)
-
-
容器中的组件:类型:DefaultErrorViewResolver—>id:conventionErrorViewResolver
-
private ModelAndView resolve(String viewName, Map
model) { String errorViewName = "error/" + viewName; TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName, this.applicationContext); return provider != null ? new ModelAndView(errorViewName, model) : this.resolveResource(errorViewName, model); } 看到上面这块源码其中errorViewName是错误视图名称,这个在源码下默认为error目录下的viewName 参数中的viewName是视图名称,那么调用这个方法的时候,视图名称到底是什么呢?
-
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map
model) { ModelAndView modelAndView = this.resolve(String.valueOf(status.value()), model); if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) { modelAndView = this.resolve((String)SERIES_VIEWS.get(status.series()), model); } return modelAndView; } 在这里,我们看到,调用resolve方法时,viewName传入的是(String)SERIES_VIEWS.get(status.series()),即传入的是http返回的错误状态码。再看下面这段代码
-
static { Mapviews = new EnumMap(Series.class); views.put(Series.CLIENT_ERROR, "4xx"); views.put(Series.SERVER_ERROR, "5xx"); SERIES_VIEWS = Collections.unmodifiableMap(views); }
这一段代码向==SERIES_VIEWS==中封装了**4xx**和**5xx**的状态码,所以我们综合上面的三段代码,可以清楚的知道:springboot在底层处理错误时,对于视图名称的获取默认规则是 /error/4xx.html或者/error/5xx.html 。因此我们在模版引擎中创建一个error目录,下面存放着我们要进行展示的资源,并以4xx或者5xx命名,我们就可以展示我们自定义的错误处理页面了。
-
-
通常,springmvc对于请求的处理是进入dispatchServlet进行请求处理的分配。在doDispatch这个方法中,进行了所以异常的捕捉。
2.进入视图解析流程processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException)3.mv=processHandlerException,处理handler发生的异常. 处理完成后返回mv
-
1.遍历所有的handlerExceptionResolvers,看看谁能处理异常 HandlerExceptionResolver 处理器异常解析器
-
2.默认的异常解析器: 如下图
1.其中DefaultErrorAtrrtibutes先来处理异常,将异常信息保存在request域中,并且返回null
2.默认没有任何解析器可以处理异常,所以异常会被抛出
3.如果没有人能处理,最终底层会发送/error请求,然后被BasicErrorController所处理。
1.遍历所有的ErrorViewResolver,看谁能解析异常,而默认的ErrorViewResolver为DefaultErrorViewResolver
DefaultErrorViewResolver作用是把响应状态码作为错误页的地址,error/5xx.html
4.模板引擎最终响应这个页面



