排查了一整天,最后只加了一个注解。问 AI 查文章,得到的答案不是劝你升级降级版本,就是让你改一堆配置文件,绕了一大圈,其实一个注解就能解决。
背景
有时候项目迭代升级后,文档页面突然白屏,控制台还冒出 NoSuchMethodError 之类的报错。很多人第一反应是“版本不兼容”,于是想着升级 springdoc、降级 Spring Boot……可生产环境里版本往往是定死的,动一发牵全身,根本不敢随便改。
我前两天也踩了这个坑,折腾很久发现:根本不用动版本,只要给全局异常处理器加一个 @Hidden 注解,问题就解决了。
一、环境信息
| Spring Boot | 3.5.x(Spring Framework 6.2.x,Java 17) |
| Knife4j | knife4j-openapi3-jakarta-spring-boot-starter 4.1.0(内置 springdoc 1.7.0) |
| 注解体系 | OpenAPI 3(io.swagger.v3.oas.annotations) |
二、问题现象
2.1 页面表现
访问 doc.html,页面白屏/报错,右上角提示 “Knife4j 文档请求异常”,接口列表加载不出来,效果如下:

2.2 前端控制台(F12)报错
打开浏览器 F12 看 Network 与 Console,能看到这样一串报错:
v3/api-docs:1 Failed to load resource: the server responded with a status of 500 ()
app.30e79dc0.js:1 Error: Request failed with status code 500
at e.exports (chunk-vendors.d59642c5.js:2:679693)
at e.exports (chunk-vendors.d59642c5.js:2:1298909)
at XMLHttpRequest.y (chunk-vendors.d59642c5.js:2:1868675)
关键信息就两条:
- /v3/api-docs 返回 500:文档页加载的核心数据请求失败了;
- app.30e79dc0.js 报 Request failed with status code 500:前端拿不到合法数据,自然渲染不出文档页;
2.3 后端控制台报错
真正的原因在后端,控制台报错如下:
jakarta.servlet.ServletException: Handler dispatch failed:
java.lang.NoSuchMethodError:
'void org.springframework.web.method.ControllerAdviceBean.<init>(java.lang.Object)'
Caused by: java.lang.NoSuchMethodError:
'void org.springframework.web.method.ControllerAdviceBean.<init>(java.lang.Object)'
at org.springdoc.core.service.GenericResponseService…
三、关键复现:一个注解让文档恢复
项目里有这样一个全局异常处理器:
@RestControllerAdvice
public class GlobalExceptionAdvice {
@ExceptionHandler
public ResponseEntity<?> handleWoNiuHealthException(WoNiuHealthException e) {
e.printStackTrace();
return ResponseEntity.status(500)
.body(Map.of("code", 500, "message", e.getMessage()));
}
@ExceptionHandler
public ResponseEntity<?> handleException(Exception e) {
e.printStackTrace();
return ResponseEntity.status(500)
.body(Map.of("code", 500, "message", e.getMessage()));
}
}
实测:
| 去掉 @Hidden | doc.html 白屏,/v3/api-docs 报 NoSuchMethodError |
| 加上 @Hidden | 文档恢复正常 |
四、根因说明(为什么不是版本不兼容?)
很多人在看到 NoSuchMethodError 时会下意识认为是 springdoc 版本太老,不兼容 Spring Framework 6.2.x,于是急着去升级依赖。但这次的问题其实不是版本兼容性问题,而是 Springdoc 内部扫描机制触发了对 ControllerAdviceBean 构造方法的调用,而这个调用在特定条件下才会出问题。
关键点在于:
Springdoc 在生成 OpenAPI 规范时,会扫描所有标注了 @RestControllerAdvice 的类,并尝试将它们包装成 ControllerAdviceBean 进行处理。
在 Spring Framework 6.2.x 中,ControllerAdviceBean 的构造方法签名发生了变化,而 springdoc 1.7.0 在某些场景下(比如遇到 ResponseEntity<?> 这种需要复杂类型解析的情况)会调用旧版本的构造方法,从而抛出 NoSuchMethodError。
这个报错是 Error 而不是 Exception,所以 @ExceptionHandler(Exception e) 根本接不住它,只能眼睁睁看着它往上抛。
结论:问题不在于“版本不兼容”,而在于 Springdoc 在扫描全局异常处理器时,触发了不兼容的方法调用。只要让 Springdoc 跳过对全局异常处理器的扫描,就能完美规避这个问题,而不需要动任何版本。
五、我的解决方法(什么都不用改,只加一个注解)
import io.swagger.v3.oas.annotations.Hidden;
@RestControllerAdvice
@Hidden // 让 Springdoc 忽略该类
public class GlobalExceptionAdvice {
// … 异常处理方法
}
就这一个注解。
原理很简单:@Hidden 通知 Springdoc 完全忽略这个类,不再扫描它、不做 Advice 包装、不解析返回类型,那串触发 NoSuchMethodError 的代码直接不执行,/v3/api-docs 正常生成,doc.html 立刻恢复。
六、为什么我推荐它,而不是升级/降级版本?
| 升级/降级 Spring Boot 或 springdoc | 高(需回归测试、协调团队) | 高(可能引入新问题) |
| 加 @Hidden 注解 | 极低(一行代码) | 极低(只影响文档扫描) |
可以说,这是当前成本和风险都最低的解法,也是我最想分享给同样踩坑的朋友的做法。


