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

如何为GroupedOpenApi设置特定前缀调整Springdoc OpenAPI上下文路径

解决方案:为特定GroupedOpenApi移除路径前缀

要实现将GroupedOpenApi的路径前缀(如/v1/legacy-api-1)从OpenAPI定义和Swagger-UI的操作路径中移除,同时保留servers配置,核心是通过自定义OpenApiCustomiser对分组后的路径进行批量替换。

步骤1:实现路径前缀移除的自定义器

创建一个通用的自定义处理器,接收要移除的前缀参数,遍历并修改OpenAPI的路径集合:

import org.springdoc.core.customizers.OpenApiCustomiser;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.PathItem;
import java.util.HashMap;
import java.util.Map;

public class PathPrefixRemoverCustomiser implements OpenApiCustomiser {
    private final String prefixToRemove;

    public PathPrefixRemoverCustomiser(String prefixToRemove) {
        // 统一前缀格式,确保以/开头,避免匹配错误
        this.prefixToRemove = prefixToRemove.startsWith("/") ? prefixToRemove : "/" + prefixToRemove;
    }

    @Override
    public void customise(OpenAPI openApi) {
        Map<String, PathItem> modifiedPaths = new HashMap<>();
        openApi.getPaths().forEach((path, pathItem) -> {
            // 移除指定前缀,保留剩余路径部分
            if (path.startsWith(prefixToRemove)) {
                String newPath = path.substring(prefixToRemove.length());
                // 处理移除前缀后为空的情况,替换为根路径/
                modifiedPaths.put(newPath.isEmpty() ? "/" : newPath, pathItem);
            } else {
                modifiedPaths.put(path, pathItem);
            }
        });
        openApi.setPaths(modifiedPaths);
    }
}

步骤2:配置GroupedOpenApi时引入自定义器

在创建每个GroupedOpenApi的Bean时,将自定义器与servers配置结合,针对不同分组单独处理:

import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.swagger.v3.oas.models.servers.Server;
import java.util.List;

@Configuration
public class OpenApiConfig {

    // 替换为实际的环境变量或配置值
    private static final String API_MANAGER_BASE_URL = "{API_MANAGER_BASE_URL}";
    private static final String OLD_LEGACY_API_1_URL = "{OLD_LEGACY_API_1_URL}";
    private static final String CONSOLIDATED_API_BASE_URL = "{CONSOLIDATED_API_BASE_URL}";

    @Bean
    public GroupedOpenApi legacyApi1Group() {
        String targetPrefix = "/v1/legacy-api-1";
        return GroupedOpenApi.builder()
                .group("legacy-api-1")
                .pathsToMatch(targetPrefix + "/**") // 过滤该分组的路径
                .addOpenApiCustomiser(new PathPrefixRemoverCustomiser(targetPrefix)) // 移除前缀
                .addOpenApiCustomiser(openApi -> {
                    // 保留原有的servers配置
                    List<Server> servers = List.of(
                            new Server().url(API_MANAGER_BASE_URL + "/legacy-api-1"),
                            new Server().url(OLD_LEGACY_API_1_URL),
                            new Server().url(CONSOLIDATED_API_BASE_URL + targetPrefix)
                    );
                    openApi.setServers(servers);
                })
                .build();
    }

    // 同理配置legacy-api-2分组
    @Bean
    public GroupedOpenApi legacyApi2Group() {
        String targetPrefix = "/v1/legacy-api-2";
        return GroupedOpenApi.builder()
                .group("legacy-api-2")
                .pathsToMatch(targetPrefix + "/**")
                .addOpenApiCustomiser(new PathPrefixRemoverCustomiser(targetPrefix))
                .addOpenApiCustomiser(openApi -> {
                    List<Server> servers = List.of(
                            new Server().url(API_MANAGER_BASE_URL + "/legacy-api-2"),
                            new Server().url("{OLD_LEGACY_API_2_URL}"),
                            new Server().url(CONSOLIDATED_API_BASE_URL + targetPrefix)
                    );
                    openApi.setServers(servers);
                })
                .build();
    }

    // v2 API分组可按需选择是否移除前缀
    @Bean
    public GroupedOpenApi v2ApiGroup() {
        String targetPrefix = "/v2";
        return GroupedOpenApi.builder()
                .group("v2-api")
                .pathsToMatch(targetPrefix + "/**")
                // 如果不需要移除v2前缀,注释掉下面一行
                // .addOpenApiCustomiser(new PathPrefixRemoverCustomiser(targetPrefix))
                .addOpenApiCustomiser(openApi -> {
                    List<Server> servers = List.of(
                            new Server().url(CONSOLIDATED_API_BASE_URL + targetPrefix)
                    );
                    openApi.setServers(servers);
                })
                .build();
    }
}

关键说明

  • 分组隔离:自定义器仅作用于当前GroupedOpenApi的路径,不会影响其他分组的API定义
  • 路径兼容性:自动处理前缀格式和空路径场景,符合OpenAPI规范
  • 无侵入性:无需修改原@RestController的@RequestMapping配置,仅通过OpenAPI自定义逻辑调整展示效果
  • 调用正确性:servers配置中的URL已包含完整的前缀/转发地址,Swagger-UI调用时会自动拼接成正确的请求URL(如{API_MANAGER_BASE_URL}/legacy-api-1/document)

内容的提问来源于stack exchange,提问作者Sean Dukehart

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 13:15:29