Spring Boot 3 集成 Swagger 踩坑实录:解决 doc.html 404 与 Unauthorized 拦截
在 Spring Boot 3 项目中集成 API 接口文档(Swagger / SpringDoc / Knife4j)并配合 Spring Security 使用时,开发者往往会遇到两个非常经典的报错。本文将结合实际排查过程,详细剖析这两个问题的成因及解决方案。
坑位一:访问 doc.html 报 404 异常
1. 案发现场
启动项目后,在浏览器中访问:
http://localhost:9999/doc.html
页面显示 404 白板,后台控制台打印如下异常:
text
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource doc.html.
2. 破案分析
这是一个非常典型的"张冠李戴"错误。排查项目的 pom.xml 依赖发现,项目中引入的是 Spring Boot 3 官方标准的 Swagger 方案:SpringDoc OpenAPI:
xml
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.3.0</version>
</dependency>
根据 SpringDoc 官方文档,springdoc-openapi-starter-webmvc-ui 会自动部署 Swagger UI,默认访问地址是:
http://server:port/context-path/swagger-ui.html
而 doc.html 是 Knife4j(国内常用的增强版 Swagger UI)的专属访问路径。Knife4j 官方也明确说明:Spring Boot 3 只支持 OpenAPI3 规范,推荐使用 knife4j-openapi3-jakarta-spring-boot-starter,访问地址正是 doc.html。
既然项目中并没有引入 Knife4j 的依赖,服务器上自然不存在 doc.html 这个静态资源,因此抛出 NoResourceFoundException。
3. 解决方案
方案 A:保持现有依赖,使用正确的官方路径
如果你使用的是 SpringDoc 的 starter,那么访问地址应该是:
http://localhost:9999/swagger-ui/index.html
或者通过配置自定义路径:
yaml
springdoc:
swagger-ui:
path: /swagger-ui.html
配置后访问 /swagger-ui.html 即可。
方案 B:替换依赖,坚持使用 Knife4j
如果你更喜欢 Knife4j 的左侧菜单栏排版,需要修改 pom.xml:
- 删除或注释掉原有的
springdoc-openapi-starter-webmvc-ui依赖; - 引入专为 Spring Boot 3 设计的 Knife4j 依赖(注意必须带
jakarta标识):
xml
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
Knife4j 的 starter 已经内置了对 springdoc-openapi 的依赖,无需再额外引入 springdoc。刷新 Maven 并重启项目后,即可正常访问:
http://localhost:9999/doc.html
坑位二:访问正确地址却返回 Unauthorized
1. 案发现场
在采用"方案 A",使用正确的地址:
http://localhost:9999/swagger-ui/index.html
访问时,页面没有渲染文档,而是直接返回一段 JSON:
json
{"success":false,"errorMsg":"Unauthorized"}
此时后台控制台没有任何报错信息。
2. 破案分析
看到熟悉的 JSON 格式,原因立刻水落石出:请求在到达 Controller 之前,被底层的安全框架拦截了。
查看依赖树可知,项目中引入了 Spring Security 及自定义的安全校验模块。在默认的安全配置下,Spring Security 会拦截所有外部请求,要求携带合法 Token(如 JWT)才能访问。浏览器直接访问文档地址时并没有携带 Token,因此触发鉴权失败,返回自定义的未授权提示。
3. 解决方案:配置 Spring Security 白名单
要解决这个问题,需要为 Swagger 相关的静态资源和接口发放"特别通行证"。
进入项目中的 Spring Security 配置类(通常带有 @Configuration 和 @EnableWebSecurity 注解),在 SecurityFilterChain 的配置中,使用 requestMatchers 将 Swagger 相关的路径设为 permitAll() 放行状态。
针对 Spring Boot 3.x(Spring Security 6.x)的配置参考如下:
java
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// 省略 csrf、cors 等其他常规配置...
.authorizeHttpRequests(auth -> auth
// 【核心修复】:将 Swagger/OpenAPI 的相关路径全部加入白名单
.requestMatchers(
"/swagger-ui/**", // 放行 UI 静态页面资源
"/swagger-ui.html", // 放行 UI 访问入口
"/v3/api-docs/**", // 放行 OpenAPI 的核心数据接口(非常重要,否则页面为空)
"/swagger-resources/**", // 放行资源配置
"/webjars/**", // 放行前端依赖的 webjars
"/doc.html" // 兼容放行 knife4j 路径
).permitAll()
// 业务接口放行配置示例
.requestMatchers("/api/user/login", "/api/user/register").permitAll()
// 其余所有请求均需要认证
.anyRequest().authenticated()
);
// 省略自定义的 JWT Filter 等配置...
return http.build();
}
多模块架构注意事项:
如果你的安全配置类写在独立的通用模块(如 common-security)中,修改代码后需要先对该模块执行:
mvn install
然后再重新启动主工程,配置才能真正生效。
重启项目后,再次访问文档地址,完整的接口文档页面即可顺利加载。
小结
- 404 问题 :
doc.html是 Knife4j 的专属入口,而 SpringDoc 的默认入口是/swagger-ui.html或/swagger-ui/index.html。根据你引入的依赖选择正确的访问路径,或统一切换为 Knife4j 的 starter。 - Unauthorized 问题 :
在 Spring Security 6 中,需要通过SecurityFilterChain的authorizeHttpRequests将/swagger-ui/**、/v3/api-docs/**等路径加入白名单,否则文档页面会被安全框架拦截。
把这两点排查清楚,Spring Boot 3 下集成 Swagger 基本就能一马平川了。