Spring Boot 3 集成 Swagger 踩坑实录:解决 doc.html 404 与 Unauthorized 拦截

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

  1. 删除或注释掉原有的 springdoc-openapi-starter-webmvc-ui 依赖;
  2. 引入专为 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

然后再重新启动主工程,配置才能真正生效。

重启项目后,再次访问文档地址,完整的接口文档页面即可顺利加载。

小结

  1. 404 问题
    doc.html 是 Knife4j 的专属入口,而 SpringDoc 的默认入口是 /swagger-ui.html/swagger-ui/index.html。根据你引入的依赖选择正确的访问路径,或统一切换为 Knife4j 的 starter。
  2. Unauthorized 问题
    在 Spring Security 6 中,需要通过 SecurityFilterChainauthorizeHttpRequests/swagger-ui/**/v3/api-docs/** 等路径加入白名单,否则文档页面会被安全框架拦截。
    把这两点排查清楚,Spring Boot 3 下集成 Swagger 基本就能一马平川了。
相关推荐
十七号程序猿2 小时前
Java图书管理系统 | 无需配置任何环境,双击一键启动,开箱即用
java·spring boot·vue·毕业设计·毕设·源代码管理
ZHOUPUYU2 小时前
PHP与WebSocket实时通信的原理到生产级应用
开发语言·html·php
小码哥_常2 小时前
当@RequestBody遇上Request:数据去哪儿了?
后端
umeelove352 小时前
Spring boot整合quartz方法
java·前端·spring boot
uimaker2 小时前
uimaker响应式jQuery Easyui+Bootstrap多配色主题设计
前端框架·bootstrap·html·jquery·easyui·后台模版
yige452 小时前
SpringBoot 集成 Activiti 7 工作流引擎
java·spring boot·后端
dreamxian3 小时前
苍穹外卖day10
java·开发语言·spring boot
G探险者3 小时前
SQL 性能优化实战:一次压测 404 的根因追查与解决
后端
人间打气筒(Ada)3 小时前
如何使用 Go 更好地开发并发程序?
开发语言·后端·golang