如何实现支持空值的枚举?SpringDoc-OpenAPI文档生成问题
解决Springdoc-OpenAPI中可空枚举的API文档生成问题
问题场景
使用springdoc-openapi 1.6.11生成API文档时,遇到一个问题:请求体中带有@Nullable注解的枚举字段,生成的Swagger YAML仅标记了nullable: true,但枚举值列表里没有包含null。这导致API允许省略该字段,但发送color=null时会被判定为无效请求。
你的代码示例:
@PostMapping(path = "/count-colors") public Integer countColors(@Parameter(description = "Request object", required = true) @RequestBody Request request) { return 1; } class Request { @Nullable @Schema(nullable = true, example = "RED") private Color color; } enum Color { RED, GREEN, YELLOW }
生成的YAML片段:
components: schemas: Request: type: object properties: color: type: string nullable: true example: RED enum: - RED - GREEN - YELLOW # 缺少null选项
可行解决方案
方案1:通过OpenAPI自定义器手动添加null枚举值
编写一个Spring配置类,在OpenAPI生成后遍历所有Schema,给标记为nullable的枚举字段添加null值:
import org.springdoc.core.customizers.OpenApiCustomiser; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.media.Schema; import java.util.List; @Configuration public class SpringDocConfig { @Bean public OpenApiCustomiser nullableEnumCustomiser() { return openApi -> { // 遍历所有组件Schema openApi.getComponents().getSchemas().values().forEach(schema -> { if (schema.getProperties() != null) { // 遍历Schema的所有属性 schema.getProperties().values().forEach(propertySchema -> { // 检查属性是否是可空枚举 if (Boolean.TRUE.equals(propertySchema.getNullable()) && propertySchema.getEnum() != null) { List<Object> enumValues = propertySchema.getEnum(); // 避免重复添加null if (!enumValues.contains(null)) { enumValues.add(null); } } }); } }); }; } }
方案2:自定义ModelConverter处理枚举
通过实现ModelConverter接口,在Schema解析阶段就给可空枚举添加null值:
import io.swagger.v3.core.converter.ModelConverter; import io.swagger.v3.core.converter.ModelConverterContext; import io.swagger.v3.core.converter.ModelConverterImpl; import io.swagger.v3.oas.models.media.Schema; import org.springframework.stereotype.Component; import java.lang.reflect.Type; import java.util.Iterator; import java.util.List; @Component public class NullableEnumModelConverter extends ModelConverterImpl { @Override public Schema resolve(Type type, ModelConverterContext context, Iterator<ModelConverter> chain) { Schema schema = super.resolve(type, context, chain); if (schema != null && schema.getEnum() != null) { // 给可空的枚举字段添加null值 if (Boolean.TRUE.equals(schema.getNullable())) { List<Object> enumValues = schema.getEnum(); if (!enumValues.contains(null)) { enumValues.add(null); } } } return schema; } }
方案3:升级springdoc-openapi版本
该问题和swagger-core的相关兼容性问题有关,后续版本的springdoc-openapi(比如2.x系列)已经修复了这个问题,升级版本后,@Nullable注解会被正确识别,自动将null加入枚举可选值列表。
验证效果
应用上述方案后,生成的YAML会包含null作为枚举选项:
components: schemas: Request: type: object properties: color: type: string nullable: true example: RED enum: - RED - GREEN - YELLOW - null
此时发送color=null的请求会被API判定为有效。
内容的提问来源于stack exchange,提问作者phyratokar
相关产品推荐
相关产品推荐

