如何在 Spring Boot 中统一处理 404 异常并返回 JSON 响应
技术百科
花韻仙語
发布时间:2026-01-01
浏览: 次 通过配置 `spring.mvc.throw-exception-if-no-handler-found=true` 并调整静态资源路径,可使未匹配的请求触发 `@exceptionhandler`,从而实现 404 异常的全局 json 格式化响应。
在 Spring Boot 中,@ControllerAdvice(或其 REST 专用变体 @RestControllerAdvice)配合 @ExceptionHandler 是处理控制器层异常的标准方式。但默认情况下,404(Not Found)错误并不会进入 @ExceptionHandler 流程——因为该异常发生在 DispatcherServlet 的请求分发阶段(即“找不到任何 HandlerMapping 匹配该 URL”),而非控制器执行过程中抛出的异常。此时 Spring Boot 会直接返回 Whitelabel 错误页(HTML),而非调用你的全局异常处理器。
要让 404 也能被 @ExceptionHandler 捕获,关键在于 强制 Spring 在无处理器匹配时抛出 NoHandlerFoundException,而非静默返回 404 响应。这需要两个协同配置:
✅ 步骤一:启用异常抛出机制
在 application.yml(或 application.properties)中启用:
spring:
mvc:
throw-exception-if-no-handler-found: true⚠️ 注意:仅设置此项不够!Spring Boot 默认将静态资源路径设为 /**,而 Whitelabel 错误页本质上是静态资源(由 BasicErrorController 提供)。若不调整静态路径,throw-exception-if-no-handler-found 将被忽略(因为 /error 路径仍能被静态资源处理器匹配)。
✅ 步骤二:隔离静态资源路径
方案 A(推荐):显式限定静态资源路径,避免覆盖 /error:
spring:
mvc:
throw-exception-if-no-handler-found: true
static-path-pattern: /static/**这样,所有非 /static/** 开头的请求(如 /api/v1/itemss)若无对应 Controller,则触发 NoHandlerFoundException。
方案 B:禁用自动配置,手动接管 Web MVC(适用于需深度定制场景):
@Configuration @EnableWebMvc // ⚠️ 关闭 Spring Boot 的 WebMvcAutoConfiguration public class WebConfig implements WebMvcConfigurer { // 可选:自定义资源处理器等 }
再配合 spring.mvc.throw-exception-if-no-handler-found=true 即可生效。
✅ 步骤三:添加 404 异常处理器
在你的 @RestControllerAdvice 类中添加:
@ExceptionHandler(NoHandlerFoundException::class)
fun handleNoHandlerFound(
exception: NoHandlerFoundException,
request: HttpServletRequest
): ResponseEntity {
logger().warn("404 Not Found: {}", exception.requestURL)
val notFound = HttpStatus.NOT_FOUND
val apiError = ApiError(
requestURI = exception.requestURL,
status = notFound.value(),
statusText = notFound.reasonPhrase,
createdAt = OffsetDateTime.now(),
errorMessage = "Requested resource does not exist"
)
return ResponseEntity(apiError, notFound)
}? 提示:NoHandlerFoundException 的 requestURL 字段需通过 exception.requestURL 获取(Kotlin 中注意空安全),或从 request.requestURL.toString() 提取。
✅ 最终效果
访问 GET /api/v1/itemss 将返回标准 JSON:
{
"requestUri": "/api/v1/itemss",
"status": 404,
"statusText": "Not Found",
"createdAt": "2025-01-12T16:52:06.932108+02:00",
"errorMessage": "Requested resource does not exist"
}⚠️ 注意事项
- 确保 NoHandlerFoundException 的包导入正确:org.springframework.web.servlet.NoHandlerFoundException;
- 若使用 Spring Security,请确认 /error 路径未被拦截(通常需放行);
- @EnableWebMvc 会完全关闭 Spring Boot 的 Web 自动配置,仅在必要时选用;
- 生产环境建议结合 ErrorAttributes 或 ErrorController 做更健壮的错误溯源。
通过以上三步配置,即可将 404 纳入统一的 JSON 异常处理体系,保持 API 响应风格一致,提升客户端集成体验与服务可观测性。
# 可选
# 找不到
# 也能
# 要让
# 适用于
# 自定义
# 而非
# app
# 将被
# 设为
# js
# json
# Error
# if
# html
# Static
# asic
# throw
# 抛出
# 处理器
# spring
# mvc
# kotlin
# spring boot
# servlet
# spring security
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- 如何在Golang中写入XML文件_生成符合规范的
- c# Task.ConfigureAwait(tr
- 如何使用Golang优化模块引入路径_Golang
- Win10怎样卸载自带Edge_Win10卸载Ed
- 如何在网页无标准表格标签时高效提取结构化数据
- 微信短链接怎么还原php_用浏览器开发者工具抓包获
- C++如何使用std::transform批量处理
- php怎么操作Redis_Redis扩展连接与基本
- Python实现图数据库操作_Neo4j核心CRU
- Win10如何卸载微软拼音输入法 Win10只保留
- Win11怎么连接蓝牙耳机_Win11蓝牙设备配对
- 如何使用Golang搭建本地API测试环境_快速验
- Win10系统映像怎么恢复 Win10使用系统映像
- Linux怎么实现内网穿透_Linux安装Frp客
- Windows10蓝屏SYSTEM_SERVICE
- Win11怎么关闭键盘按键音_Win11禁用打字声
- 如何使用Golang实现云原生应用弹性伸缩_自动应
- Windows如何拦截2345弹窗广告_Windo
- php8.4匿名类怎么用_php8.4匿名类创建与
- Win11怎么开启游戏工具栏_Windows11
- Mac如何开启夜览模式_Mac护眼模式设置与定时
- Windows怎样关闭锁屏广告_Windows关闭
- Win11开始菜单打不开_修复Windows 11
- Windows10系统怎么查看CPU温度_Win1
- PythonFastAPI项目实战教程_API接口
- 如何在Golang中实现RPC异步返回_Golan
- Win10如何更改用户账户控制_Windows10
- Go语言中slice追加操作的底层共享机制解析
- php高频调试功能有哪些_php常用调试函数与工具
- Drupal 中渲染节点时出现 HTML 标签嵌套
- Linux如何使用grep搜索文件内容_Linux
- Python异步编程高级项目教程_asyncio协
- 作用域操作符会影响性能吗_php静态调用性能分析【
- c++怎么处理多线程死锁_c++ lock_gua
- php下载安装选zip还是msi格式_两种安装包对
- Python性能剖析高级教程_cProfileLi
- 如何在包含多值的列中精准搜索指定演员?
- c++如何判断文件是否存在_c++ filesys
- Python对象比较排序规则_集合使用说明【指导】
- Win11截图快捷键是什么_Win11自带截图工具
- Windows10电脑怎么连接蓝牙设备_Win10
- 如何使用Golang反射创建map对象_动态生成键
- php8.4xdebug无法调试怎么办_php8.
- Win11怎么退出高对比度模式_Win11取消反色
- Win11视频默认播放器怎么改_Win11关联第三
- Windows蓝屏错误0x0000001E怎么修复
- 如何在Golang中验证模块完整性_Golangg
- Python函数接口文档化_自动化说明【指导】
- 如何使用Golang模拟请求超时_Golang c
- Windows10如何更改桌面图标间距_Win10

t 的 WebMvcAutoConfiguration
public class WebConfig implements WebMvcConfigurer {
// 可选:自定义资源处理器等
}
QQ客服