forked from loafle/openapi-generator-original
[java][client] Add a "serializationLibrary" option (#3759)
* [java][client] Add a "serializationLibrary" option * Update docs
This commit is contained in:
parent
dc7bcbdb85
commit
60e4c923dd
@ -56,3 +56,4 @@ sidebar_label: java
|
||||
|useReflectionEqualsHashCode|Use org.apache.commons.lang3.builder for equals and hashCode in the models. WARNING: This will fail under a security manager, unless the appropriate permissions are set up correctly and also there's potential performance impact.| |false|
|
||||
|caseInsensitiveResponseHeaders|Make API response's headers case-insensitive. Available on okhttp-gson, jersey2 libraries| |false|
|
||||
|library|library template (sub-template) to use|<dl><dt>**jersey1**</dt><dd>HTTP client: Jersey client 1.19.x. JSON processing: Jackson 2.8.x. Enable Java6 support using '-DsupportJava6=true'. Enable gzip request encoding using '-DuseGzipFeature=true'. IMPORTANT NOTE: jersey 1.x is no longer actively maintained so please upgrade to 'jersey2' or other HTTP libaries instead.</dd><dt>**jersey2**</dt><dd>HTTP client: Jersey client 2.25.1. JSON processing: Jackson 2.8.x</dd><dt>**feign**</dt><dd>HTTP client: OpenFeign 9.x or 10.x. JSON processing: Jackson 2.8.x. To enable OpenFeign 10.x, set the 'feignVersion' option to '10.x'</dd><dt>**okhttp-gson**</dt><dd>[DEFAULT] HTTP client: OkHttp 3.x. JSON processing: Gson 2.8.x. Enable Parcelable models on Android using '-DparcelableModel=true'. Enable gzip request encoding using '-DuseGzipFeature=true'.</dd><dt>**retrofit**</dt><dd>HTTP client: OkHttp 2.x. JSON processing: Gson 2.x (Retrofit 1.9.0). IMPORTANT NOTE: retrofit1.x is no longer actively maintained so please upgrade to 'retrofit2' instead.</dd><dt>**retrofit2**</dt><dd>HTTP client: OkHttp 3.x. JSON processing: Gson 2.x (Retrofit 2.3.0). Enable the RxJava adapter using '-DuseRxJava[2]=true'. (RxJava 1.x or 2.x)</dd><dt>**resttemplate**</dt><dd>HTTP client: Spring RestTemplate 4.x. JSON processing: Jackson 2.8.x</dd><dt>**webclient**</dt><dd>HTTP client: Spring WebClient 5.x. JSON processing: Jackson 2.9.x</dd><dt>**resteasy**</dt><dd>HTTP client: Resteasy client 3.x. JSON processing: Jackson 2.8.x</dd><dt>**vertx**</dt><dd>HTTP client: VertX client 3.x. JSON processing: Jackson 2.8.x</dd><dt>**google-api-client**</dt><dd>HTTP client: Google API client 1.x. JSON processing: Jackson 2.8.x</dd><dt>**rest-assured**</dt><dd>HTTP client: rest-assured : 4.x. JSON processing: Gson 2.x. Only for Java8</dd><dt>**native**</dt><dd>HTTP client: Java native HttpClient. JSON processing: Jackson 2.9.x. Only for Java11+</dd><dl>|okhttp-gson|
|
||||
|serializationLibrary|Serialization library, default depends from the library|<dl><dt>**jackson**</dt><dd>Use Jackson as serialization library</dd><dt>**gson**</dt><dd>Use Gson as serialization library</dd><dl>|null|
|
||||
|
@ -78,6 +78,10 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
public static final String RETROFIT_2 = "retrofit2";
|
||||
public static final String VERTX = "vertx";
|
||||
|
||||
public static final String SERIALIZATION_LIBRARY = "serializationLibrary";
|
||||
public static final String SERIALIZATION_LIBRARY_GSON = "gson";
|
||||
public static final String SERIALIZATION_LIBRARY_JACKSON = "jackson";
|
||||
|
||||
protected String gradleWrapperPackage = "gradle.wrapper";
|
||||
protected boolean useRxJava = false;
|
||||
protected boolean useRxJava2 = false;
|
||||
@ -95,6 +99,8 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
protected boolean useReflectionEqualsHashCode = false;
|
||||
protected boolean caseInsensitiveResponseHeaders = false;
|
||||
protected String authFolder;
|
||||
protected String serializationLibrary = null;
|
||||
|
||||
|
||||
public JavaClientCodegen() {
|
||||
super();
|
||||
@ -128,7 +134,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
cliOptions.add(CliOption.newBoolean(USE_REFLECTION_EQUALS_HASHCODE, "Use org.apache.commons.lang3.builder for equals and hashCode in the models. WARNING: This will fail under a security manager, unless the appropriate permissions are set up correctly and also there's potential performance impact."));
|
||||
cliOptions.add(CliOption.newBoolean(CASE_INSENSITIVE_RESPONSE_HEADERS, "Make API response's headers case-insensitive. Available on " + OKHTTP_GSON + ", " + JERSEY2 + " libraries"));
|
||||
|
||||
|
||||
supportedLibraries.put(JERSEY1, "HTTP client: Jersey client 1.19.x. JSON processing: Jackson 2.8.x. Enable Java6 support using '-DsupportJava6=true'. Enable gzip request encoding using '-DuseGzipFeature=true'. IMPORTANT NOTE: jersey 1.x is no longer actively maintained so please upgrade to 'jersey2' or other HTTP libaries instead.");
|
||||
supportedLibraries.put(JERSEY2, "HTTP client: Jersey client 2.25.1. JSON processing: Jackson 2.8.x");
|
||||
supportedLibraries.put(FEIGN, "HTTP client: OpenFeign 9.x or 10.x. JSON processing: Jackson 2.8.x. To enable OpenFeign 10.x, set the 'feignVersion' option to '10.x'");
|
||||
@ -150,6 +155,12 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
cliOptions.add(libraryOption);
|
||||
setLibrary(OKHTTP_GSON);
|
||||
|
||||
CliOption serializationLibrary = new CliOption(SERIALIZATION_LIBRARY, "Serialization library, default depends from the library");
|
||||
Map<String, String> serializationOptions = new HashMap<>();
|
||||
serializationOptions.put(SERIALIZATION_LIBRARY_GSON, "Use Gson as serialization library");
|
||||
serializationOptions.put(SERIALIZATION_LIBRARY_JACKSON, "Use Jackson as serialization library");
|
||||
serializationLibrary.setEnum(serializationOptions);
|
||||
cliOptions.add(serializationLibrary);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -284,6 +295,10 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
"BeanValidationException.java"));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(SERIALIZATION_LIBRARY)) {
|
||||
setSerializationLibrary(additionalProperties.get(SERIALIZATION_LIBRARY).toString());
|
||||
}
|
||||
|
||||
//TODO: add doc to retrofit1 and feign
|
||||
if (FEIGN.equals(getLibrary()) || RETROFIT_1.equals(getLibrary())) {
|
||||
modelDocTemplateFiles.remove("model_doc.mustache");
|
||||
@ -301,7 +316,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
}
|
||||
|
||||
if (FEIGN.equals(getLibrary())) {
|
||||
additionalProperties.put("jackson", "true");
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
|
||||
supportingFiles.add(new SupportingFile("ParamExpander.mustache", invokerFolder, "ParamExpander.java"));
|
||||
supportingFiles.add(new SupportingFile("EncodingUtils.mustache", invokerFolder, "EncodingUtils.java"));
|
||||
} else if (OKHTTP_GSON.equals(getLibrary()) || StringUtils.isEmpty(getLibrary())) {
|
||||
@ -316,48 +331,48 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
// NOTE: below moved to postProcessOpoerationsWithModels
|
||||
//supportingFiles.add(new SupportingFile("auth/OAuthOkHttpClient.mustache", authFolder, "OAuthOkHttpClient.java"));
|
||||
//supportingFiles.add(new SupportingFile("auth/RetryingOAuth.mustache", authFolder, "RetryingOAuth.java"));
|
||||
additionalProperties.put("gson", "true");
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_GSON);
|
||||
} else if (usesAnyRetrofitLibrary()) {
|
||||
supportingFiles.add(new SupportingFile("auth/OAuthOkHttpClient.mustache", authFolder, "OAuthOkHttpClient.java"));
|
||||
supportingFiles.add(new SupportingFile("CollectionFormats.mustache", invokerFolder, "CollectionFormats.java"));
|
||||
additionalProperties.put("gson", "true");
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_GSON);
|
||||
if ("retrofit2".equals(getLibrary()) && !usePlayWS) {
|
||||
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
|
||||
}
|
||||
} else if (JERSEY2.equals(getLibrary())) {
|
||||
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
|
||||
supportingFiles.add(new SupportingFile("ApiResponse.mustache", invokerFolder, "ApiResponse.java"));
|
||||
additionalProperties.put("jackson", "true");
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
|
||||
} else if (NATIVE.equals(getLibrary())) {
|
||||
setJava8Mode(true);
|
||||
additionalProperties.put("java8", "true");
|
||||
additionalProperties.put("jackson", "true");
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
|
||||
} else if (RESTEASY.equals(getLibrary())) {
|
||||
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
|
||||
additionalProperties.put("jackson", "true");
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
|
||||
} else if (JERSEY1.equals(getLibrary())) {
|
||||
additionalProperties.put("jackson", "true");
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
|
||||
} else if (RESTTEMPLATE.equals(getLibrary())) {
|
||||
additionalProperties.put("jackson", "true");
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
|
||||
supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java"));
|
||||
} else if (WEBCLIENT.equals(getLibrary())) {
|
||||
setJava8Mode(true);
|
||||
additionalProperties.put("java8", "true");
|
||||
additionalProperties.put("jackson", "true");
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
|
||||
} else if (VERTX.equals(getLibrary())) {
|
||||
typeMapping.put("file", "AsyncFile");
|
||||
importMapping.put("AsyncFile", "io.vertx.core.file.AsyncFile");
|
||||
setJava8Mode(true);
|
||||
additionalProperties.put("java8", "true");
|
||||
additionalProperties.put("jackson", "true");
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
|
||||
apiTemplateFiles.put("apiImpl.mustache", "Impl.java");
|
||||
apiTemplateFiles.put("rxApiImpl.mustache", ".java");
|
||||
supportingFiles.remove(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml"));
|
||||
} else if (GOOGLE_API_CLIENT.equals(getLibrary())) {
|
||||
additionalProperties.put("jackson", "true");
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
|
||||
|
||||
} else if (REST_ASSURED.equals(getLibrary())) {
|
||||
additionalProperties.put("gson", "true");
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_GSON);
|
||||
additionalProperties.put("convert", new CaseFormatLambda(LOWER_CAMEL, UPPER_UNDERSCORE));
|
||||
apiTemplateFiles.put("api.mustache", ".java");
|
||||
supportingFiles.add(new SupportingFile("ResponseSpecBuilders.mustache", invokerFolder, "ResponseSpecBuilders.java"));
|
||||
@ -415,16 +430,30 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java"));
|
||||
supportingFiles.add(new SupportingFile("Pair.mustache", invokerFolder, "Pair.java"));
|
||||
|
||||
additionalProperties.put("jackson", "true");
|
||||
additionalProperties.remove("gson");
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("jackson") && !NATIVE.equals(getLibrary())) {
|
||||
supportingFiles.add(new SupportingFile("RFC3339DateFormat.mustache", invokerFolder, "RFC3339DateFormat.java"));
|
||||
if ("threetenbp".equals(dateLibrary) && !usePlayWS) {
|
||||
supportingFiles.add(new SupportingFile("CustomInstantDeserializer.mustache", invokerFolder, "CustomInstantDeserializer.java"));
|
||||
}
|
||||
if(getSerializationLibrary() == null) {
|
||||
LOGGER.info("No serializationLibrary configured, using '"+SERIALIZATION_LIBRARY_GSON+"' as fallback");
|
||||
setSerializationLibrary(SERIALIZATION_LIBRARY_GSON);
|
||||
}
|
||||
if(SERIALIZATION_LIBRARY_JACKSON.equals(getSerializationLibrary())) {
|
||||
additionalProperties.put(SERIALIZATION_LIBRARY_JACKSON, "true");
|
||||
additionalProperties.remove(SERIALIZATION_LIBRARY_GSON);
|
||||
if (!NATIVE.equals(getLibrary())) {
|
||||
supportingFiles.add(new SupportingFile("RFC3339DateFormat.mustache", invokerFolder, "RFC3339DateFormat.java"));
|
||||
if ("threetenbp".equals(dateLibrary) && !usePlayWS) {
|
||||
supportingFiles.add(new SupportingFile("CustomInstantDeserializer.mustache", invokerFolder, "CustomInstantDeserializer.java"));
|
||||
}
|
||||
}
|
||||
} else if (SERIALIZATION_LIBRARY_GSON.equals(getSerializationLibrary())) {
|
||||
additionalProperties.put(SERIALIZATION_LIBRARY_GSON, "true");
|
||||
additionalProperties.remove(SERIALIZATION_LIBRARY_JACKSON);
|
||||
} else {
|
||||
additionalProperties.remove(SERIALIZATION_LIBRARY_JACKSON);
|
||||
additionalProperties.remove(SERIALIZATION_LIBRARY_GSON);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean usesAnyRetrofitLibrary() {
|
||||
@ -581,12 +610,12 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
if (!BooleanUtils.toBoolean(model.isEnum)) {
|
||||
//final String lib = getLibrary();
|
||||
//Needed imports for Jackson based libraries
|
||||
if (additionalProperties.containsKey("jackson")) {
|
||||
if (additionalProperties.containsKey(SERIALIZATION_LIBRARY_JACKSON)) {
|
||||
model.imports.add("JsonProperty");
|
||||
model.imports.add("JsonValue");
|
||||
model.imports.add("JsonInclude");
|
||||
}
|
||||
if (additionalProperties.containsKey("gson")) {
|
||||
if (additionalProperties.containsKey(SERIALIZATION_LIBRARY_GSON)) {
|
||||
model.imports.add("SerializedName");
|
||||
model.imports.add("TypeAdapter");
|
||||
model.imports.add("JsonAdapter");
|
||||
@ -596,7 +625,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
}
|
||||
} else { // enum class
|
||||
//Needed imports for Jackson's JsonCreator
|
||||
if (additionalProperties.containsKey("jackson")) {
|
||||
if (additionalProperties.containsKey(SERIALIZATION_LIBRARY_JACKSON)) {
|
||||
model.imports.add("JsonValue");
|
||||
model.imports.add("JsonCreator");
|
||||
}
|
||||
@ -607,7 +636,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
|
||||
objs = super.postProcessModelsEnum(objs);
|
||||
//Needed import for Gson based libraries
|
||||
if (additionalProperties.containsKey("gson")) {
|
||||
if (additionalProperties.containsKey(SERIALIZATION_LIBRARY_GSON)) {
|
||||
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");
|
||||
List<Object> models = (List<Object>) objs.get("models");
|
||||
for (Object _mo : models) {
|
||||
@ -628,7 +657,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
@Override
|
||||
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||
objs = super.postProcessModels(objs);
|
||||
if (additionalProperties.containsKey("jackson") && !JERSEY1.equals(getLibrary())) {
|
||||
if (additionalProperties.containsKey(SERIALIZATION_LIBRARY_JACKSON) && !JERSEY1.equals(getLibrary())) {
|
||||
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");
|
||||
List<Object> models = (List<Object>) objs.get("models");
|
||||
for (Object _mo : models) {
|
||||
@ -712,6 +741,31 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
this.caseInsensitiveResponseHeaders = caseInsensitiveResponseHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialization library.
|
||||
* @return 'gson' or 'jackson'
|
||||
*/
|
||||
public String getSerializationLibrary() {
|
||||
return serializationLibrary;
|
||||
}
|
||||
|
||||
public void setSerializationLibrary(String serializationLibrary) {
|
||||
if(SERIALIZATION_LIBRARY_JACKSON.equalsIgnoreCase(serializationLibrary)) {
|
||||
this.serializationLibrary = SERIALIZATION_LIBRARY_JACKSON;
|
||||
} else if(SERIALIZATION_LIBRARY_GSON.equalsIgnoreCase(serializationLibrary)) {
|
||||
this.serializationLibrary = SERIALIZATION_LIBRARY_GSON;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unexpected serializationLibrary value: " + serializationLibrary);
|
||||
}
|
||||
}
|
||||
|
||||
public void forceSerializationLibrary(String serializationLibrary) {
|
||||
if((this.serializationLibrary != null) && !this.serializationLibrary.equalsIgnoreCase(serializationLibrary)) {
|
||||
LOGGER.warn("The configured serializationLibrary '" + this.serializationLibrary + "', is not supported by the library: '" + getLibrary() + "', switching back to: " + serializationLibrary);
|
||||
}
|
||||
setSerializationLibrary(serializationLibrary);
|
||||
}
|
||||
|
||||
final private static Pattern JSON_MIME_PATTERN = Pattern.compile("(?i)application\\/json(;.*)?");
|
||||
final private static Pattern JSON_VENDOR_MIME_PATTERN = Pattern.compile("(?i)application\\/vnd.(.*)+json(;.*)?");
|
||||
|
||||
|
@ -150,6 +150,7 @@ public class JavaClientCodegenTest {
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.API_PACKAGE), "org.openapitools.client.api");
|
||||
Assert.assertEquals(codegen.getInvokerPackage(), "org.openapitools.client");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "org.openapitools.client");
|
||||
Assert.assertEquals(codegen.getSerializationLibrary(), JavaClientCodegen.SERIALIZATION_LIBRARY_GSON);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -159,6 +160,7 @@ public class JavaClientCodegenTest {
|
||||
codegen.setModelPackage("xyz.yyyyy.zzzzzzz.model");
|
||||
codegen.setApiPackage("xyz.yyyyy.zzzzzzz.api");
|
||||
codegen.setInvokerPackage("xyz.yyyyy.zzzzzzz.invoker");
|
||||
codegen.setSerializationLibrary("JACKSON");
|
||||
codegen.processOpts();
|
||||
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.TRUE);
|
||||
@ -169,6 +171,7 @@ public class JavaClientCodegenTest {
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.API_PACKAGE), "xyz.yyyyy.zzzzzzz.api");
|
||||
Assert.assertEquals(codegen.getInvokerPackage(), "xyz.yyyyy.zzzzzzz.invoker");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "xyz.yyyyy.zzzzzzz.invoker");
|
||||
Assert.assertEquals(codegen.getSerializationLibrary(), JavaClientCodegen.SERIALIZATION_LIBRARY_GSON); // the library JavaClientCodegen.OKHTTP_GSON only supports GSON
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -178,6 +181,8 @@ public class JavaClientCodegenTest {
|
||||
codegen.additionalProperties().put(CodegenConstants.MODEL_PACKAGE, "xyz.yyyyy.zzzzzzz.mmmmm.model");
|
||||
codegen.additionalProperties().put(CodegenConstants.API_PACKAGE, "xyz.yyyyy.zzzzzzz.aaaaa.api");
|
||||
codegen.additionalProperties().put(CodegenConstants.INVOKER_PACKAGE, "xyz.yyyyy.zzzzzzz.iiii.invoker");
|
||||
codegen.additionalProperties().put(JavaClientCodegen.SERIALIZATION_LIBRARY, "JACKSON");
|
||||
codegen.additionalProperties().put(CodegenConstants.LIBRARY, JavaClientCodegen.JERSEY2);
|
||||
codegen.processOpts();
|
||||
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.TRUE);
|
||||
@ -188,6 +193,7 @@ public class JavaClientCodegenTest {
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.API_PACKAGE), "xyz.yyyyy.zzzzzzz.aaaaa.api");
|
||||
Assert.assertEquals(codegen.getInvokerPackage(), "xyz.yyyyy.zzzzzzz.iiii.invoker");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "xyz.yyyyy.zzzzzzz.iiii.invoker");
|
||||
Assert.assertEquals(codegen.getSerializationLibrary(), JavaClientCodegen.SERIALIZATION_LIBRARY_JACKSON);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
x
Reference in New Issue
Block a user