16、springboot——错误处理原理+定制错误页面(1)
一、springboot默认的处理机制
1.浏览器返回一个错误的页面
默认处理错误:返回一个错误的页面:
包括错误类型、时间......


2.其他客户端访问
默认响应一个json数据

原理:
错误自动配置的类:ErrorMvcAutoConfiguration.java

默认配置:
@Bean @ConditionalOnMissingBean( value = {ErrorAttributes.class}, search = SearchStrategy.CURRENT ) public DefaultErrorAttributes errorAttributes() { return new DefaultErrorAttributes(this.serverProperties.getError().isIncludeException()); } @Bean @ConditionalOnMissingBean( value = {ErrorController.class}, search = SearchStrategy.CURRENT ) public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) { return new BasicErrorController(errorAttributes, this.serverProperties.getError(), this.errorViewResolvers); } @Bean public ErrorMvcAutoConfiguration.ErrorPageCustomizer errorPageCustomizer() { return new ErrorMvcAutoConfiguration.ErrorPageCustomizer(this.serverProperties, this.dispatcherServletPath); } @Bean @ConditionalOnBean({DispatcherServlet.class}) @ConditionalOnMissingBean public DefaultErrorViewResolver conventionErrorViewResolver() { return new DefaultErrorViewResolver(this.applicationContext, this.resourceProperties); }
1、DefaultErrorAttributes:
在页面共享信息 public Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) { Map<String, Object> errorAttributes = new LinkedHashMap(); errorAttributes.put("timestamp", new Date()); errorAttributes.put("path", request.path()); Throwable error = this.getError(request); HttpStatus errorStatus = this.determineHttpStatus(error); errorAttributes.put("status", errorStatus.value()); errorAttributes.put("error", errorStatus.getReasonPhrase()); errorAttributes.put("message", this.determineMessage(error)); this.handleException(errorAttributes, this.determineException(error), includeStackTrace); return errorAttributes; }
2、BasicErrorController:处理默认/error请求
@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 = this.getStatus(request); Map<String, Object> model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML))); response.setStatus(status.value()); //去哪个页面作为错误页面,包含页面地址和页面内容 ModelAndView modelAndView = this.resolveErrorView(request, response, status, model); return modelAndView != null ? modelAndView : new ModelAndView("error", model); } @RequestMapping //产生json数据,其他客户端来到这个方法处理; public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) { Map<String, Object> body = this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.ALL)); HttpStatus status = this.getStatus(request); return new ResponseEntity(body, status); } ... }
3、ErrorPageCustomizer:
public class ErrorProperties { @Value("${error.path:/error}") private String path = "/error"; public String getPath() { return this.path; } ... }
4、DefaultErrorViewResolver:
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { ModelAndView modelAndView = this.resolve(String.valueOf(status.value()), model); if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) { modelAndView = this.resolve((String)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); //模板引擎不可用,就在静态资源文件夹下找errorViewName对应的页面 return provider != null ? new ModelAndView(errorViewName, model) : this.resolveResource(errorViewName, model); }
步骤:
一但系统出现4xx或者5xx之类的错误;ErrorPageCustomizer就会生效(定制错误的响应规则);
就会来到/error请求,就会被BasicErrorController进行处理
1)响应页面(resolveErrorView方法)去哪个页面是由DefaultErrorViewResolver解析得到的
protected ModelAndView resolveErrorView(HttpServletRequest request, HttpServletResponse response, HttpStatus status, Map<String, Object> model) { //所有的ErrorViewResolver得到ModelAndView Iterator var5 = this.errorViewResolvers.iterator(); ModelAndView modelAndView; do { if (!var5.hasNext()) { return null; } ErrorViewResolver resolver = (ErrorViewResolver)var5.next(); modelAndView = resolver.resolveErrorView(request, status, model); } while(modelAndView == null); return modelAndView; }
分类:
SpringBoot
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)