代码优先生成Open API规范:多态Map值的Schema注解配置求助
问题描述
采用**代码优先(Code first)**方式,通过以下依赖生成OpenAPI规范:
<dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-annotations</artifactId> <version>2.2.15</version> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId> <version>1.7.0</version> </dependency>
JSON请求示例:
{ "replacementVariables": { "salutation": "Ms", "firstName": "Jeff", "day": ["1", "2", "3" ], "points": ["24", "29", "13" ] } }
其中replacementVariables的键不固定,值支持string或array<string>类型,后端已适配该场景。
反序列化使用的Java对象:
private Map<String, Object> replacementVariables;
依赖Jackson库完成反序列化:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.10.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.10.2</version> </dependency>
反序列化正常,但需要生成如下格式的OpenAPI规范:
... requestBody: content: application/json: schema: $ref: '#/components/schemas/Request' ... components: schemas: Request: properties: replacementVariables: $ref: '#/components/schemas/ReplacementVariables' ReplacementVariables: type: object additionalProperties: anyOf: - string - $ref: '#/components/schemas/ReplacementVariablesList' ReplacementVariablesList: type: array items: type: string
尝试过@Schema结合anyOf、additionalProperties、additionalPropertiesSchema,以及@JsonTypeInfo和@JsonSubTypes,均无法生成符合要求的规范,需要指导编写正确的注解。
解决方案
要生成目标OpenAPI规范,需通过自定义Schema类结合Swagger注解实现,直接在Map<String, Object>上注解无法满足需求,具体步骤如下:
1. 定义ReplacementVariablesList类
该类对应OpenAPI中的数组类型,仅用于生成Schema结构,无需业务字段:
import io.swagger.v3.oas.annotations.media.Schema; @Schema(type = "array", items = @Schema(type = "string")) public class ReplacementVariablesList { // 无业务字段,仅用于OpenAPI Schema生成 }
2. 定义ReplacementVariables类
该类对应动态键的对象,通过@Schema指定additionalProperties的值类型为anyOf:
import io.swagger.v3.oas.annotations.media.Schema; @Schema(type = "object", additionalProperties = @Schema( anyOf = { @Schema(type = "string"), @Schema(ref = "#/components/schemas/ReplacementVariablesList") } )) public class ReplacementVariables { // 无业务字段,仅用于OpenAPI Schema生成 }
3. 修改Request类的字段注解
将原Map<String, Object>字段通过@Schema引用自定义的ReplacementVariables Schema:
import io.swagger.v3.oas.annotations.media.Schema; public class Request { @Schema(ref = "#/components/schemas/ReplacementVariables") private Map<String, Object> replacementVariables; // 标准getter/setter方法 public Map<String, Object> getReplacementVariables() { return replacementVariables; } public void setReplacementVariables(Map<String, Object> replacementVariables) { this.replacementVariables = replacementVariables; } }
4. 验证生成结果
启动Spring应用后,访问默认OpenAPI文档地址/v3/api-docs,即可看到与目标结构一致的Schema:
Request的replacementVariables字段引用ReplacementVariables组件ReplacementVariables为object类型,additionalProperties的值包含string和ReplacementVariablesList两种类型ReplacementVariablesList为array<string>类型
关键说明
- 自定义空类仅用于Swagger识别并生成Schema组件,Jackson反序列化不受影响,依然可以正常处理
Map<String, Object>类型的字段 - 通过
@Schema(ref = ...)关联各个组件,确保生成的OpenAPI规范结构完全匹配需求
内容的提问来源于stack exchange,提问作者Swapnil Kharabe
相关产品推荐
相关产品推荐

