使用OpenAPI Generator生成DHL Java客户端时oneOf模型序列化异常问题
解决openapi-generator-maven-plugin生成oneOf类序列化多余字段问题
方案1:修正插件配置,确保oneOf生成接口而非继承AbstractOpenApiSchema
检查并调整maven插件配置,启用正确的参数组合,让oneOf类型生成接口而非继承带冗余字段的抽象类。注意使用最新稳定版插件,避免旧版本的兼容性问题:
<plugin> <groupId>org.openapitools</groupId> <artifactId>openapi-generator-maven-plugin</artifactId> <version>6.6.0</version> <executions> <execution> <goals> <goal>generate</goal> </goals> <configuration> <inputSpec>${project.basedir}/src/main/resources/dhl-api.yaml</inputSpec> <generatorName>java</generatorName> <configOptions> <useOneOfInterfaces>true</useOneOfInterfaces> <generateInterfaces>true</generateInterfaces> <useAbstractSchema>false</useAbstractSchema> <serializationLibrary>jackson</serializationLibrary> </configOptions> </configuration> </execution> </executions> </plugin>
如果API YAML中Shipper的oneOf包含同名类型(比如oneOf列表里有Shipper本身),会导致生成逻辑异常,需要先修改YAML,给冲突类型重命名(比如将oneOf中的Shipper改为FullShipper)。
方案2:自定义Jackson序列化器过滤冗余字段
如果配置调整无效,通过自定义Jackson序列化器,在序列化时直接输出业务数据,跳过instance、isNullable等冗余字段:
- 创建自定义序列化器:
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import org.openapitools.jackson.nullable.JsonNullable; import java.io.IOException; public class AbstractOpenApiSchemaSerializer extends JsonSerializer<AbstractOpenApiSchema> { @Override public void serialize(AbstractOpenApiSchema value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeObject(value.getActualInstance()); } }
- 在生成的
Consignee、Shipper类上添加序列化注解(若不想手动修改生成类,可通过修改openapi-generator的模板批量添加):
import com.fasterxml.jackson.databind.annotation.JsonSerialize; @JsonSerialize(using = AbstractOpenApiSchemaSerializer.class) public class Consignee extends AbstractOpenApiSchema { // 生成类的原有内容 }
方案3:修改生成模板,移除AbstractOpenApiSchema继承
从根源上修改生成逻辑,让oneOf类型不继承冗余的抽象类:
- 从openapi-generator官方仓库复制Java模板的
model.mustache文件到项目目录(如src/main/resources/templates/java/)。 - 修改模板中的继承逻辑:检测到oneOf类型时,移除
extends AbstractOpenApiSchema的代码,改为实现对应接口。 - 在插件配置中指定自定义模板目录:
<configuration> <!-- 其他配置 --> <templateDirectory>${project.basedir}/src/main/resources/templates/java</templateDirectory> </configuration>
内容的提问来源于stack exchange,提问作者AnQuqu
相关产品推荐
相关产品推荐

