You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot中OpenAPI在Swagger文档生成重复API问题

环境信息
  • Java: 21
  • SpringBoot: 3.2.1

OpenApi依赖

<dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
      <version>2.1.0</version>
    </dependency>

OpenAPI YAML 文件内容

openapi: 3.0.3
info:
  title: 示例接口集
  description: |-
    一组简单的示例API集合
  version: 1.0-SNAPSHOT
servers:
  - url: http://127.0.1:8091/api/v1
    description: 本地服务器(使用测试数据)
  - url: https://example-dev.com/api/v1
    description: UAT服务器(使用测试数据)
  - url: https://example.com/api/v1
    description: 生产服务器(使用真实数据)
tags:
  - name: 示例
    description: 示例接口
paths:
  /examples:
    get:
      summary: 获取示例数据
      description: 获取示例数据
      operationId: getExample
      responses:
        200:
          description: 请求成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Example'
        404:
          description: 未找到目标数据
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExampleNotFoundError'
  
components:
  schemas:
    Example:
      type: object
      properties:
        creatorId:
          type: string
          description: 创建者ID
        hipiCoins:
          type: number
          description: 虚拟货币数量
    ExampleNotFoundError:
      type: object
      properties:
        creatorId:
          type: string
          description: 创建者ID
        hipiCoins:
          type: number
          description: 虚拟货币数量

Controller 代码

@Generated(
    value = "org.openapitools.codegen.languages.SpringCodegen",
    date = "2024-01-15T23:26:32.308871+05:30[Asia/Kolkata]")
@Controller
public class ExampleController implements ExampleApi {

  private final ExampleApiDelegate delegate;

  public ExampleController(
      @org.springframework.beans.factory.annotation.Autowired(required = false)
          ExampleApiDelegate delegate) {
    this.delegate = Optional.ofNullable(delegate).orElse(new ExampleApiDelegate() {});
  }

  @Override
  public ExampleApiDelegate getDelegate() {
    return delegate;
  }
}

Application.properties 配置

spring.application.name=example-service
server.port=8091
springdoc.enable-native-support=true
springdoc.swagger-ui.path=/swagger-ui
logging.level.root=INFO
问题描述

Swagger文档中同时展示了两个重复的API接口:GET /api/v1/examples 和 GET /examples,需求是仅保留带前缀的GET /api/v1/examples接口,但尝试过Stack Overflow上的相关解决方案后仍未解决该问题。

解决方案

出现重复接口的核心原因是:OpenAPI YAML定义的基础路径为/examples,同时Spring Boot自动扫描生成了不带前缀的接口,再加上servers配置中的/api/v1前缀,导致两种路径都被渲染到Swagger文档中。以下是几种可行的解决方式:

方式一:配置Spring Boot上下文路径

在application.properties中添加上下文路径配置,让所有接口自动带上/api/v1前缀:

server.servlet.context-path=/api/v1

此配置会让Spring Boot的所有接口统一使用该前缀,OpenAPI文档会自动匹配该路径,不再展示不带前缀的/examples接口。

方式二:指定springdoc的接口文档路径前缀

如果不想修改全局上下文路径,可以单独配置springdoc的接口文档路径:

springdoc.api-docs.path=/api/v1/v3/api-docs
springdoc.swagger-ui.url=/api/v1/v3/api-docs

确保该前缀与OpenAPI YAML中servers配置的路径一致,Swagger UI就只会加载带前缀的接口文档。

方式三:调整OpenAPI Generator生成参数

如果接口代码是通过OpenAPI Generator生成的,在生成时可以指定api-prefix参数,让生成的接口自动带上/api/v1前缀:

--api-prefix /api/v1

这样生成的ExampleApi接口会直接包含前缀,不会出现不带前缀的路径定义。

方式四:自定义过滤规则移除无效路径

如果以上方法都不生效,可以通过自定义OpenApiCustomiser过滤掉不带前缀的路径:

import org.springdoc.core.customizers.OpenApiCustomiser;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class OpenApiConfig {
    @Bean
    public OpenApiCustomiser removeNonPrefixedPaths() {
        return openApi -> {
            openApi.getPaths().keySet().removeIf(path -> !path.startsWith("/api/v1"));
        };
    }
}

该配置会移除所有不以/api/v1开头的路径,确保Swagger文档中只保留符合要求的接口。


内容的提问来源于stack exchange,提问作者Prafulla Kumar Sahu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 04:15:43