Blog

  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 搜索

SpringBoot自动装配--ErrorMvcAutoConfiguration

发表于 2019-08-17 分类于 SpringBoot 阅读次数:
本文字数: 7.1k

简介

Springboot项目在启动的时候,会自动装配一些常用的配置类(xxxAuoConfiguration),今天就来看一下和error有关的自动装配

ErrorMvcAutoConfiguration

1
2
3
4
5
6
7
@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 {}

ErrorMvcAutoConfiguration中有以下的组件:

DefaultErrorAttributes

1
2
3
4
5
6
@Bean
@ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
public DefaultErrorAttributes errorAttributes() {
return new DefaultErrorAttributes(
this.serverProperties.getError().isIncludeException());
}

DefaultErrorAttributes中有个getErrorAttributes方法,是用于获取错误信息的

1
2
3
4
5
6
7
8
9
10
@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest,
boolean includeStackTrace) {
Map<String, Object> errorAttributes = new LinkedHashMap<>();
errorAttributes.put("timestamp", new Date());
addStatus(errorAttributes, webRequest);
addErrorDetails(errorAttributes, webRequest, includeStackTrace);
addPath(errorAttributes, webRequest);
return errorAttributes;
}

ErrorPageCustomizer

1
2
3
4
@Bean
public ErrorPageCustomizer errorPageCustomizer() {
return new ErrorPageCustomizer(this.serverProperties);
}

其中主要有个registerErrorPages,这就是获取错误页面路径的方法。会返回一个
path=/error,所以springboot默认会跳转到/error

1
2
3
4
5
6
7
@Override
public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
ErrorPage errorPage = new ErrorPage(
this.properties.getServlet().getServletPrefix()
+ this.properties.getError().getPath());
errorPageRegistry.addErrorPages(errorPage);
}

DefaultErrorViewResolver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Configuration
static class DefaultErrorViewResolverConfiguration {

private final ApplicationContext applicationContext;

private final ResourceProperties resourceProperties;

DefaultErrorViewResolverConfiguration(ApplicationContext applicationContext,
ResourceProperties resourceProperties) {
this.applicationContext = applicationContext;
this.resourceProperties = resourceProperties;
}

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

}

默认的错误页面解析器,其中的主要方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status,
Map<String, Object> model) {
ModelAndView modelAndView = resolve(String.valueOf(status), 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) {
//错误页面的名称 error/状态码
String errorViewName = "error/" + viewName;
//Get the provider that can be used to render the given view.
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.resourceProperties.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;
}

WhitelabelErrorViewConfiguration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Configuration
@ConditionalOnProperty(prefix = "server.error.whitelabel", name = "enabled", matchIfMissing = true)
@Conditional(ErrorTemplateMissingCondition.class)
protected static class WhitelabelErrorViewConfiguration {

private final SpelView defaultErrorView = new SpelView(
"<html><body><h1>Whitelabel Error Page</h1>"
+ "<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>"
+ "<div id='created'>${timestamp}</div>"
+ "<div>There was an unexpected error (type=${error}, status=${status}).</div>"
+ "<div>${message}</div></body></html>");

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

// If the user adds @EnableWebMvc then the bean name view resolver from
// WebMvcAutoConfiguration disappears, so add it back in to avoid disappointment.
@Bean
@ConditionalOnMissingBean(BeanNameViewResolver.class)
public BeanNameViewResolver beanNameViewResolver() {
BeanNameViewResolver resolver = new BeanNameViewResolver();
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
return resolver;
}

}

这个就是默认的白页,当没有自定义的error页面时,springboot默认会使用白页。如果在template中存在了error.html,就不会注册这个bean

BasicErrorController

1
2
3
4
5
6
@Bean
@ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
this.errorViewResolvers);
}

BasicErrorController是默认处理/error请求的。其中有两个主要的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {
//返回的是页面,一般是浏览器发送的请求
@RequestMapping(produces = "text/html")
public ModelAndView errorHtml(HttpServletRequest request,
HttpServletResponse response) {
HttpStatus status = getStatus(request);
//获取异常的信息,其中的getErrorAttributes就是DefaultErrorAttributes中的方法
Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
response.setStatus(status.value());
//获取页面,就是使用DefaultErrorViewResolver中的方法
ModelAndView modelAndView = resolveErrorView(request, response, status, model);
//如果modeAndView是null的话,就new一个,其中viewName是error,如果template中存在自定义的error.html的话就会使用自定义的,否则使用默认的白页。
return (modelAndView == null ? new ModelAndView("error", model) : modelAndView);
}
//返回的是json数据
@RequestMapping
@ResponseBody
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map<String, Object> body = getErrorAttributes(request,
isIncludeStackTrace(request, MediaType.ALL));
HttpStatus status = getStatus(request);
return new ResponseEntity<>(body, status);
}
}

------ 已触及底线感谢您的阅读 ------
麻辣香锅不要辣 微信支付

微信支付

  • 本文作者: 麻辣香锅不要辣
  • 本文链接: https://http://ybhub.gitee.io/2019/08/17/springboot-ErrorMvcAutoConfiguration/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
# SpringBoot # 自动装配
Mybatis_参数处理过程
SpringBoot自动装配--嵌入式Servlet容器
  • 文章目录
  • 站点概览
麻辣香锅不要辣

麻辣香锅不要辣

21 日志
11 分类
20 标签
GitHub 简书
  1. 1. 简介
  2. 2. ErrorMvcAutoConfiguration
    1. 2.1. DefaultErrorAttributes
    2. 2.2. ErrorPageCustomizer
    3. 2.3. DefaultErrorViewResolver
    4. 2.4. WhitelabelErrorViewConfiguration
    5. 2.5. BasicErrorController
© 2019 – 2020 麻辣香锅不要辣 | 站点总字数: 20.4k字
|
0%