使用OpenAPI生成客户端时,如何保留JSON类中的自定义Type Adapter?
OpenAPI生成客户端时自定义Type Adapter代码被覆盖的原因及解决办法
原因
OpenAPI Generator是完全基于你的OpenAPI规格文件(yaml/json)重新生成代码文件的,包括JSON.java。你手动添加的导入语句、适配器实例化和注册代码,不属于生成器预设逻辑的一部分,也没有在规格文件或生成配置中声明,所以每次执行生成操作时,生成器都会用新生成的文件覆盖原有文件,不管你加了//DO NOT REMOVE这类注释都没用。
解决办法
1. 通过生成器配置自动注册适配器
直接在OpenAPI Generator的配置中声明自定义Type Adapter,让生成器自动把这些代码加到JSON.java里,避免手动修改被覆盖。
如果用Maven插件,在插件配置里添加:
<configuration> <!-- 映射自定义模型类 --> <typeMappings> <typeMapping>Ekm=com.salesforce.sds.kms.client.model.Ekm</typeMapping> <typeMapping>EkmSpec=com.salesforce.sds.kms.client.model.EkmSpec</typeMapping> </typeMappings> <!-- 映射自定义适配器类 --> <importMappings> <importMapping>EkmAdapter=com.salesforce.sds.kms.client.Serialization.EkmAdapter</importMapping> <importMapping>EkmSpecAdapter=com.salesforce.sds.kms.client.Serialization.EkmSpecAdapter</importMapping> </importMappings> </configuration>
如果用命令行生成,添加对应的参数:
openapi-generator generate -i your-spec.yaml -g java \ --type-mappings Ekm=com.salesforce.sds.kms.client.model.Ekm,EkmSpec=com.salesforce.sds.kms.client.model.EkmSpec \ --import-mappings EkmAdapter=com.salesforce.sds.kms.client.Serialization.EkmAdapter,EkmSpecAdapter=com.salesforce.sds.kms.client.Serialization.EkmSpecAdapter
2. 自定义模板修改生成逻辑
OpenAPI Generator使用Mustache模板生成代码,你可以修改JSON.mustache模板,把自定义适配器的代码固化到模板里,每次生成都会自动包含这些内容。
步骤:
- 找到对应语言的模板文件(Java+Gson的模板在生成器源码的
modules/openapi-generator/src/main/resources/Java/libraries/google-gson/JSON.mustache) - 复制该模板到你项目的自定义模板目录(比如
src/main/resources/openapi-templates) - 修改模板:
- 在导入区域添加:
import com.salesforce.sds.kms.client.Serialization.EkmAdapter; import com.salesforce.sds.kms.client.Serialization.EkmSpecAdapter; - 在适配器实例化区域添加:
private EkmSpecAdapter ekmSpecAdapter = new EkmSpecAdapter(); private EkmAdapter ekmAdapter = new EkmAdapter(); - 在Gson注册区域添加:
.registerTypeAdapter(EkmSpec.class, ekmSpecAdapter) .registerTypeAdapter(Ekm.class, ekmAdapter)
- 在导入区域添加:
- 生成时指定自定义模板目录,比如Maven插件添加:
<configuration> <templateDirectory>src/main/resources/openapi-templates</templateDirectory> </configuration>
3. 继承JSON类扩展功能
不修改生成的JSON.java,而是创建一个子类来扩展它,在子类中注册自定义适配器:
public class CustomJSON extends JSON { private final EkmSpecAdapter ekmSpecAdapter = new EkmSpecAdapter(); private final EkmAdapter ekmAdapter = new EkmAdapter(); public static Gson createCustomGson() { return createGson() .registerTypeAdapter(EkmSpec.class, ekmSpecAdapter) .registerTypeAdapter(Ekm.class, ekmAdapter) .create(); } }
之后项目中统一使用CustomJSON.createCustomGson()代替原有的JSON.createGson(),这样即使重新生成JSON.java,子类的代码也不会被影响。
代码差异示例
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import com.google.gson.JsonElement; -import com.salesforce.sds.kms.client.Serialization.EkmAdapter; // DO NOT REMOVE -import com.salesforce.sds.kms.client.Serialization.EkmSpecAdapter; // DO NOT REMOVE import io.gsonfire.GsonFireBuilder; import io.gsonfire.TypeSelector; @@ -51,8 +49,6 @@ public class JSON { private OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter(); private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter(); private ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter(); - private EkmSpecAdapter ekmSpecAdapter = new EkmSpecAdapter(); //DO NOT REMOVE - private EkmAdapter ekmAdapter = new EkmAdapter(); //DO NOT REMOVE public static GsonBuilder createGson() { GsonFireBuilder fireBuilder = new GsonFireBuilder() @@ -104,8 +100,6 @@ public class JSON { .registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter) .registerTypeAdapter(LocalDate.class, localDateTypeAdapter) .registerTypeAdapter(byte[].class, byteArrayAdapter) - .registerTypeAdapter(EkmSpec.class,ekmSpecAdapter) //DO NOT REMOVE. This is custom serialization - .registerTypeAdapter(Ekm.class,ekmAdapter) //DO NOT REMOVE. This is custom serialization .create(); }
内容的提问来源于stack exchange,提问作者Fan Zhang
相关产品推荐
相关产品推荐

