Spring Boot自定义ErrorController未生效,无法显示自定义错误页面
我之前也碰到过一模一样的坑,咱们来拆解问题和解决办法:
问题根源
你通过@SpringBootApplication(exclude = { ErrorMvcAutoConfiguration.class })移除了默认错误配置,这不仅关掉了白标页面,还把Spring Boot自动将错误请求转发到/error端点的核心逻辑也删掉了。这就导致当应用抛出404、500这类错误时,Tomcat直接接管了错误处理,而不会把请求转发到你的CustomErrorController——这就是为什么你的handleError方法从来没被触发,但主动访问/error/404这类端点却正常的原因。
正确的解决方案
1. 恢复Spring Boot的错误转发机制,只禁用白标页面
把启动类上的exclude配置删掉,转而在application.properties(或application.yml)里添加配置来关闭白标页面:
server.error.whitelabel.enabled=false
这样Spring Boot会保留错误请求转发到/error的逻辑,同时不会显示默认的白标页面。
2. 优化CustomErrorController的映射(可选但推荐)
给你的handleError方法添加produces属性,明确处理HTML类型的请求,避免和其他类型的错误处理冲突:
import org.springframework.http.MediaType; import javax.servlet.RequestDispatcher; import javax.servlet.http.HttpServletRequest; @Controller @RequestMapping("/error") public class CustomErrorController implements ErrorController { @RequestMapping(produces = MediaType.TEXT_HTML_VALUE) public String handleError(HttpServletRequest request) { Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); if (statusCode != null) { return "redirect:/error/" + statusCode; } return "error/error"; } @Override public String getErrorPath() { return "/error"; } @GetMapping("/404") public String notFoundErrorPage() { return "error/404"; } // Other error codes mapping methods }
另外注意:Spring Boot 2.3及以上版本中,ErrorController的getErrorPath()方法已经被标记为Deprecated,不过你的写法在当前场景下依然有效,后续如果需要升级,可以直接依赖@RequestMapping("/error")来指定错误路径。
3. 验证效果
做完上面的配置后,访问一个不存在的路径(比如/non-existent),Spring Boot会自动把请求转发到/error,你的handleError方法会拿到404状态码,然后重定向到/error/404,最终显示你的自定义404页面。
为什么之前的部分场景正常?
你提到的通过Spring Security跳转/error/403、@ControllerAdvice跳转/error/500能正常显示,是因为这些都是主动调用端点,绕过了Spring Boot的自动错误转发逻辑,直接请求了你的控制器方法,所以不受ErrorMvcAutoConfiguration的影响。
内容的提问来源于stack exchange,提问作者Elliot RG

