异常定义页面优先级:
先精确后模糊,先动态后静态
404问题(优先级由高到低):
- templates/error/404.html
- static/error/404.html
- templates/error/4xx.html
- static/error/4xx.html
500问题(优先级由高到低):
- templates/error/500.html
- static/error/500.html
- templates/error/5xx.html
- static/error/5xx.html
异常处理原理解析
进入ErrorMvcAutoConfiguration类中,找到DefaultErrorViewResolver方法,默认错误视图解析器:
解析resolveErrorView方法:
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
//String.valueOf(status.value()) 获得错误的状态码
//model 是错误异常的信息
ModelAndView modelAndView = resolve(String.valueOf(status.value()), model);
//如果没有查询到视图,且存在4xx和5xx,调用resolve方法
if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
//传入状态码信息 和 错误异常的信息,调用resolve方法
modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
}
return modelAndView;
}
解析resolve方法(查找动态资源方法):
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);
}
//调用resolveResource,将状态码和错误异常的信息传入
return resolveResource(errorViewName, model);
}
解析resolveResource方法(查找静态资源方法):
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;
}