Springdoc编程式添加安全方案后components下Schemas消失问题排查
核心问题根因
该故障的本质是v2分组的自定义OpenAPI配置存在操作逻辑错位,触发了springdoc-openapi的内容覆盖机制,和安全方案本身的配置没有直接关联:
- springdoc默认的文档构建流程,会先完成所有匹配分组路径的Controller接口解析,自动扫描接口参数、返回值对应的模型类,把解析到的所有Schema定义合并进OpenAPI对象的
components.schemas节点,最后再执行用户配置的自定义OpenAPI修改逻辑。 - v2分组的自定义逻辑直接用全新创建的空OpenAPI实例/全新的Components实例替换了springdoc自动生成的基础OpenAPI对象。这类空实例本身不包含任何自动扫描生成的Schema条目,仅保留手动添加的安全方案配置,会直接覆盖原本生成完成的所有Schema内容。
现有配置的具体疏漏
- 分组配置的一致性被破坏:v1分组的自定义逻辑是对springdoc传入的、已完成Schema扫描的OpenAPI对象做增量修改(仅调整版本号),没有替换底层对象,因此所有自动生成的Schema都能正常保留;v2分组的自定义逻辑跳过了“在自动生成的基础上修改”的环节,直接用自定义空实例替换底层对象,直接引发内容丢失。
- 对应springdoc-openapi v1.5.1版本的固有兼容问题:该版本在自定义配置时,如果手动执行
new Components()创建新实例并赋值给OpenAPI对象,会直接清空之前所有自动扫描生成的Schema条目——哪怕没有替换整个OpenAPI对象,只要替换了Components实例,就会出现Schema丢失的问题。 - 绝大多数踩该坑的典型错误写法:
// 错误示例:直接创建全新的OpenAPI实例做自定义配置 GroupedOpenApi.builder() .group("v2") .pathsToMatch("/v2/**") .packagesToScan("com.test.controller") .addOpenApiCustomiser(ignored -> new OpenAPI() .components(new Components() // 全新空Components,会清空所有自动生成的Schema .addSecuritySchemes("Access Token", new SecurityScheme().type(SecurityScheme.Type.APIKEY) .in(SecurityScheme.In.HEADER) .name("Authorization"))) .info(new Info().version("v2"))) .build(); - 正确的配置逻辑需要基于自动生成的OpenAPI对象做增量修改:
GroupedOpenApi.builder() .group("v2") .pathsToMatch("/v2/**") .packagesToScan("com.test.controller") .addOpenApiCustomiser(openApi -> { // 回调传入的openApi已携带所有自动扫描生成的Schema内容 openApi.getInfo().version("v2"); // 在现有Components实例上追加安全方案,不替换原有实例 openApi.getComponents().addSecuritySchemes("Access Token", new SecurityScheme().type(SecurityScheme.Type.APIKEY) .in(SecurityScheme.In.HEADER) .name("Authorization")); // 追加全局安全校验要求 openApi.addSecurityItem(new SecurityRequirement().addList("Access Token")); }) .build();
Swagger UI报错的触发逻辑
v2分组最终生成的OpenAPI文档被替换为仅包含安全配置的空对象,接口定义里引用的/components/schemas/Ping指针在最终文档的对应节点下不存在,Swagger UI执行引用解析时就会抛出Could not resolve reference的错误。
内容的提问来源于stack exchange,提问作者GloWorm
相关产品推荐
相关产品推荐

