如何将含多参数的枚举添加到OpenAPI.json并保留参数关联?
我有一个带多参数的枚举类:
public enum MyEnum { VALUE_1("value1_string_1", "value1_string_2"); private final String argument1; private final String argument2; MyEnum (String argument1, String argument2) { this.argument1 = argument1; this.argument2 = argument2; } public String getArgument1() { return argument1; } public String getArgument2() { return argument2; } }
作为REST API的DTO类会使用该枚举的两个参数值为自身字段赋值:field1对应argument1,field2对应argument2:
public class MyDTO { private String field1; private String field2; ... } ... MyDTO myDto = new MyDTO(); myDto.setField1(VALUE_1.getArgument1()) myDto.setField2(VALUE_1.getArgument2())
我需要把包含参数信息的枚举添加到openapi.json中,但尝试用@Schema(..., implementation = MyEnum.class) private String field1;时,生成的文档只包含枚举名称,没有参数信息:
"field1" : { "type" : "string", "enum" : [ "VALUE_1" ] }
核心需求:
- 必须保留
argument1和argument2的关联关系,API使用者需要明确知道value1_string_1和value1_string_2是配对的 - 枚举的参数信息要自动同步到
openapi.json,不能靠手动加描述来维护 - 曾考虑用
@Schema(... ref = "#/components/schemas/MyEnum/properties/argument1" ) private String field1;,但如果枚举本身没出现在文档里,这个引用就无效
当前项目依赖的Swagger版本:
<dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-annotations</artifactId> <version>2.2.7</version> </dependency>
1. 让Swagger识别枚举的完整结构
给MyEnum加上@Schema注解标记类本身,同时给两个私有字段也加上@Schema说明,这样Swagger会把枚举当成一个带属性的组件来处理:
import io.swagger.v3.oas.annotations.media.Schema; @Schema(name = "MyEnum", description = "包含配对参数的自定义枚举") public enum MyEnum { VALUE_1("value1_string_1", "value1_string_2"); @Schema(description = "枚举的第一个参数值") private final String argument1; @Schema(description = "与argument1配对的第二个参数值") private final String argument2; MyEnum (String argument1, String argument2) { this.argument1 = argument1; this.argument2 = argument2; } public String getArgument1() { return argument1; } public String getArgument2() { return argument2; } }
这一步会让MyEnum作为完整的schema出现在openapi.json的components/schemas里,包含两个参数的定义和具体枚举实例的配对值。
2. 在DTO中关联枚举的对应参数
修改MyDTO的字段注解,用ref直接引用枚举的属性,同时加上示例值强化关联关系:
import io.swagger.v3.oas.annotations.media.Schema; public class MyDTO { @Schema(ref = "#/components/schemas/MyEnum/properties/argument1", example = "value1_string_1", description = "对应MyEnum的argument1参数值") private String field1; @Schema(ref = "#/components/schemas/MyEnum/properties/argument2", example = "value1_string_2", description = "对应MyEnum的argument2参数值,与field1配对") private String field2; ... }
3. 确保枚举被Swagger扫描到
如果枚举类不在Swagger默认扫描的包路径下,得在Swagger配置里手动把枚举所在的包加进去(以Spring项目为例):
import org.springdoc.core.GroupedOpenApi; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SwaggerConfig { @Bean public GroupedOpenApi publicApi() { return GroupedOpenApi.builder() .group("public-api") .packagesToScan("com.yourproject.enums", "com.yourproject.dto") // 替换成你的枚举和DTO所在包 .build(); } }
4. 验证最终效果
生成的openapi.json里,components/schemas会有MyEnum的完整定义:
"MyEnum": { "type": "object", "properties": { "argument1": { "type": "string", "description": "枚举的第一个参数值" }, "argument2": { "type": "string", "description": "与argument1配对的第二个参数值" } }, "enum": [ { "argument1": "value1_string_1", "argument2": "value1_string_2" } ] }
同时MyDTO的字段会正确关联到枚举的参数,API使用者能清晰看到value1_string_1和value1_string_2的配对关系,而且枚举更新时文档会自动同步。
备选方案:自定义处理枚举的转换器
如果上面的方法没生效,还可以写个自定义的ModelConverter来强制生成枚举的属性结构:
import io.swagger.v3.core.converter.AnnotatedType; import io.swagger.v3.core.converter.ModelConverter; import io.swagger.v3.core.converter.ModelConverterContext; import io.swagger.v3.oas.models.media.Schema; import java.util.Iterator; public class EnumSchemaConverter implements ModelConverter { @Override public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) { Schema schema = chain.next().resolve(type, context, chain); // 只处理MyEnum类型的枚举 if (type.getType() == MyEnum.class) { schema.setType("object"); schema.addProperty("argument1", new Schema().type("string").description("枚举第一个参数")); schema.addProperty("argument2", new Schema().type("string").description("枚举第二个参数")); // 遍历枚举实例,添加配对值 for (MyEnum enumVal : MyEnum.values()) { schema.addEnumItem(new Object() { public final String argument1 = enumVal.getArgument1(); public final String argument2 = enumVal.getArgument2(); }); } } return schema; } }
然后在配置类里注册这个转换器:
import io.swagger.v3.core.converter.ModelConverters; import jakarta.annotation.PostConstruct; import org.springframework.context.annotation.Configuration; @Configuration public class SwaggerConfig { @PostConstruct public void setupEnumConverter() { ModelConverters.getInstance().addConverter(new EnumSchemaConverter()); } }
内容的提问来源于stack exchange,提问作者stm

