本例介绍SpringBoot错误处理机制
错误处理现象
新建一个SpringBoot Web项目,在浏览器中随便输入一个错误地址进行访问,如:http://localhost:8081/test/aa,会出现一个错误页面
浏览器页面错误:

如果用PostMan请求错误地址,得到一个Json错误
Json错误:

错误处理原理
可以参考ErrorMvcAutoConfiguration,错误处理的自动配置
一但系统出现4xx或者5xx之类的错误;ErrorPageCustomizer就会生效(定制错误的响应规则);就会来到/error请求;就会被BasicErrorController处理;
1、DefaultErrorAttributes: 错误请求中有的属性
1 @Override
2 public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
3 Map<String, Object> errorAttributes = new LinkedHashMap<>();
4 errorAttributes.put("timestamp", new Date());
5 addStatus(errorAttributes, webRequest);
6 addErrorDetails(errorAttributes, webRequest, includeStackTrace);
7 addPath(errorAttributes, webRequest);
8 return errorAttributes;
9 }
2、BasicErrorController: 处理默认/error请求
1 // 产生error界面
2 @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
3 public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
4 HttpStatus status = getStatus(request);
5 Map<String, Object> model = Collections
6 // getErrorAttributes 获取错误内容
7 .unmodifiableMap(getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
8 response.setStatus(status.value());
9
10 // 去哪个错误界面
11 ModelAndView modelAndView = resolveErrorView(request, response, status, model);
12 return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
13 }
14
15 // 产生错误json数据
16 @RequestMapping
17 public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
18 Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL));
19 HttpStatus status = getStatus(request);
20 return new ResponseEntity<>(body, status);
21 }
3、ErrorPageCustomizer: 系统出现错误以后来到error请求进行处理;(web.xml注册的错误页面规则)
1 /**
2 * {@link WebServerFactoryCustomizer} that configures the server's error pages.
3 */
4 private static class ErrorPageCustomizer implements ErrorPageRegistrar, Ordered {
5
6 private final ServerProperties properties;
7
8 private final DispatcherServletPath dispatcherServletPath;
9
10 protected ErrorPageCustomizer(ServerProperties properties, DispatcherServletPath dispatcherServletPath) {
11 this.properties = properties;
12 this.dispatcherServletPath = dispatcherServletPath;
13 }
14
15 // 注入错误页面
16 @Override
17 public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
18 ErrorPage errorPage = new ErrorPage(
19 this.dispatcherServletPath.getRelativePath(this.properties.getError().getPath()));
20 errorPageRegistry.addErrorPages(errorPage);
21 }
22
23 @Override
24 public int getOrder() {
25 return 0;
26 }
27
28 }
// 错误路径配置
1 @Value("${error.path:/error}")
2 private String path = "/error";
4、DefaultErrorViewResolver: 响应页面去哪个页面是由DefaultErrorViewResolver解析得到的;
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
ModelAndView modelAndView = resolve(String.valueOf(status.value()), model);
if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
// status.series() 状态码
modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
}
return modelAndView;
}
private ModelAndView resolve(String viewName, Map<String, Object> model) {
//默认SpringBoot可以去找到一个页面? error/404
String errorViewName = "error/" + viewName;
//模板引擎可以解析这个页面地址就用模板引擎解析
TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName,
this.applicationContext);
if (provider != null) {
//模板引擎可用的情况下返回到errorViewName指定的视图地址
return new ModelAndView(errorViewName, model);
}
//模板引擎不可用,就在静态资源文件夹下找errorViewName对应的页面 error/404.html
return resolveResource(errorViewName, model);
}
来源:https://www.cnblogs.com/h--d/p/12387815.html