You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenAPI YAML枚举继承实现问题:SpringBoot API序列化报错

OpenAPI生成SpringBoot REST API的StudentType层级实现与序列化问题解决

问题背景

基于OpenAPI YAML定义开发SpringBoot REST API时,生成的StudentType.java是接口,导致StudentDto无法正常序列化,调用API时抛出Jackson反序列化错误,同时需要在Swagger UI中让StudentType1和StudentType2显示为StudentType的子类型。

现有OpenAPI定义

主API YAML文件

/controller/myApi:
post:
  tags:
    - ... 
  operationId: postNewStudent            
    
  requestBody:
    content:
      application/json:
        schema:              
          $ref: '#/components/schemas/StudentDto'          

components:
  schemas:
    StudentDto:
      type: object
      properties:
        prop1:
          type: string          
        prop2:                   
        studentType:
          $ref: 'common/studentSchema.yaml#/components/schemas/studentType'

common/studentSchema.yaml文件

components:
  schemas:
    studentType:
      type: string
      description: |
        ....           
      oneOf: 
        - $ref: '#/components/schemas/studentType1'                    
        - $ref: '#/components/schemas/studentType2'

    studentType1:
      type: string
      description: ...
      enum: 
       - ENUM_VAL1_1
       - ENUM_VAL1_2
    
    studentType2:
      type: string
      description: ...
      enum:
       - ENUM_VAL2_1
       - ENUM_VAL2_2

错误信息

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `...StudentDto` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer

解决方案

1. 修改OpenAPI定义,用鉴别器实现多态层级

调整studentSchema.yaml中的studentType定义,通过discriminator指定多态鉴别字段,将结构改为对象类型(string类型无法承载鉴别字段),让子类型继承父类型:

components:
  schemas:
    studentType:
      type: object
      description: 学生类型父类
      discriminator:
        propertyName: type
        mapping:
          TYPE1: '#/components/schemas/studentType1'
          TYPE2: '#/components/schemas/studentType2'
      required:
        - type
      properties:
        type:
          type: string
          description: 类型标识,用于区分不同子类型
      oneOf:
        - $ref: '#/components/schemas/studentType1'
        - $ref: '#/components/schemas/studentType2'

    studentType1:
      allOf:
        - $ref: '#/components/schemas/studentType'
        - type: object
          properties:
            value:
              type: string
              description: studentType1枚举值
              enum: 
               - ENUM_VAL1_1
               - ENUM_VAL1_2
          required:
            - value
    
    studentType2:
      allOf:
        - $ref: '#/components/schemas/studentType'
        - type: object
          properties:
            value:
              type: string
              description: studentType2枚举值
              enum:
               - ENUM_VAL2_1
               - ENUM_VAL2_2
          required:
            - value

修改后,OpenAPI Generator会生成抽象父类StudentType,以及继承它的StudentType1和StudentType2子类,Jackson可通过type字段自动识别并反序列化对应子类。

2. 配置OpenAPI Generator生成抽象类而非接口

若希望保留原有string enum结构,可通过生成器配置让oneOf生成抽象类而非接口:

  • Maven配置:在pom.xml的openapi-generator-maven-plugin中添加参数:
<plugin>
  <groupId>org.openapitools</groupId>
  <artifactId>openapi-generator-maven-plugin</artifactId>
  <version>最新版本</version>
  <executions>
    <execution>
      <goals>
        <goal>generate</goal>
      </goals>
      <configuration>
        <!-- 其他配置 -->
        <configOptions>
          <abstractClassForOneOf>true</abstractClassForOneOf>
          <interfaceOnly>false</interfaceOnly>
        </configOptions>
      </configuration>
    </execution>
  </executions>
</plugin>
  • Gradle配置:在build.gradle中添加:
openapiGenerate {
  // 其他配置
  configOptions = [
    abstractClassForOneOf: "true",
    interfaceOnly: "false"
  ]
}

同时在application.yml中配置Jackson支持多态反序列化:

spring:
  jackson:
    deserialization:
      fail-on-unknown-properties: false
    polymorphism:
      type-id-resolver: com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator

3. 确保Swagger UI显示子类型

上述两种修改方式都会让Swagger UI自动识别oneOf与discriminator的关联关系,在StudentDto的Schema中展示StudentType的子类型选项,支持用户选择具体子类型结构。


内容的提问来源于stack exchange,提问作者blaiso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 15:30:19