如何自定义Spring Boot的错误页面显示?
在 Spring Boot 中自定义错误页面,可以根据项目类型(前后端分离 or 传统 Web 应用)和需求灵活选择方式。以下是 最常用、最推荐的几种方法,从简单到高级逐步说明。
✅ 一、最简单方式:静态/模板错误页(推荐用于传统 Web 应用)
Spring Boot 内置了 DefaultErrorViewResolver,它会自动在特定目录下查找错误页面。
📁 目录结构要求
src/main/resources/
├── static/ ← 静态资源(HTML、CSS、JS)
│ └── error/
│ ├── 404.html
│ ├── 500.html
│ └── error.html ← 通用兜底页面
└── templates/ ← 模板引擎(如 Thymeleaf、Freemarker)
└── error/
├── 404.html
├── 500.html
└── error.html
💡 优先级:
- 如果使用了模板引擎(如 Thymeleaf),Spring Boot 会优先从
templates/error/查找;- 否则从
static/error/查找静态 HTML。
🔧 配置步骤
-
引入模板引擎(可选但推荐)
<!-- Thymeleaf 示例 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> -
创建错误页面
src/main/resources/templates/error/404.html<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head><title>404 Not Found</title></head> <body> <h1>抱歉,页面未找到!</h1> <p th:text="${error}"></p> <!-- 可显示错误信息 --> <a href="/">返回首页</a> </body> </html>src/main/resources/templates/error/500.html(类似)
-
通用错误页
error.html- 文件名就叫
error.html,会匹配所有未明确指定的状态码。
- 文件名就叫
✅ 优点:无需写 Java 代码,开箱即用。
❌ 缺点:无法动态处理逻辑(如记录日志、发送告警)。
✅ 二、完全控制:实现 ErrorController(适用于需要深度定制)
⚠️ 注意:从 Spring Boot 2.3 开始,
ErrorController接口已 deprecated,官方推荐使用@ControllerAdvice+ 自定义错误页组合。但若你仍需完全接管/error路径,可继承BasicErrorController。
示例:自定义 ErrorController
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class CustomErrorController implements ErrorController {
@RequestMapping("/error")
public String handleError() {
// 可在此添加日志、监控等逻辑
return "error/custom"; // 返回 templates/error/custom.html
}
}
💡 更现代的做法是 不实现
ErrorController,而是:
- 使用
@ControllerAdvice处理异常- 配合
application.properties触发异常(见下文)
✅ 三、结合全局异常处理器 + 错误页(推荐生产环境)
如果你希望 既能统一处理异常,又能返回友好页面,可组合使用:
步骤 1:启用 404 异常抛出
在 application.properties 中添加:
# 让 404 也抛出异常,从而被 @ControllerAdvice 捕获
spring.mvc.throw-exception-if-no-handler-found=true
spring.web.resources.add-mappings=false
步骤 2:创建全局异常处理器(返回视图)
@ControllerAdvice // 注意:这里用 @ControllerAdvice,不是 @RestControllerAdvice
public class GlobalExceptionViewHandler {
@ExceptionHandler(NoHandlerFoundException.class)
public String handle404() {
return "error/404"; // 跳转到 templates/error/404.html
}
@ExceptionHandler(Exception.class)
public String handleGeneral(Exception e, Model model) {
model.addAttribute("message", "服务器开小差了~");
return "error/500";
}
}
✅ 这样既保留了异常处理能力,又能渲染自定义页面。
✅ 四、通过配置类注册错误页(编程式)
适用于需要动态注册错误页的场景:
@Configuration
public class ErrorPageConfig {
@Bean
public ErrorPageRegistrar errorPageRegistrar() {
return registry -> {
registry.addErrorPages(
new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"),
new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500")
);
};
}
}
然后创建对应的 Controller:
@Controller
public class ErrorPageController {
@GetMapping("/error/404")
public String notFound() {
return "error/404";
}
@GetMapping("/error/500")
public String serverError() {
return "error/500";
}
}
🔍 错误页面中可用的数据(Thymeleaf 示例)
Spring Boot 默认会将以下属性放入 Model,可在页面中使用:
| 属性 | 说明 |
|---|---|
timestamp |
时间戳 |
status |
HTTP 状态码(如 404) |
error |
错误名称(如 "Not Found") |
message |
异常消息(开发环境可见) |
path |
请求路径 |
示例:
<p>状态码: <span th:text="${status}"></span></p>
<p>请求路径: <span th:text="${path}"></span></p>
⚠️ 生产环境中,
message和trace默认不会暴露(安全考虑),可通过配置开启:server.error.include-message=always server.error.include-stacktrace=on_trace_param
🧪 验证是否生效
- 启动应用
- 访问一个不存在的 URL(如
/abc)→ 应显示你的404.html - 在 Controller 中手动抛出异常 → 应显示
500.html
✅ 总结:如何选择?
| 场景 | 推荐方案 |
|---|---|
| 简单 Web 应用,只需友好提示 | 方式一:/static/error/ 或 /templates/error/ |
| 需要记录日志、发送告警等逻辑 | 方式三:@ControllerAdvice + 返回视图 |
| 完全接管错误处理流程 | 方式四:ErrorPageRegistrar + 自定义 Controller |
| 前后端分离 API 项目 | 不要用错误页面!改用 @RestControllerAdvice 返回 JSON |
💡 最佳实践:
- 传统 Web 项目:用 方式一 + 方式三组合
- REST API 项目:只用
@RestControllerAdvice返回 JSON,不要配置 HTML 错误页
浙公网安备 33010602011771号