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 白板,后台控制台打印如下异常:

org.springframework.web.servlet.resource.NoResourceFoundException: No static resource doc.html.

2. 破案分析

这是一个非常典型的“张冠李戴”错误。排查项目的 pom.xml 依赖发现,项目中引入的是 Spring Boot 3 官方标准的 Swagger 方案:SpringDoc OpenAPI:

<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
或者通过配置自定义路径:

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 标识):
<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:

{"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)的配置参考如下:

@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 基本就能一马平川了。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐