Skip to content

Commit 6d335cd

Browse files
authored
feature(jackson3) add jackson3 support for Java Client generator - Restclient (#23023)
* Update restclient generator for spring 7 * Cleanup * Merge pom.xml * Merge ApiClients * Update restclient * Update docs * Use the same options as server generator * Sync samples * Add .gitignore * Add @JsonIgnore on no-arg constructor * Add @JsonIgnore only for jackson3 * Remove @JsonIgnore * Add to output folder * Update Jackson * Update jackson * Update gradle build * Fix build * Fix gradle * Fix build for gradle * Add missing samples * Update samples * Update samples * Fix kotlin samples * Change order * Change permissions for build
1 parent 3972c65 commit 6d335cd

File tree

662 files changed

+52866
-539
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

662 files changed

+52866
-539
lines changed

.github/workflows/samples-java-client-jdk17.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ jobs:
3232
- samples/client/petstore/java/webclient-jakarta
3333
- samples/client/petstore/java/restclient
3434
- samples/client/petstore/java/restclient-nullable-arrays
35+
- samples/client/petstore/java/restclient-springBoot4-jackson2
36+
- samples/client/petstore/java/restclient-springBoot4-jackson3
3537
- samples/client/petstore/java/restclient-swagger2
3638
- samples/client/petstore/java/restclient-useSingleRequestParameter
3739
- samples/client/petstore/java/restclient-useSingleRequestParameter-static
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
generatorName: java
2+
outputDir: samples/client/petstore/java/restclient-springBoot4-jackson2
3+
library: restclient
4+
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
5+
templateDir: modules/openapi-generator/src/main/resources/Java
6+
additionalProperties:
7+
artifactId: petstore-restclient
8+
hideGenerationTimestamp: "true"
9+
containerDefaultToNull: "true"
10+
useSpringBoot4: true
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
generatorName: java
2+
outputDir: samples/client/petstore/java/restclient-springBoot4-jackson3
3+
library: restclient
4+
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
5+
templateDir: modules/openapi-generator/src/main/resources/Java
6+
additionalProperties:
7+
artifactId: petstore-restclient
8+
hideGenerationTimestamp: "true"
9+
containerDefaultToNull: "true"
10+
useSpringBoot4: true
11+
useJackson3: true
12+
openApiNullable: false

docs/generators/java-microprofile.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
9797
|useBeanValidation|Use BeanValidation API annotations| |false|
9898
|useEnumCaseInsensitive|Use `equalsIgnoreCase` when String for enum comparison| |false|
9999
|useGzipFeature|Send gzip-encoded requests| |false|
100+
|useJackson3|Set it in order to use jackson 3 dependencies (only allowed when `useSpringBoot4` is set and incompatible with `openApiNullable`).| |false|
100101
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
101102
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and only one match in oneOf's schemas) will be skipped. Only jersey2, jersey3, native, okhttp-gson support this option.| |false|
102103
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
@@ -107,6 +108,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
107108
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
108109
|useSealedOneOfInterfaces|Generate the oneOf interfaces as sealed interfaces. Only supported for WebClient and RestClient.| |false|
109110
|useSingleRequestParameter|Setting this property to "true" will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY native, jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option. Setting this property to "static" does the same as "true", but also makes the generated arguments class static with single parameter instantiation.| |false|
111+
|useSpringBoot4|Generate code and provide dependencies for use with Spring Boot 4.x.| |false|
110112
|useUnaryInterceptor|If true it will generate ResponseInterceptors using a UnaryOperator. This can be usefull for manipulating the request before it gets passed, for example doing your own decryption| |false|
111113
|webclientBlockingOperations|Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync| |false|
112114
|withAWSV4Signature|whether to include AWS v4 signature support (only available for okhttp-gson library)| |false|

docs/generators/java.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
9797
|useBeanValidation|Use BeanValidation API annotations| |false|
9898
|useEnumCaseInsensitive|Use `equalsIgnoreCase` when String for enum comparison| |false|
9999
|useGzipFeature|Send gzip-encoded requests| |false|
100+
|useJackson3|Set it in order to use jackson 3 dependencies (only allowed when `useSpringBoot4` is set and incompatible with `openApiNullable`).| |false|
100101
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
101102
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and only one match in oneOf's schemas) will be skipped. Only jersey2, jersey3, native, okhttp-gson support this option.| |false|
102103
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
@@ -107,6 +108,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
107108
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
108109
|useSealedOneOfInterfaces|Generate the oneOf interfaces as sealed interfaces. Only supported for WebClient and RestClient.| |false|
109110
|useSingleRequestParameter|Setting this property to "true" will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY native, jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option. Setting this property to "static" does the same as "true", but also makes the generated arguments class static with single parameter instantiation.| |false|
111+
|useSpringBoot4|Generate code and provide dependencies for use with Spring Boot 4.x.| |false|
110112
|useUnaryInterceptor|If true it will generate ResponseInterceptors using a UnaryOperator. This can be usefull for manipulating the request before it gets passed, for example doing your own decryption| |false|
111113
|webclientBlockingOperations|Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync| |false|
112114
|withAWSV4Signature|whether to include AWS v4 signature support (only available for okhttp-gson library)| |false|

flake.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
devShells.default = pkgs.mkShell
1414
{
1515
buildInputs = with pkgs;[
16-
jdk11
16+
jdk17
1717
maven
18+
gradle
1819
];
1920
};
2021
}

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import static com.google.common.base.CaseFormat.LOWER_CAMEL;
4848
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
4949
import static java.util.Collections.sort;
50+
import static org.openapitools.codegen.CodegenConstants.SERIALIZATION_LIBRARY;
5051
import static org.openapitools.codegen.CodegenConstants.X_IMPLEMENTS;
5152
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
5253
import static org.openapitools.codegen.utils.StringUtils.camelize;
@@ -117,6 +118,12 @@ public class JavaClientCodegen extends AbstractJavaCodegen
117118
public static final String SERIALIZATION_LIBRARY_JACKSON = "jackson";
118119
public static final String SERIALIZATION_LIBRARY_JSONB = "jsonb";
119120

121+
public static final String USE_SPRING_BOOT4 = "useSpringBoot4";
122+
public static final String USE_JACKSON_3 = "useJackson3";
123+
private static final String JACKSON2_PACKAGE = "com.fasterxml.jackson";
124+
private static final String JACKSON3_PACKAGE = "tools.jackson";
125+
private static final String JACKSON_PACKAGE = "jacksonPackage";
126+
120127
public static final String GENERATE_CLIENT_AS_BEAN = "generateClientAsBean";
121128

122129
protected String gradleWrapperPackage = "gradle.wrapper";
@@ -134,7 +141,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
134141
@Setter protected boolean microProfileRegisterExceptionMapper = true;
135142
@Setter protected String configKey = null;
136143
@Setter(AccessLevel.PRIVATE) protected boolean configKeyFromClassName = false;
137-
138144
@Setter protected boolean asyncNative = false;
139145
@Setter protected boolean parcelableModel = false;
140146
@Setter protected boolean performBeanValidation = false;
@@ -158,6 +164,8 @@ public class JavaClientCodegen extends AbstractJavaCodegen
158164
* Serialization library.
159165
*/
160166
@Getter protected String serializationLibrary = null;
167+
@Getter @Setter protected boolean useSpringBoot4 = false;
168+
@Getter @Setter protected boolean useJackson3 = false;
161169
@Setter protected boolean useOneOfDiscriminatorLookup = false; // use oneOf discriminator's mapping for model lookup
162170
protected String rootJavaEEPackage;
163171
protected Map<String, MpRestClientVersion> mpRestClientVersions = new LinkedHashMap<>();
@@ -298,8 +306,8 @@ public JavaClientCodegen() {
298306
serializationOptions.put(SERIALIZATION_LIBRARY_JSONB, "Use JSON-B as serialization library");
299307
serializationLibrary.setEnum(serializationOptions);
300308
cliOptions.add(serializationLibrary);
301-
302-
// Ensure the OAS 3.x discriminator mappings include any descendent schemas that allOf
309+
cliOptions.add(CliOption.newBoolean(USE_SPRING_BOOT4, "Generate code and provide dependencies for use with Spring Boot 4.x.", useSpringBoot4));
310+
cliOptions.add(CliOption.newBoolean(USE_JACKSON_3, "Set it in order to use jackson 3 dependencies (only allowed when `" + USE_SPRING_BOOT4 + "` is set and incompatible with `"+OPENAPI_NULLABLE+"`).", useJackson3)); // Ensure the OAS 3.x discriminator mappings include any descendent schemas that allOf
303311
// inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values,
304312
// and the discriminator mapping schemas in the OAS document.
305313
this.setLegacyDiscriminatorBehavior(false);
@@ -367,8 +375,24 @@ public void processOpts() {
367375
// default jackson unless overridden by setSerializationLibrary
368376
this.jackson = !additionalProperties.containsKey(CodegenConstants.SERIALIZATION_LIBRARY) ||
369377
SERIALIZATION_LIBRARY_JACKSON.equals(additionalProperties.get(CodegenConstants.SERIALIZATION_LIBRARY));
370-
371378
convertPropertyToBooleanAndWriteBack(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, this::setUseOneOfDiscriminatorLookup);
379+
convertPropertyToBooleanAndWriteBack(USE_JACKSON_3, this::setUseJackson3);
380+
convertPropertyToBooleanAndWriteBack(USE_SPRING_BOOT4, this::setUseSpringBoot4);
381+
if(isUseJackson3() && !isUseSpringBoot4()){
382+
throw new IllegalArgumentException("useJackson3 is only available with Spring Boot >= 4");
383+
}
384+
if(isUseJackson3() && isOpenApiNullable()){
385+
throw new IllegalArgumentException("openApiNullable cannot be set with useJackson3");
386+
}
387+
388+
if(this.useJackson3){
389+
this.applyJackson3Package();
390+
} else {
391+
this.applyJackson2Package();
392+
}
393+
394+
// override parent one
395+
importMapping.put("JsonDeserialize", (useJackson3 ? JACKSON3_PACKAGE : JACKSON2_PACKAGE) + ".databind.annotation.JsonDeserialize");
372396

373397
// RxJava
374398
if (additionalProperties.containsKey(USE_RX_JAVA2) && additionalProperties.containsKey(USE_RX_JAVA3)) {
@@ -790,8 +814,10 @@ public void processOpts() {
790814
additionalProperties.remove(SERIALIZATION_LIBRARY_GSON);
791815
additionalProperties.remove(SERIALIZATION_LIBRARY_JSONB);
792816
supportingFiles.add(new SupportingFile("RFC3339DateFormat.mustache", invokerFolder, "RFC3339DateFormat.java"));
793-
supportingFiles.add(new SupportingFile("RFC3339InstantDeserializer.mustache", invokerFolder, "RFC3339InstantDeserializer.java"));
794-
supportingFiles.add(new SupportingFile("RFC3339JavaTimeModule.mustache", invokerFolder, "RFC3339JavaTimeModule.java"));
817+
if (!useJackson3) {
818+
supportingFiles.add(new SupportingFile("RFC3339InstantDeserializer.mustache", invokerFolder, "RFC3339InstantDeserializer.java"));
819+
supportingFiles.add(new SupportingFile("RFC3339JavaTimeModule.mustache", invokerFolder, "RFC3339JavaTimeModule.java"));
820+
}
795821
break;
796822
case SERIALIZATION_LIBRARY_GSON:
797823
additionalProperties.put(SERIALIZATION_LIBRARY_GSON, "true");
@@ -809,7 +835,7 @@ public void processOpts() {
809835
additionalProperties.remove(SERIALIZATION_LIBRARY_JSONB);
810836
break;
811837
}
812-
838+
813839
if (isLibrary(FEIGN)) {
814840
additionalProperties.put("feign-okhttp", "true");
815841
} else if (isLibrary(FEIGN_HC5)) {
@@ -1028,6 +1054,7 @@ private static boolean isMultipartType(List<Map<String, String>> consumes) {
10281054
@Override
10291055
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
10301056
super.postProcessModelProperty(model, property);
1057+
10311058
if (!model.isEnum) {
10321059
//Needed imports for Jackson based libraries
10331060
if (additionalProperties.containsKey(SERIALIZATION_LIBRARY_JACKSON)) {
@@ -1241,6 +1268,14 @@ public void setCaseInsensitiveResponseHeaders(final Boolean caseInsensitiveRespo
12411268
this.caseInsensitiveResponseHeaders = caseInsensitiveResponseHeaders;
12421269
}
12431270

1271+
protected void applyJackson2Package() {
1272+
writePropertyBack(JACKSON_PACKAGE, JACKSON2_PACKAGE);
1273+
}
1274+
1275+
protected void applyJackson3Package() {
1276+
writePropertyBack(JACKSON_PACKAGE, JACKSON3_PACKAGE);
1277+
}
1278+
12441279
public void setSerializationLibrary(String serializationLibrary) {
12451280
if (SERIALIZATION_LIBRARY_JACKSON.equalsIgnoreCase(serializationLibrary)) {
12461281
this.serializationLibrary = SERIALIZATION_LIBRARY_JACKSON;
@@ -1281,7 +1316,7 @@ public String toApiVarName(String name) {
12811316

12821317
@Override
12831318
public void addImportsToOneOfInterface(List<Map<String, String>> imports) {
1284-
if(additionalProperties.containsKey(SERIALIZATION_LIBRARY_JACKSON)) {
1319+
if (additionalProperties.containsKey(SERIALIZATION_LIBRARY_JACKSON)) {
12851320
for (String i : Arrays.asList("JsonSubTypes", "JsonTypeInfo", "JsonIgnoreProperties")) {
12861321
Map<String, String> oneImport = new HashMap<>();
12871322
oneImport.put("import", importMapping.get(i));

modules/openapi-generator/src/main/resources/Java/RFC3339DateFormat.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{{>licenseInfo}}
22
package {{invokerPackage}};
33

4-
import com.fasterxml.jackson.databind.util.StdDateFormat;
4+
import {{jacksonPackage}}.databind.util.StdDateFormat;
55

66
import java.text.DateFormat;
77
import java.text.FieldPosition;

0 commit comments

Comments
 (0)