Skip to content

Commit 54ccecd

Browse files
committed
Add jackson3 support for webclient
# Conflicts: # docs/generators/java.md # modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java # modules/openapi-generator/src/main/resources/Java/RFC3339DateFormat.mustache
1 parent 68dc149 commit 54ccecd

File tree

215 files changed

+26284
-106
lines changed

Some content is hidden

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

215 files changed

+26284
-106
lines changed
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/webclient-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-jackson3
8+
hideGenerationTimestamp: "true"
9+
useJackson3: true
10+
useJakartaEe: true

docs/generators/java-microprofile.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
9999
|useGzipFeature|Send gzip-encoded requests| |false|
100100
|useJackson3|Set it in order to use jackson 3 dependencies (only allowed when `useSpringBoot4` is set and incompatible with `openApiNullable`).| |false|
101101
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
102+
|useJackson3|Use Jackson 3 instead of Jackson 2 for JSON processing. Only supported for 'native' and 'webclient' libraries.| |false|
102103
|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|
103104
|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|
104105
|usePlayWS|Use Play! Async HTTP client (Play WS API)| |false|

docs/generators/java.md

Lines changed: 97 additions & 97 deletions
Large diffs are not rendered by default.

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ public JavaClientCodegen() {
307307
serializationLibrary.setEnum(serializationOptions);
308308
cliOptions.add(serializationLibrary);
309309
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
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+"`). For 'java' generator: only supported for 'native' and 'webclient' libraries.", useJackson3)); // Ensure the OAS 3.x discriminator mappings include any descendent schemas that allOf
311311
// inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values,
312312
// and the discriminator mapping schemas in the OAS document.
313313
this.setLegacyDiscriminatorBehavior(false);
@@ -385,9 +385,19 @@ public void processOpts() {
385385
throw new IllegalArgumentException("openApiNullable cannot be set with useJackson3");
386386
}
387387

388-
if(this.useJackson3){
388+
// TODO
389+
// if (useJackson3) {
390+
// if (!libNative && !libWebClient) {
391+
// LOGGER.warn("useJackson3 option is currently only supported for library=native|webclient. Ignoring useJackson3.");
392+
// useJackson3 = false;
393+
// additionalProperties.put(USE_JACKSON_3, false);
394+
// }
395+
// }
396+
397+
if (isUseJackson3()) {
389398
this.applyJackson3Package();
390-
} else {
399+
}
400+
else {
391401
this.applyJackson2Package();
392402
}
393403

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

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

4+
{{^useJackson3}}
45
import java.io.IOException;
6+
{{/useJackson3}}
57
import java.time.Instant;
68
import java.time.OffsetDateTime;
79
import java.time.ZoneId;
@@ -12,10 +14,19 @@ import java.time.temporal.TemporalAccessor;
1214
import java.util.function.BiFunction;
1315
import java.util.function.Function;
1416

17+
{{^useJackson3}}
1518
import com.fasterxml.jackson.core.JsonParser;
1619
import com.fasterxml.jackson.databind.DeserializationContext;
1720
import com.fasterxml.jackson.datatype.jsr310.JavaTimeFeature;
1821
import com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer;
22+
{{/useJackson3}}
23+
{{#useJackson3}}
24+
import tools.jackson.core.JacksonException;
25+
import tools.jackson.core.JsonParser;
26+
import tools.jackson.databind.DeserializationContext;
27+
import tools.jackson.datatype.jsr310.JavaTimeFeature;
28+
import tools.jackson.datatype.jsr310.deser.InstantDeserializer;
29+
{{/useJackson3}}
1930

2031
{{>generatedAnnotation}}
2132

@@ -84,7 +95,7 @@ public class RFC3339InstantDeserializer<T extends Temporal> extends InstantDeser
8495
}
8596

8697
@Override
87-
protected T _fromString(JsonParser p, DeserializationContext ctxt, String string0) throws IOException {
98+
protected T _fromString(JsonParser p, DeserializationContext ctxt, String string0) throws {{^useJackson3}}IOException{{/useJackson3}}{{#useJackson3}}JacksonException{{/useJackson3}} {
8899
return super._fromString(p, ctxt, string0.replace( ' ', 'T' ));
89100
}
90101
}

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@ import java.time.Instant;
55
import java.time.OffsetDateTime;
66
import java.time.ZonedDateTime;
77

8+
{{^useJackson3}}
89
import com.fasterxml.jackson.databind.module.SimpleModule;
910
import com.fasterxml.jackson.databind.Module.SetupContext;
11+
{{/useJackson3}}
12+
{{#useJackson3}}
13+
import tools.jackson.databind.module.SimpleModule;
14+
{{/useJackson3}}
1015

1116
{{>generatedAnnotation}}
1217

@@ -15,8 +20,14 @@ public class RFC3339JavaTimeModule extends SimpleModule {
1520
1621
public RFC3339JavaTimeModule() {
1722
super("RFC3339JavaTimeModule");
23+
{{#useJackson3}}
24+
addDeserializer(Instant.class, RFC3339InstantDeserializer.INSTANT);
25+
addDeserializer(OffsetDateTime.class, RFC3339InstantDeserializer.OFFSET_DATE_TIME);
26+
addDeserializer(ZonedDateTime.class, RFC3339InstantDeserializer.ZONED_DATE_TIME);
27+
{{/useJackson3}}
1828
}
1929

30+
{{^useJackson3}}
2031
@Override
2132
public void setupModule(SetupContext context) {
2233
super.setupModule(context);
@@ -25,5 +36,6 @@ public class RFC3339JavaTimeModule extends SimpleModule {
2536
addDeserializer(OffsetDateTime.class, RFC3339InstantDeserializer.OFFSET_DATE_TIME);
2637
addDeserializer(ZonedDateTime.class, RFC3339InstantDeserializer.ZONED_DATE_TIME);
2738
}
39+
{{/useJackson3}}
2840

29-
}
41+
}

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

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,24 @@
22

33
package {{invokerPackage}};
44

5+
{{^useJackson3}}
56
import com.fasterxml.jackson.core.JsonProcessingException;
67
import com.fasterxml.jackson.databind.DeserializationFeature;
78
import com.fasterxml.jackson.databind.ObjectMapper;
89
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
10+
{{/useJackson3}}
11+
{{#useJackson3}}
12+
import tools.jackson.databind.DeserializationFeature;
13+
import tools.jackson.databind.JsonMapper;
14+
import tools.jackson.databind.ObjectMapper;
15+
{{/useJackson3}}
916
{{#openApiNullable}}
17+
{{^useJackson3}}
1018
import org.openapitools.jackson.nullable.JsonNullableModule;
19+
{{/useJackson3}}
20+
{{#useJackson3}}
21+
import org.openapitools.jackson.nullable.JsonNullableJackson3Module;
22+
{{/useJackson3}}
1123
{{/openApiNullable}}
1224
{{#generateClientAsBean}}
1325
import org.springframework.beans.factory.annotation.Autowired;
@@ -27,8 +39,14 @@ import org.springframework.http.client.ClientHttpRequestExecution;
2739
import org.springframework.http.client.ClientHttpRequestInterceptor;
2840
import org.springframework.http.client.ClientHttpResponse;
2941
import org.springframework.http.client.reactive.ClientHttpRequest;
42+
{{^useJackson3}}
3043
import org.springframework.http.codec.json.Jackson2JsonDecoder;
3144
import org.springframework.http.codec.json.Jackson2JsonEncoder;
45+
{{/useJackson3}}
46+
{{#useJackson3}}
47+
import org.springframework.http.codec.json.JacksonJsonDecoder;
48+
import org.springframework.http.codec.json.JacksonJsonEncoder;
49+
{{/useJackson3}}
3250
{{#generateClientAsBean}}
3351
import org.springframework.stereotype.Component;
3452
{{/generateClientAsBean}}
@@ -130,11 +148,11 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
130148
}
131149

132150
public ApiClient(ObjectMapper mapper, DateFormat format) {
133-
this(buildWebClient(mapper.copy()), format);
151+
this(buildWebClient(mapper{{^useJackson3}}.copy(){{/useJackson3}}), format);
134152
}
135153

136154
public ApiClient(WebClient webClient, ObjectMapper mapper, DateFormat format) {
137-
this(Optional.ofNullable(webClient).orElseGet(() -> buildWebClient(mapper.copy())), format);
155+
this(Optional.ofNullable(webClient).orElseGet(() -> buildWebClient(mapper{{^useJackson3}}.copy(){{/useJackson3}})), format);
138156
}
139157

140158
protected ApiClient(WebClient webClient, DateFormat format) {
@@ -154,6 +172,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
154172
if (null == dateFormat) {
155173
dateFormat = createDefaultDateFormat();
156174
}
175+
{{^useJackson3}}
157176
ObjectMapper mapper = new ObjectMapper();
158177
mapper.setDateFormat(dateFormat);
159178
mapper.registerModule(new JavaTimeModule());
@@ -163,6 +182,17 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
163182
mapper.registerModule(jnm);
164183
{{/openApiNullable}}
165184
return mapper;
185+
{{/useJackson3}}
186+
{{#useJackson3}}
187+
return JsonMapper
188+
.builder()
189+
.setDateFormat(dateFormat)
190+
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, {{failOnUnknownProperties}})
191+
{{#openApiNullable}}
192+
.addModule(new JsonNullableJackson3Module())
193+
{{/openApiNullable}}
194+
.build();
195+
{{/useJackson3}}
166196
}
167197

168198
protected void init() {
@@ -185,8 +215,14 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
185215
ExchangeStrategies strategies = ExchangeStrategies
186216
.builder()
187217
.codecs(clientDefaultCodecsConfigurer -> {
218+
{{^useJackson3}}
188219
clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(mapper, MediaType.APPLICATION_JSON));
189220
clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(mapper, MediaType.APPLICATION_JSON));
221+
{{/useJackson3}}
222+
{{#useJackson3}}
223+
clientDefaultCodecsConfigurer.defaultCodecs().jacksonJsonEncoder(new JacksonJsonEncoder(mapper));
224+
clientDefaultCodecsConfigurer.defaultCodecs().jacksonJsonDecoder(new JacksonJsonDecoder(mapper));
225+
{{/useJackson3}}
190226
}).build();
191227
WebClient.Builder webClientBuilder = WebClient.builder().exchangeStrategies(strategies);
192228
return webClientBuilder;
@@ -456,20 +492,30 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
456492
if (value instanceof Collection) {
457493
valueCollection = (Collection<?>) value;
458494
} else {
495+
{{^useJackson3}}
459496
try {
460497
return parameterToMultiValueMap(collectionFormat, name, objectMapper.writeValueAsString(value));
461498
} catch (JsonProcessingException e) {
462499
throw new RuntimeException(e);
463500
}
501+
{{/useJackson3}}
502+
{{#useJackson3}}
503+
return parameterToMultiValueMap(collectionFormat, name, objectMapper.writeValueAsString(value));
504+
{{/useJackson3}}
464505
}
465506

466507
List<String> values = new ArrayList<>();
467508
for(Object o : valueCollection) {
509+
{{^useJackson3}}
468510
try {
469511
values.add(objectMapper.writeValueAsString(o));
470512
} catch (JsonProcessingException e) {
471513
throw new RuntimeException(e);
472514
}
515+
{{/useJackson3}}
516+
{{#useJackson3}}
517+
values.add(objectMapper.writeValueAsString(o));
518+
{{/useJackson3}}
473519
}
474520
return parameterToMultiValueMap(collectionFormat, name, "[" + StringUtils.collectionToDelimitedString(values, collectionFormat.separator) + "]");
475521
}

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,20 +131,37 @@ ext {
131131
swagger_annotations_version = "2.2.9"
132132
{{/swagger2AnnotationLibrary}}
133133
{{#useJakartaEe}}
134+
{{^useJackson3}}
134135
spring_boot_version = "3.2.12"
136+
{{/useJackson3}}
137+
{{#useJackson3}}
138+
spring_boot_version = "4.0.3"
139+
{{/useJackson3}}
135140
jakarta_annotation_version = "2.1.1"
136141
beanvalidation_version = "3.0.2"
137142
reactor_version = "3.5.12"
138143
reactor_netty_version = "1.2.8"
139144
{{/useJakartaEe}}
140145
{{^useJakartaEe}}
146+
{{^useJackson3}}
141147
spring_boot_version = "2.7.17"
148+
{{/useJackson3}}
149+
{{#useJackson3}}
150+
spring_boot_version = "4.0.3"
151+
{{/useJackson3}}
142152
jakarta_annotation_version = "1.3.5"
143153
beanvalidation_version = "2.0.2"
144154
reactor_version = "3.4.34"
145155
reactor_netty_version = "1.2.8"
146156
{{/useJakartaEe}}
157+
{{^useJackson3}}
147158
jackson_version = "2.19.2"
159+
{{/useJackson3}}
160+
{{#useJackson3}}
161+
jackson_version = "3.1.0"
162+
jackson_databind_version = "3.1.0"
163+
jackson_annotations_version = "2.19.2"
164+
{{/useJackson3}}
148165
jackson_databind_version = "2.19.2"
149166
{{#openApiNullable}}
150167
jackson_databind_nullable_version = "0.2.9"
@@ -166,17 +183,25 @@ dependencies {
166183
implementation "io.projectreactor:reactor-core:$reactor_version"
167184
implementation "org.springframework.boot:spring-boot-starter-webflux:$spring_boot_version"
168185
implementation "io.projectreactor.netty:reactor-netty-http:$reactor_netty_version"
186+
{{^useJackson3}}
169187
implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version"
170-
implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
171188
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_databind_version"
172189
implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version"
190+
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version"
191+
implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
192+
{{/useJackson3}}
193+
{{#useJackson3}}
194+
implementation "tools.jackson.core:jackson-core:$jackson_version"
195+
implementation "tools.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version"
196+
implementation "tools.jackson.core:jackson-databind:$jackson_databind_version"
197+
implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_annotations_version"
198+
{{/useJackson3}}
173199
{{#openApiNullable}}
174200
implementation "org.openapitools:jackson-databind-nullable:$jackson_databind_nullable_version"
175201
{{/openApiNullable}}
176202
{{#joda}}
177203
implementation "joda-time:joda-time:$jodatime_version"
178204
{{/joda}}
179-
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version"
180205
implementation "jakarta.annotation:jakarta.annotation-api:$jakarta_annotation_version"
181206
testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version"
182207
}

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,20 @@
114114
</dependency>
115115

116116
<!-- JSON processing: jackson -->
117+
{{^useJackson3}}
117118
<dependency>
118119
<groupId>com.fasterxml.jackson.core</groupId>
119120
<artifactId>jackson-databind</artifactId>
120121
<version>${jackson-databind-version}</version>
121122
</dependency>
123+
{{/useJackson3}}
124+
{{#useJackson3}}
125+
<dependency>
126+
<groupId>tools.jackson.core</groupId>
127+
<artifactId>jackson-databind</artifactId>
128+
<version>${jackson-databind-version}</version>
129+
</dependency>
130+
{{/useJackson3}}
122131
{{#openApiNullable}}
123132
<dependency>
124133
<groupId>org.openapitools</groupId>
@@ -127,14 +136,21 @@
127136
</dependency>
128137
{{/openApiNullable}}
129138

139+
{{^useJackson3}}
130140
<dependency>
131141
<groupId>com.fasterxml.jackson.datatype</groupId>
132142
<artifactId>jackson-datatype-jsr310</artifactId>
133143
<version>${jackson-version}</version>
134144
</dependency>
145+
{{/useJackson3}}
135146
{{#joda}}
136147
<dependency>
148+
{{^useJackson3}}
137149
<groupId>com.fasterxml.jackson.datatype</groupId>
150+
{{/useJackson3}}
151+
{{#useJackson3}}
152+
<groupId>tools.jackson.datatype</groupId>
153+
{{/useJackson3}}
138154
<artifactId>jackson-datatype-joda</artifactId>
139155
<version>${jackson-version}</version>
140156
</dependency>
@@ -167,19 +183,35 @@
167183
{{#swagger2AnnotationLibrary}}
168184
<swagger-annotations-version>2.2.15</swagger-annotations-version>
169185
{{/swagger2AnnotationLibrary}}
186+
{{^useJackson3}}
170187
<jackson-version>2.19.2</jackson-version>
171188
<jackson-databind-version>2.19.2</jackson-databind-version>
189+
{{/useJackson3}}
190+
{{#useJackson3}}
191+
<jackson-version>3.1.0</jackson-version>
192+
<jackson-databind-version>3.1.0</jackson-databind-version>
193+
{{/useJackson3}}
172194
{{#openApiNullable}}
173195
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
174196
{{/openApiNullable}}
175197
{{#useJakartaEe}}
198+
{{^useJackson3}}
176199
<spring-boot-version>3.2.12</spring-boot-version>
200+
{{/useJackson3}}
201+
{{#useJackson3}}
202+
<spring-boot-version>4.0.3</spring-boot-version>
203+
{{/useJackson3}}
177204
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
178205
<reactor-version>3.5.12</reactor-version>
179206
<reactor-netty-version>1.2.8</reactor-netty-version>
180207
{{/useJakartaEe}}
181208
{{^useJakartaEe}}
209+
{{^useJackson3}}
182210
<spring-boot-version>2.7.17</spring-boot-version>
211+
{{/useJackson3}}
212+
{{#useJackson3}}
213+
<spring-boot-version>4.0.3</spring-boot-version>
214+
{{/useJackson3}}
183215
<jakarta-annotation-version>1.3.5</jakarta-annotation-version>
184216
<reactor-version>3.4.34</reactor-version>
185217
<reactor-netty-version>1.2.8</reactor-netty-version>

0 commit comments

Comments
 (0)