Skip to content

Commit 0d2ff8c

Browse files
authored
feat(jackson3): add jackson3 support for Java Client generator - WebClient (#23031)
* feat(jackson3): add jackson3 support for Java Client generator - WebClient * chore: generate bin/generate-samples.sh bin/configs/java-* * fix: add back FindBugs JSR 305 dependency * chore: generate bin/generate-samples.sh bin/configs/java-* * chore: generate bin/generate-samples.sh bin/configs/java-*
1 parent cca5dda commit 0d2ff8c

233 files changed

Lines changed: 26014 additions & 258 deletions

File tree

Some content is hidden

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

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ jobs:
4343
- samples/client/petstore/java/restclient-useSingleRequestParameter-static
4444
- samples/client/others/java/webclient-sealedInterface
4545
- samples/client/others/java/webclient-sealedInterface_3_1
46+
- samples/client/petstore/java/webclient-springBoot4-jackson3
4647
- samples/client/petstore/java/webclient-useSingleRequestParameter
4748
- samples/client/others/java/restclient-enum-in-multipart
4849
steps:
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/webclient-springBoot4-jackson3
3+
library: webclient
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-webclient
8+
hideGenerationTimestamp: "true"
9+
containerDefaultToNull: "true"
10+
useSpringBoot4: true
11+
useJackson3: true
12+
openApiNullable: false

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,11 @@ public void processOpts() {
391391
this.applyJackson2Package();
392392
}
393393

394+
if(this.useSpringBoot4) {
395+
setUseJakartaEe(true);
396+
applyJakartaPackage();
397+
}
398+
394399
// override parent one
395400
importMapping.put("JsonDeserialize", (useJackson3 ? JACKSON3_PACKAGE : JACKSON2_PACKAGE) + ".databind.annotation.JsonDeserialize");
396401

modules/openapi-generator/src/main/resources/Java/libraries/webclient/ApiClient.mustache

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,21 @@
22

33
package {{invokerPackage}};
44

5+
import {{jacksonPackage}}.databind.DeserializationFeature;
6+
7+
{{#useJackson3}}
8+
import {{jacksonPackage}}.core.JacksonException;
9+
import {{jacksonPackage}}.databind.json.JsonMapper;
10+
import org.springframework.http.codec.json.JacksonJsonDecoder;
11+
import org.springframework.http.codec.json.JacksonJsonEncoder;
12+
{{/useJackson3}}
13+
{{^useJackson3}}
514
import com.fasterxml.jackson.core.JsonProcessingException;
6-
import com.fasterxml.jackson.databind.DeserializationFeature;
715
import com.fasterxml.jackson.databind.ObjectMapper;
816
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
17+
import org.springframework.http.codec.json.Jackson2JsonDecoder;
18+
import org.springframework.http.codec.json.Jackson2JsonEncoder;
19+
{{/useJackson3}}
920
{{#openApiNullable}}
1021
import org.openapitools.jackson.nullable.JsonNullableModule;
1122
{{/openApiNullable}}
@@ -27,8 +38,6 @@ import org.springframework.http.client.ClientHttpRequestExecution;
2738
import org.springframework.http.client.ClientHttpRequestInterceptor;
2839
import org.springframework.http.client.ClientHttpResponse;
2940
import org.springframework.http.client.reactive.ClientHttpRequest;
30-
import org.springframework.http.codec.json.Jackson2JsonDecoder;
31-
import org.springframework.http.codec.json.Jackson2JsonEncoder;
3241
{{#generateClientAsBean}}
3342
import org.springframework.stereotype.Component;
3443
{{/generateClientAsBean}}
@@ -110,15 +119,20 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
110119

111120
protected final WebClient webClient;
112121
protected final DateFormat dateFormat;
113-
protected final ObjectMapper objectMapper;
122+
{{^useJackson3}}
123+
protected final ObjectMapper mapper;
124+
{{/useJackson3}}
125+
{{#useJackson3}}
126+
protected final JsonMapper mapper;
127+
{{/useJackson3}}
114128

115129
protected Map<String, Authentication> authentications;
116130

117131

118132
public ApiClient() {
119133
this.dateFormat = createDefaultDateFormat();
120-
this.objectMapper = createDefaultObjectMapper(this.dateFormat);
121-
this.webClient = buildWebClient(this.objectMapper);
134+
this.mapper = createDefaultMapper(this.dateFormat);
135+
this.webClient = buildWebClient(this.mapper);
122136
this.init();
123137
}
124138

@@ -129,18 +143,18 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
129143
this(Optional.ofNullable(webClient).orElseGet(() -> buildWebClient()), createDefaultDateFormat());
130144
}
131145

132-
public ApiClient(ObjectMapper mapper, DateFormat format) {
133-
this(buildWebClient(mapper.copy()), format);
146+
public ApiClient({{#useJackson3}}JsonMapper{{/useJackson3}}{{^useJackson3}}ObjectMapper{{/useJackson3}} mapper, DateFormat format) {
147+
this(buildWebClient(mapper), format);
134148
}
135149

136-
public ApiClient(WebClient webClient, ObjectMapper mapper, DateFormat format) {
137-
this(Optional.ofNullable(webClient).orElseGet(() -> buildWebClient(mapper.copy())), format);
150+
public ApiClient(WebClient webClient, {{#useJackson3}}JsonMapper{{/useJackson3}}{{^useJackson3}}ObjectMapper{{/useJackson3}} mapper, DateFormat format) {
151+
this(Optional.ofNullable(webClient).orElseGet(() -> buildWebClient(mapper)), format);
138152
}
139153

140154
protected ApiClient(WebClient webClient, DateFormat format) {
141155
this.webClient = webClient;
142156
this.dateFormat = format;
143-
this.objectMapper = createDefaultObjectMapper(format);
157+
this.mapper = createDefaultMapper(format);
144158
this.init();
145159
}
146160

@@ -150,7 +164,21 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
150164
return dateFormat;
151165
}
152166

153-
public static ObjectMapper createDefaultObjectMapper(@Nullable DateFormat dateFormat) {
167+
{{#useJackson3}}
168+
public static JsonMapper createDefaultMapper(@Nullable DateFormat dateFormat) {
169+
return JsonMapper.builder()
170+
.defaultDateFormat(dateFormat)
171+
{{#failOnUnknownProperties}}
172+
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
173+
{{/failOnUnknownProperties}}
174+
{{^failOnUnknownProperties}}
175+
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
176+
{{/failOnUnknownProperties}}
177+
.build();
178+
}
179+
{{/useJackson3}}
180+
{{^useJackson3}}
181+
public static ObjectMapper createDefaultMapper(@Nullable DateFormat dateFormat) {
154182
if (null == dateFormat) {
155183
dateFormat = createDefaultDateFormat();
156184
}
@@ -164,6 +192,8 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
164192
{{/openApiNullable}}
165193
return mapper;
166194
}
195+
{{/useJackson3}}
196+
167197

168198
protected void init() {
169199
// Setup authentications (key: authentication name, value: authentication).
@@ -181,12 +211,18 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
181211
* @param mapper ObjectMapper used for serialize/deserialize
182212
* @return WebClient
183213
*/
184-
public static WebClient.Builder buildWebClientBuilder(ObjectMapper mapper) {
214+
public static WebClient.Builder buildWebClientBuilder({{#useJackson3}}JsonMapper{{/useJackson3}}{{^useJackson3}}ObjectMapper{{/useJackson3}} mapper) {
185215
ExchangeStrategies strategies = ExchangeStrategies
186216
.builder()
187217
.codecs(clientDefaultCodecsConfigurer -> {
218+
{{#useJackson3}}
219+
clientDefaultCodecsConfigurer.defaultCodecs().jacksonJsonEncoder(new JacksonJsonEncoder(mapper, MediaType.APPLICATION_JSON));
220+
clientDefaultCodecsConfigurer.defaultCodecs().jacksonJsonDecoder(new JacksonJsonDecoder(mapper, MediaType.APPLICATION_JSON));
221+
{{/useJackson3}}
222+
{{^useJackson3}}
188223
clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(mapper, MediaType.APPLICATION_JSON));
189224
clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(mapper, MediaType.APPLICATION_JSON));
225+
{{/useJackson3}}
190226
}).build();
191227
WebClient.Builder webClientBuilder = WebClient.builder().exchangeStrategies(strategies);
192228
return webClientBuilder;
@@ -197,15 +233,15 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
197233
* @return WebClient
198234
*/
199235
public static WebClient.Builder buildWebClientBuilder() {
200-
return buildWebClientBuilder(createDefaultObjectMapper(null));
236+
return buildWebClientBuilder(createDefaultMapper(null));
201237
}
202238

203239
/**
204240
* Build the WebClient used to make HTTP requests.
205241
* @param mapper ObjectMapper used for serialize/deserialize
206242
* @return WebClient
207243
*/
208-
public static WebClient buildWebClient(ObjectMapper mapper) {
244+
public static WebClient buildWebClient({{#useJackson3}}JsonMapper{{/useJackson3}}{{^useJackson3}}ObjectMapper{{/useJackson3}} mapper) {
209245
return buildWebClientBuilder(mapper).build();
210246
}
211247

@@ -214,7 +250,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
214250
* @return WebClient
215251
*/
216252
public static WebClient buildWebClient() {
217-
return buildWebClientBuilder(createDefaultObjectMapper(null)).build();
253+
return buildWebClientBuilder(createDefaultMapper(null)).build();
218254
}
219255

220256
/**
@@ -403,11 +439,11 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
403439
}
404440

405441
/**
406-
* Get the ObjectMapper used to make HTTP requests.
407-
* @return ObjectMapper objectMapper
442+
* Get the {{#useJackson3}}JsonMapper{{/useJackson3}}{{^useJackson3}}ObjectMapper{{/useJackson3}} used to make HTTP requests.
443+
* @return {{#useJackson3}}JsonMapper{{/useJackson3}}{{^useJackson3}}ObjectMapper{{/useJackson3}} mapper
408444
*/
409-
public ObjectMapper getObjectMapper() {
410-
return objectMapper;
445+
public {{#useJackson3}}JsonMapper{{/useJackson3}}{{^useJackson3}}ObjectMapper{{/useJackson3}} get{{#useJackson3}}JsonMapper{{/useJackson3}}{{^useJackson3}}ObjectMapper{{/useJackson3}}() {
446+
return mapper;
411447
}
412448

413449
/**
@@ -457,17 +493,17 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
457493
valueCollection = (Collection<?>) value;
458494
} else {
459495
try {
460-
return parameterToMultiValueMap(collectionFormat, name, objectMapper.writeValueAsString(value));
461-
} catch (JsonProcessingException e) {
496+
return parameterToMultiValueMap(collectionFormat, name, mapper.writeValueAsString(value));
497+
} catch ({{#useJackson3}}JacksonException{{/useJackson3}}{{^useJackson3}}JsonProcessingException{{/useJackson3}} e) {
462498
throw new RuntimeException(e);
463499
}
464500
}
465501

466502
List<String> values = new ArrayList<>();
467503
for(Object o : valueCollection) {
468504
try {
469-
values.add(objectMapper.writeValueAsString(o));
470-
} catch (JsonProcessingException e) {
505+
values.add(mapper.writeValueAsString(o));
506+
} catch ({{#useJackson3}}JacksonException{{/useJackson3}}{{^useJackson3}}JsonProcessingException{{/useJackson3}} e) {
471507
throw new RuntimeException(e);
472508
}
473509
}

modules/openapi-generator/src/main/resources/Java/libraries/webclient/build.gradle.mustache

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,19 @@ if(hasProperty('target') && target == 'android') {
125125

126126
ext {
127127
{{#swagger1AnnotationLibrary}}
128-
swagger_annotations_version = "1.6.3"
128+
swagger_annotations_version = "1.6.16"
129129
{{/swagger1AnnotationLibrary}}
130130
{{#swagger2AnnotationLibrary}}
131-
swagger_annotations_version = "2.2.9"
131+
swagger_annotations_version = "2.2.43"
132132
{{/swagger2AnnotationLibrary}}
133133
{{#useJakartaEe}}
134-
spring_boot_version = "3.2.12"
135-
jakarta_annotation_version = "2.1.1"
134+
{{^useSpringBoot4}}
135+
spring_boot_version = "3.5.11"
136+
{{/useSpringBoot4}}
137+
{{#useSpringBoot4}}
138+
spring_boot_version = "4.0.3"
139+
{{/useSpringBoot4}}
140+
jakarta_annotation_version = "3.0.0"
136141
beanvalidation_version = "3.0.2"
137142
reactor_version = "3.5.12"
138143
reactor_netty_version = "1.2.8"
@@ -144,13 +149,18 @@ ext {
144149
reactor_version = "3.4.34"
145150
reactor_netty_version = "1.2.8"
146151
{{/useJakartaEe}}
147-
jackson_version = "2.19.2"
148-
jackson_databind_version = "2.19.2"
152+
{{#useJackson3}}
153+
jackson_version = "3.1.0"
154+
{{/useJackson3}}
155+
{{^useJackson3}}
156+
jackson_version = "2.21.1"
157+
{{/useJackson3}}
158+
jackson_annotations_version = "2.21"
149159
{{#openApiNullable}}
150160
jackson_databind_nullable_version = "0.2.9"
151161
{{/openApiNullable}}
152162
{{#joda}}
153-
jodatime_version = "2.9.9"
163+
jodatime_version = "2.14.0"
154164
{{/joda}}
155165
junit_version = "5.10.2"
156166
}
@@ -166,17 +176,18 @@ dependencies {
166176
implementation "io.projectreactor:reactor-core:$reactor_version"
167177
implementation "org.springframework.boot:spring-boot-starter-webflux:$spring_boot_version"
168178
implementation "io.projectreactor.netty:reactor-netty-http:$reactor_netty_version"
169-
implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version"
170-
implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
171-
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_databind_version"
172-
implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version"
179+
implementation "{{jacksonPackage}}.core:jackson-core:$jackson_version"
180+
implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_annotations_version"
181+
implementation "{{jacksonPackage}}.core:jackson-databind:$jackson_version"
173182
{{#openApiNullable}}
174183
implementation "org.openapitools:jackson-databind-nullable:$jackson_databind_nullable_version"
175184
{{/openApiNullable}}
176185
{{#joda}}
177186
implementation "joda-time:joda-time:$jodatime_version"
178187
{{/joda}}
188+
{{^useJackson3}}
179189
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version"
190+
{{/useJackson3}}
180191
implementation "jakarta.annotation:jakarta.annotation-api:$jakarta_annotation_version"
181192
testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version"
182193
}

modules/openapi-generator/src/main/resources/Java/libraries/webclient/model.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import java.io.Serializable;
2828
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
2929
import com.fasterxml.jackson.annotation.JsonTypeName;
3030
{{#withXml}}
31-
import com.fasterxml.jackson.dataformat.xml.annotation.*;
31+
import {{jacksonPackage}}.dataformat.xml.annotation.*;
3232
{{/withXml}}
3333
{{#vendorExtensions.x-has-readonly-properties}}
3434
import com.fasterxml.jackson.annotation.JsonCreator;

modules/openapi-generator/src/main/resources/Java/libraries/webclient/pom.mustache

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,20 @@
114114
</dependency>
115115

116116
<!-- JSON processing: jackson -->
117+
<dependency>
118+
<groupId>{{jacksonPackage}}.core</groupId>
119+
<artifactId>jackson-core</artifactId>
120+
<version>${jackson-version}</version>
121+
</dependency>
117122
<dependency>
118123
<groupId>com.fasterxml.jackson.core</groupId>
124+
<artifactId>jackson-annotations</artifactId>
125+
<version>${jackson-annotations-version}</version>
126+
</dependency>
127+
<dependency>
128+
<groupId>{{jacksonPackage}}.core</groupId>
119129
<artifactId>jackson-databind</artifactId>
120-
<version>${jackson-databind-version}</version>
130+
<version>${jackson-version}</version>
121131
</dependency>
122132
{{#openApiNullable}}
123133
<dependency>
@@ -127,14 +137,16 @@
127137
</dependency>
128138
{{/openApiNullable}}
129139

140+
{{^useJackson3}}
130141
<dependency>
131142
<groupId>com.fasterxml.jackson.datatype</groupId>
132143
<artifactId>jackson-datatype-jsr310</artifactId>
133144
<version>${jackson-version}</version>
134145
</dependency>
146+
{{/useJackson3}}
135147
{{#joda}}
136148
<dependency>
137-
<groupId>com.fasterxml.jackson.datatype</groupId>
149+
<groupId>{{jacksonPackage}}.datatype</groupId>
138150
<artifactId>jackson-datatype-joda</artifactId>
139151
<version>${jackson-version}</version>
140152
</dependency>
@@ -162,18 +174,27 @@
162174
<properties>
163175
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
164176
{{#swagger1AnnotationLibrary}}
165-
<swagger-annotations-version>1.6.6</swagger-annotations-version>
177+
<swagger-annotations-version>1.6.16</swagger-annotations-version>
166178
{{/swagger1AnnotationLibrary}}
167179
{{#swagger2AnnotationLibrary}}
168-
<swagger-annotations-version>2.2.15</swagger-annotations-version>
180+
<swagger-annotations-version>2.2.43</swagger-annotations-version>
169181
{{/swagger2AnnotationLibrary}}
170-
<jackson-version>2.19.2</jackson-version>
171-
<jackson-databind-version>2.19.2</jackson-databind-version>
182+
{{#useJackson3}}
183+
<jackson-version>3.1.0</jackson-version>
184+
{{/useJackson3}}
185+
{{^useJackson3}}
186+
<jackson-version>2.21.1</jackson-version>
187+
{{/useJackson3}}
172188
{{#openApiNullable}}
173189
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
174190
{{/openApiNullable}}
175191
{{#useJakartaEe}}
176-
<spring-boot-version>3.2.12</spring-boot-version>
192+
{{^useSpringBoot4}}
193+
<spring-boot-version>3.5.11</spring-boot-version>
194+
{{/useSpringBoot4}}
195+
{{#useSpringBoot4}}
196+
<spring-boot-version>4.0.3</spring-boot-version>
197+
{{/useSpringBoot4}}
177198
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
178199
<reactor-version>3.5.12</reactor-version>
179200
<reactor-netty-version>1.2.8</reactor-netty-version>
@@ -184,9 +205,10 @@
184205
<reactor-version>3.4.34</reactor-version>
185206
<reactor-netty-version>1.2.8</reactor-netty-version>
186207
{{/useJakartaEe}}
187-
<junit-version>5.10.2</junit-version>
208+
<jackson-annotations-version>2.21</jackson-annotations-version>
209+
<junit-version>5.14.3</junit-version>
188210
{{#joda}}
189-
<jodatime-version>2.9.9</jodatime-version>
211+
<jodatime-version>2.14.0</jodatime-version>
190212
{{/joda}}
191213
</properties>
192214
</project>

0 commit comments

Comments
 (0)