spring boot自定义errorcontroller未生效,因2.3+默认server.error.include-message=never且basicerrorcontroller优先拦截异常;需实现errorcontroller接口并注册为@bean,禁用whitelabel页面,并确保error.html置于static/error/下。

Spring Boot 自定义 ErrorController 为什么没生效
因为 Spring Boot 2.3+ 默认启用了 server.error.include-message=never,且内置的 BasicErrorController 会拦截所有未捕获异常,直接返回 JSON 或白页——你写的 @Controller 或 @RestController 根本收不到请求。
- 确认是否在
application.properties中显式设置了server.error.include-message=always(仅调试用,生产禁用) - 自定义
ErrorController必须实现org.springframework.boot.web.servlet.error.ErrorController接口,并注册为@Bean,不能只写个普通 Controller - 若用了 WebMvcConfigurer +
addViewControllers()映射/error,它会被BasicErrorController优先覆盖,除非你先 disable 默认控制器:spring.boot.error.whitelabel.enabled=false
Thymeleaf 模板里显示异常详情要小心 status 和 error 变量名
Spring Boot 内置错误页面模板(如 error.html)默认通过 Model 传入 timestamp、status、error、exception、message、path 等变量。但这些名字不是固定的,取决于你用的是哪种错误处理器。
-
status是 HTTP 状态码(如404),error是错误类型描述(如Not Found),message默认为空(除非开了include-message) - 想显示堆栈?
exception字段只有在server.error.include-stacktrace=on_trace_param且 URL 带?trace=true时才存在;否则为空 - 别在模板里写
${exception.printStackTrace()}——会报错,要用${exception?.stackTrace}并配合th:if判断非空
ResponseEntityExceptionHandler 拦不住 404 和 406 错误
这个类只处理 @Controller 层抛出的异常(比如 @Valid 失败、手动 throw new RuntimeException()),但 404(NoHandlerFoundException)、406(NotAcceptableException)这类由 DispatcherServlet 早期阶段触发的异常,默认不进这里。
- 启用
spring.mvc.throw-exception-if-no-handler-found=true才能让 404 进到ResponseEntityExceptionHandler - 同时必须关掉静态资源默认处理:加
spring.web.resources.add-mappings=false,否则 404 仍被 ResourceHttpRequestHandler 吃掉 - 406 异常需要额外配置
ContentNegotiationManager,或改用@ExceptionHandler(NotAcceptableException.class)单独捕获
静态错误页(/error/404.html)优先级比模板高,但路径必须严格匹配
Spring Boot 支持直接放静态文件到 src/main/resources/static/error/ 下,按状态码命名(如 404.html、5xx.html),它会自动匹配——但这套机制只在没找到动态 error controller 时才生效,而且对路径大小写和扩展名敏感。
- 文件必须放在
static/error/(不是templates/error/),且命名只能是数字(404.html)或通配符(5xx.html),不能叫not-found.html - 如果项目用了
WebMvcConfigurer并重写了addResourceHandlers(),可能屏蔽了默认的 error 资源定位逻辑 - 本地开发时浏览器缓存 404 页面很顽固,建议用无痕模式或加时间戳参数测试
error.html 放错目录层级,或者忘了在模板里用 th:fragment="error" 配合 layout 复用——这些地方一错,页面就回退到空白或默认白页,查日志都看不到明显报错。










