springdoc-openapi-ui仅生成请求响应Schema的配置方法咨询
如何让springdoc-openapi仅保留请求/响应相关的DTO Schema
springdoc-openapi目前没有提供直接的配置项来自动移除未被请求或响应引用的Schema,但你不需要逐个给DTO加@Hidden注解,有更高效的解决方案:
最佳实践:自定义OpenApiCustomizer过滤未使用的Schema
通过实现OpenApiCustomizer接口,我们可以遍历所有API的请求体、响应体,收集被引用的Schema,然后从OpenAPI规范中移除未被引用的Schema。这种方式无需修改任何DTO类,适合已有项目快速适配。
代码实现示例
import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.parameters.RequestBody; import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; import org.springdoc.core.customizers.OpenApiCustomizer; import org.springframework.stereotype.Component; import java.util.HashSet; import java.util.Set; @Component public class UnusedSchemaFilter implements OpenApiCustomizer { @Override public void customise(OpenAPI openApi) { Set<String> usedSchemaNames = new HashSet<>(); // 遍历所有API操作,收集请求/响应用到的Schema openApi.getPaths().values().forEach(pathItem -> pathItem.readOperations().forEach(operation -> { collectUsedSchemas(operation.getRequestBody(), usedSchemaNames); collectUsedSchemas(operation.getResponses(), usedSchemaNames); }) ); // 移除未被引用的Schema openApi.getComponents().getSchemas().entrySet().removeIf(entry -> !usedSchemaNames.contains(entry.getKey())); } private void collectUsedSchemas(RequestBody requestBody, Set<String> usedSchemaNames) { if (requestBody == null || requestBody.getContent() == null) return; requestBody.getContent().values().forEach(mediaType -> { if (mediaType.getSchema() != null) { addSchemaAndDependencies(mediaType.getSchema(), usedSchemaNames); } }); } private void collectUsedSchemas(ApiResponses apiResponses, Set<String> usedSchemaNames) { if (apiResponses == null) return; apiResponses.values().forEach(apiResponse -> { if (apiResponse.getContent() != null) { apiResponse.getContent().values().forEach(mediaType -> { if (mediaType.getSchema() != null) { addSchemaAndDependencies(mediaType.getSchema(), usedSchemaNames); } }); } }); } private void addSchemaAndDependencies(Schema<?> schema, Set<String> usedSchemaNames) { // 处理引用类型的Schema if (schema.get$ref() != null) { String schemaName = schema.get$ref().substring(schema.get$ref().lastIndexOf('/') + 1); usedSchemaNames.add(schemaName); } // 递归处理嵌套依赖的Schema(包括属性、数组元素) if (schema.getProperties() != null) { schema.getProperties().values().forEach(propertySchema -> addSchemaAndDependencies(propertySchema, usedSchemaNames) ); } if (schema.getItems() != null) { addSchemaAndDependencies(schema.getItems(), usedSchemaNames); } } }
说明
- 这个过滤器会自动收集所有API接口中请求体、响应体直接或间接引用的Schema(包括嵌套DTO)
- 最终生成的
api-docs.json只会保留这些被用到的Schema,完全符合客户端代码生成的需求
替代方案:注解标记(适合小量DTO场景)
如果你的DTO数量不多,也可以给不需要暴露的DTO类添加@Hidden注解,或者使用@Schema(hidden = true),但这种方式需要逐个修改类,扩展性较差。
内容的提问来源于stack exchange,提问作者gunyoung
相关产品推荐
相关产品推荐

