ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
默认效果: ​ 1)、浏览器,返回一个默认的错误页面 ![](https://img.kancloud.cn/2d/31/2d314aa4ad7f050deb17d829ed8ec157_747x202.png) 浏览器发送请求的请求头: ![](https://img.kancloud.cn/78/fe/78fe44db0d738c6c528cd697fcbcd0f4_714x113.png) ​ 2)、如果是其他客户端,默认响应一个json数据 ![](https://img.kancloud.cn/27/2d/272deb8306b563043ea3d3e8845a4d67_397x130.png) ![](https://img.kancloud.cn/c5/de/c5dea80336305ba5e1d33ff396953392_595x158.png) 原理: ​ 可以参照ErrorMvcAutoConfiguration;错误处理的自动配置; 给容器中添加了以下组件 ​ 1、DefaultErrorAttributes: ```java 帮我们在页面共享信息; @Override public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) { Map<String, Object> errorAttributes = new LinkedHashMap<String, Object>(); errorAttributes.put("timestamp", new Date()); addStatus(errorAttributes, requestAttributes); addErrorDetails(errorAttributes, requestAttributes, includeStackTrace); addPath(errorAttributes, requestAttributes); return errorAttributes; } ``` ​ 2、BasicErrorController:处理默认/error请求 ```java @Controller @RequestMapping("${server.error.path:${error.path:/error}}") public class BasicErrorController extends AbstractErrorController { @RequestMapping(produces = "text/html")//产生html类型的数据;浏览器发送的请求来到这个方法处理 public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { HttpStatus status = getStatus(request); Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes( request, isIncludeStackTrace(request, MediaType.TEXT_HTML))); response.setStatus(status.value()); //去哪个页面作为错误页面;包含页面地址和页面内容 ModelAndView modelAndView = resolveErrorView(request, response, status, model); return (modelAndView == null ? new ModelAndView("error", model) : modelAndView); } @RequestMapping @ResponseBody //产生json数据,其他客户端来到这个方法处理; 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<Map<String, Object>>(body, status); } ``` ​ 3、ErrorPageCustomizer: ```java @Value("${error.path:/error}") private String path = "/error"; 系统出现错误以后来到error请求进行处理;(web.xml注册的错误页面规则) ``` ​ 4、DefaultErrorViewResolver: ```java @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) { //默认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); } ``` ​ 步骤: ​ 一但系统出现4xx或者5xx之类的错误;ErrorPageCustomizer就会生效(定制错误的响应规则);就会来到/error请求;就会被**BasicErrorController**处理; ​ 1)响应页面;去哪个页面是由**DefaultErrorViewResolver**解析得到的; ```java protected ModelAndView resolveErrorView(HttpServletRequest request, HttpServletResponse response, HttpStatus status, Map<String, Object> model) { //所有的ErrorViewResolver得到ModelAndView for (ErrorViewResolver resolver : this.errorViewResolvers) { ModelAndView modelAndView = resolver.resolveErrorView(request, status, model); if (modelAndView != null) { return modelAndView; } } return null; } ```