从Springfox迁移到Springdoc:如何暴露额外模型
在Springdoc中添加未被API直接引用的模型
嗨,我来帮你搞定这个问题!之前你用Springfox的additionalModels方法手动添加未被REST API直接使用的模型,在Springdoc里确实有比创建虚拟操作/参数更优雅的方案,不用再搞那些“假接口”啦。
下面是两种推荐的实现方式,都是直接操作OpenAPI规范的components部分,干净又高效:
方法一:使用OpenApiCustomiser手动添加模型(最接近Springfox的方式)
你可以通过自定义OpenApiCustomiser Bean,借助Springdoc底层的ModelConverters工具类解析模型类,然后将其添加到OpenAPI的schemas组件中。这种方式和Springfox的additionalModels逻辑完全对应,代码示例如下:
import io.swagger.v3.core.converter.ModelConverters; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.media.Schema; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SpringdocAdditionalModelsConfig { @Bean public OpenApiCustomiser additionalModelsCustomiser() { return openApi -> { // 解析需要添加的模型类为Schema对象 Schema<?> xModel1Schema = ModelConverters.getInstance() .readAllAsResolvedSchema(XModel1.class).schema; Schema<?> xModel2Schema = ModelConverters.getInstance() .readAllAsResolvedSchema(XModel2.class).schema; // 将Schema添加到OpenAPI的components/schemas中 Components components = openApi.getComponents(); if (components == null) { components = new Components(); openApi.setComponents(components); } // 这里可以自定义模型的名称,也可以直接用类名 components.addSchemas(XModel1.class.getSimpleName(), xModel1Schema); components.addSchemas(XModel2.class.getSimpleName(), xModel2Schema); }; } }
这个方法的优势在于:
- 完全不需要创建虚拟接口或参数,直接操作OpenAPI规范
ModelConverters会自动识别模型上的所有Swagger注解(比如@Schema、@JsonProperty等),生成的Schema和自动扫描的模型保持一致- 逻辑清晰,和Springfox的使用习惯无缝衔接
方法二:通过@Schema注解间接关联模型(适合特定场景)
如果你的某个已存在的API方法的返回值或参数中,需要间接引用这些模型(比如作为泛型类型、或者在@Schema的implementation属性中指定),也可以用这种方式:
比如在某个已有的Controller方法上:
@GetMapping("/example") @ApiResponse(responseCode = "200", description = "示例响应", content = @Content(schema = @Schema(type = "object", implementation = XModel1.class))) public String getExample() { return "example"; }
不过这种方式本质上还是依赖了已有的API接口,不如第一种方法直接和灵活,更适合那些需要在特定API的响应/请求中关联模型的场景。
总结一下,方法一是最推荐的替代Springfox additionalModels的方案,完全满足你的需求,而且比虚拟操作的方案简洁很多。
内容的提问来源于stack exchange,提问作者aldan95




