Spring Boot:自定义 Whitelabel 错误页面

更新于 2025-12-30

baeldung 2024-05-11

1. 概述

在本教程中,我们将学习如何禁用并自定义 Spring Boot 应用程序的默认错误页面。合理的错误处理体现了专业性和高质量的工作。

2. 禁用 Whitelabel 错误页面

首先,我们可以通过将 server.error.whitelabel.enabled 属性设置为 false 来完全禁用 Whitelabel 错误页面:

server.error.whitelabel.enabled=false

将上述配置添加到 application.properties 文件中后,Whitelabel 错误页面将被禁用,并显示来自底层应用容器(例如 Tomcat)的简洁错误页面。

我们也可以通过排除 ErrorMvcAutoConfiguration 自动配置类来达到相同效果。可以在属性文件中添加以下内容:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration

# 对于 Spring Boot 2.0:
# spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration

或者,在主启动类上添加如下注解:

@EnableAutoConfiguration(exclude = {ErrorMvcAutoConfiguration.class})

以上所有方法都会禁用 Whitelabel 错误页面。那么问题来了:此时到底由谁来处理错误呢?

如前所述,通常是由底层的应用容器来处理。好消息是,我们可以进一步自定义,显示我们自己的错误页面,而不是使用任何默认页面。这正是下一节的重点。

3. 显示自定义错误页面

首先,我们需要创建一个自定义的 HTML 错误页面。

由于我们使用的是 Thymeleaf 模板引擎,因此将该文件保存为 error.html

<!DOCTYPE html>
<html>
<body>
<h1>出错了!</h1>
<h2>我们的工程师正在紧急处理</h2>
<a href="/">返回首页</a>
</body>
</html>

如果我们将此文件保存在 resources/templates 目录下,Spring Boot 默认的 BasicErrorController 将自动识别并使用它。

这样就足以显示我们自定义的错误页面了。稍加样式美化后,用户就能看到一个更加美观友好的错误页面:

Spring Boot 自定义错误页面

我们还可以更具体一些:通过在文件名中包含 HTTP 状态码,让特定状态码使用特定页面。例如,将文件保存为 404.html 并放在 resources/templates/error 目录下,那么该页面将专门用于处理 404 错误。

3.1 自定义 ErrorController

目前的方法有一个限制:无法在发生错误时执行自定义逻辑。要实现这一点,我们需要创建一个替换默认控制器的错误控制器 Bean。

为此,我们需要创建一个实现 ErrorController 接口的类。此外,还需设置 server.error.path 属性,以指定发生错误时调用的自定义路径:

@Controller
public class MyErrorController implements ErrorController {

    @RequestMapping("/error")
    public String handleError() {
        // 可在此处添加日志记录等逻辑
        return "error";
    }
}

在上面的代码片段中,我们为类添加了 @Controller 注解,并为 server.error.path 属性所指定的路径创建了映射:

server.error.path=/error

这样,该控制器就能处理对 /error 路径的请求。

handleError() 方法中,我们返回之前创建的自定义错误页面。现在如果触发 404 错误,就会显示我们自己的页面。

我们还可以进一步增强 handleError() 方法,使其根据不同的错误类型显示不同的错误页面。

例如,我们可以为 404 和 500 错误分别设计精美的页面,然后根据错误的 HTTP 状态码决定显示哪个页面:

@RequestMapping("/error")
public String handleError(HttpServletRequest request) {
    Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
    
    if (status != null) {
        Integer statusCode = Integer.valueOf(status.toString());
    
        if (statusCode == HttpStatus.NOT_FOUND.value()) {
            return "error-404";
        } else if (statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
            return "error-500";
        }
    }
    return "error";
}

这样,当发生 404 错误时,就会显示 error-404.html 页面:

4. 结论

通过以上方法,我们现在可以更优雅地处理错误,并向用户展示美观友好的错误页面。