惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
Y
Y Combinator Blog
云风的 BLOG
云风的 BLOG
Microsoft Azure Blog
Microsoft Azure Blog
腾讯CDC
T
The Blog of Author Tim Ferriss
P
Proofpoint News Feed
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
小众软件
小众软件
美团技术团队
Martin Fowler
Martin Fowler
爱范儿
爱范儿
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
宝玉的分享
宝玉的分享
J
Java Code Geeks
B
Blog
V
V2EX
Stack Overflow Blog
Stack Overflow Blog
B
Blog RSS Feed
博客园 - Franky

博客园 - JackYang

I walk alone句子结构中 alone 后置的原因及同类用法解析 《用了3个月Cursor后,我删掉了自己写了10年的工具库》:从“造轮子自豪”到“承认AI写得更好”的心理崩塌与重建 2026年AI Agent时代下如何打造新一代研发体系:从熵增困境到智能工厂的范式重构(基于2025年底文章重写) AgentScope-Java 深度实践:构建企业级生产就绪的智能体应用 传统软件的AI重生:大模型时代下的系统重构与智能升级(2026实践指南)——从代码理解到数据交互,构建安全、高效、可落地的企业级AI集成架构 浅析英文复合名词“X Recording / X Logging”的翻译逻辑与本地化策略——兼论“How + 复合名词 + Works”句式的处理 浅析英文句式“How + 名词 + Works”的翻译逻辑与应用场景 会员契约论新观察:从身份标签到价值博弈——解构与评估现代会员体系 深度剖析akshare-data:OpenClaw生态中的金融数据Skill构建之道——手把手教你用akshare-data搭建个人AI量化系统 DeepSeek-V4:中国大模型的新范式革命—— 万字深度技术全景解析 深入 Java I/O 核心:BufferedInputStream 全景式源码解析与工程实践——2026 高并发时代下的性能基石,从 JDK 源码到虚拟线程(Project Loom)的协同优化 2026年前端工程化的新纪元:从Rust工具链革命到AI Agent原生架构演进 万字详文:解构 SessionBindingService —— AI智能体的“会话粘合剂” Windows 本地部署 Hermes Agent 安装教程 + 飞书接入,会自我进化AI Agent 智能体(全程避坑,亲测有效) 2026年最新、最全、可用的Docker 国内镜像源加速(截至 2026 年 4月14日 亲测可用) Java 中Jar包冲突问题及解决方案 Spring Boot的全局异常处理器如何配置? This application has no explicit mapping for /error “no main manifest attribute, in app.jar” 错误详解与解决方案 深度拆解三大 AI 核心协议:MCP、ACP、A2A,读懂智能代理全域通信底层逻辑—— 从技术原理、架构设计、落地场景到生态未来,全面揭秘 AI 智能体协作的底层标准 The Java® Virtual Machine Specification Java SE 26 Edition 中文版简介第二小节:The Java Virtual Machine The Java® Virtual Machine Specification Java SE 26 Edition 中文版简介第一小节:A Bit of History Java 中 “Error: Could not find or load main class” 错误详解与全面解决方案 云原生时代,Docker和虚拟机谁才是王者?K8s架构下的终极选型指南 2026年全网最新、最全、最好用的Excel快捷键大全:提升工作效率的必备技巧 2026年全网最新、最全的Word快捷键大全:从入门到精通 WPS快捷键大全及使用技巧 2026年最新版IntelliJ IDEA 2026.1下载、安装与配置教程: IDEA 2026.1新手使用教程(万字详解) OpenClaw源码大揭秘:WhatsApp登录工具如何用50行代码破解AI智能体的移动端困局? 2026AI Agent:AI Agent从“工具箱”到“操作系统”——深度解构AI聚合化(Aggregation)、自动化(Automation)与普惠化(Democratization
如何自定义Spring Boot的错误页面显示?
JackYang · 2026-04-13 · via 博客园 - JackYang

在 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。

🔧 配置步骤

  1. 引入模板引擎(可选但推荐)

    <!-- Thymeleaf 示例 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    
  2. 创建错误页面

    • 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(类似)
  3. 通用错误页 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>

⚠️ 生产环境中,messagetrace 默认不会暴露(安全考虑),可通过配置开启:

server.error.include-message=always
server.error.include-stacktrace=on_trace_param

🧪 验证是否生效

  1. 启动应用
  2. 访问一个不存在的 URL(如 /abc)→ 应显示你的 404.html
  3. 在 Controller 中手动抛出异常 → 应显示 500.html

✅ 总结:如何选择?

场景 推荐方案
简单 Web 应用,只需友好提示 方式一/static/error//templates/error/
需要记录日志、发送告警等逻辑 方式三@ControllerAdvice + 返回视图
完全接管错误处理流程 方式四ErrorPageRegistrar + 自定义 Controller
前后端分离 API 项目 不要用错误页面!改用 @RestControllerAdvice 返回 JSON

💡 最佳实践

  • 传统 Web 项目:用 方式一 + 方式三组合
  • REST API 项目:只用 @RestControllerAdvice 返回 JSON,不要配置 HTML 错误页