承接前文
指定为true的时候(默认配置),则会显示前文样例中的错误信息,如下
源码层分析
springboot安排了ErrorMvcAutoConfiguration自动配置类来处理错误页面的相关信息,笔者分几个步骤来进行分析
No.1 脑壳上的注解看一发
@Configuration @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) // Load before the main WebMvcAutoConfiguration so that the error View is available @AutoConfigureBefore(WebMvcAutoConfiguration.class) @EnableConfigurationProperties({ ServerProperties.class, ResourceProperties.class }) public class ErrorMvcAutoConfiguration { }可以看出其是排在WebMvcAutoConfiguration配置类之前的,那么为什么需要排在前面呢?看注释是说这样才可以使error视图有效,那怎么实现的呢?笔者带着问题继续往下探索
No.2 DefaultErrorViewResolverConfiguration内部类-错误视图解析器注册
@Configuration static class DefaultErrorViewResolverConfiguration { private final ApplicationContext applicationContext; private final ResourceProperties resourceProperties; DefaultErrorViewResolverConfiguration(ApplicationContext applicationContext, ResourceProperties resourceProperties) { this.applicationContext = applicationContext; this.resourceProperties = resourceProperties; } // 注册了DefaultErrorViewResolver解析器 @Bean @ConditionalOnBean(DispatcherServlet.class) @ConditionalOnMissingBean public DefaultErrorViewResolver conventionErrorViewResolver() { return new DefaultErrorViewResolver(this.applicationContext, this.resourceProperties); } }DefaultErrorViewResolver这个默认的错误视图解析器很有意思,里面包含了一些默认的处理,也分几个小步骤来吧,这样会显得清晰
- 静态方法了解
static { Map<Series, String> views = new EnumMap<>(Series.class); views.put(Series.CLIENT_ERROR, "4xx"); views.put(Series.SERVER_ERROR, "5xx"); SERIES_VIEWS = Collections.unmodifiableMap(views); }应该是对HTTP状态码的映射处理,以4开头的是客户端错误,5开头的为服务端错误
- 构造函数了解
public DefaultErrorViewResolver(ApplicationContext applicationContext, ResourceProperties resourceProperties) { Assert.notNull(applicationContext, "ApplicationContext must not be null"); Assert.notNull(resourceProperties, "ResourceProperties must not be null"); this.applicationContext = applicationContext; this.resourceProperties = resourceProperties; // 模板加载器 this.templateAvailabilityProviders = new TemplateAvailabilityProviders( applicationContext); }上述的模板加载器主要是读取所有spring.factories中的org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider对应的属性值,本质也就是模板的渲染器,比如我们常用的freemarker、velocity、jsp等等
- 视图对象获取了解
@Override public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { // 优先根据状态码来查找view静态资源,比如404则会查找error/404视图 ModelAndView modelAndView = resolve(String.valueOf(status), model); if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) { // 上述不存在则再查找error/4xx或者error/5xx视图 modelAndView = resolve(SERIES_VIEWS.get(status.series()), model); }
