Skip to content

Commit 76a8dfd

Browse files
authored
[Java][okhttp-gson] Fix LocalDateTime Serialization (#24643)
* [Java][okhttp-gson] Fix `LocalDateTime` Serialization * generate samples * add test * fim pom sample * fix serializer logic per cubic comment * samples * update test * address cubic ApiClient feedback * samples
1 parent aa61616 commit 76a8dfd

34 files changed

Lines changed: 1123 additions & 1 deletion

File tree

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,17 @@ public class ApiClient {
523523
return this;
524524
}
525525

526+
/**
527+
* <p>Set LocalDateTimeFormat.</p>
528+
*
529+
* @param dateFormat a {@link java.time.format.DateTimeFormatter} object
530+
* @return a {@link {{invokerPackage}}.ApiClient} object
531+
*/
532+
public ApiClient setLocalDateTimeFormat(DateTimeFormatter dateFormat) {
533+
JSON.setLocalDateTimeFormat(dateFormat);
534+
return this;
535+
}
536+
526537
{{/jsr310}}
527538
/**
528539
* <p>Set LenientOnJson.</p>

modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/JSON.mustache

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ import java.text.ParseException;
3333
import java.text.ParsePosition;
3434
{{#jsr310}}
3535
import java.time.LocalDate;
36+
import java.time.LocalDateTime;
3637
import java.time.OffsetDateTime;
3738
import java.time.format.DateTimeFormatter;
39+
import java.time.format.DateTimeParseException;
3840
{{/jsr310}}
3941
import java.util.Date;
4042
import java.util.Locale;
@@ -59,6 +61,7 @@ public class JSON {
5961
{{#jsr310}}
6062
private static OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
6163
private static LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
64+
private static LocalDateTimeTypeAdapter localDateTimeTypeAdapter = new LocalDateTimeTypeAdapter();
6265
{{/jsr310}}
6366
private static ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter();
6467

@@ -125,6 +128,7 @@ public class JSON {
125128
{{#jsr310}}
126129
gsonBuilder.registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter);
127130
gsonBuilder.registerTypeAdapter(LocalDate.class, localDateTypeAdapter);
131+
gsonBuilder.registerTypeAdapter(LocalDateTime.class, localDateTimeTypeAdapter);
128132
{{/jsr310}}
129133
gsonBuilder.registerTypeAdapter(byte[].class, byteArrayAdapter);
130134
{{#models}}
@@ -431,6 +435,55 @@ public class JSON {
431435
}
432436
}
433437

438+
/**
439+
* Gson TypeAdapter for JSR310 LocalDateTime type
440+
*/
441+
public static class LocalDateTimeTypeAdapter extends TypeAdapter<LocalDateTime> {
442+
443+
private DateTimeFormatter formatter;
444+
445+
public LocalDateTimeTypeAdapter() {
446+
this(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
447+
}
448+
449+
public LocalDateTimeTypeAdapter(DateTimeFormatter formatter) {
450+
this.formatter = formatter;
451+
}
452+
453+
public void setFormat(DateTimeFormatter dateFormat) {
454+
this.formatter = dateFormat;
455+
}
456+
457+
@Override
458+
public void write(JsonWriter out, LocalDateTime date) throws IOException {
459+
if (date == null) {
460+
out.nullValue();
461+
} else {
462+
out.value(formatter.format(date));
463+
}
464+
}
465+
466+
@Override
467+
public LocalDateTime read(JsonReader in) throws IOException {
468+
switch (in.peek()) {
469+
case NULL:
470+
in.nextNull();
471+
return null;
472+
default:
473+
String date = in.nextString();
474+
try {
475+
return LocalDateTime.parse(date, formatter);
476+
} catch (DateTimeParseException e) {
477+
if (date.length() > 10 && date.charAt(10) == ' ') {
478+
date = date.substring(0, 10) + 'T' + date.substring(11);
479+
return LocalDateTime.parse(date, formatter);
480+
}
481+
throw e;
482+
}
483+
}
484+
}
485+
}
486+
434487
public static void setOffsetDateTimeFormat(DateTimeFormatter dateFormat) {
435488
offsetDateTimeTypeAdapter.setFormat(dateFormat);
436489
}
@@ -439,6 +492,10 @@ public class JSON {
439492
localDateTypeAdapter.setFormat(dateFormat);
440493
}
441494

495+
public static void setLocalDateTimeFormat(DateTimeFormatter dateFormat) {
496+
localDateTimeTypeAdapter.setFormat(dateFormat);
497+
}
498+
442499
{{/jsr310}}
443500
/**
444501
* Gson TypeAdapter for java.sql.Date type

samples/client/echo_api/java/okhttp-gson-user-defined-templates/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,17 @@ public ApiClient setLocalDateFormat(DateTimeFormatter dateFormat) {
453453
return this;
454454
}
455455

456+
/**
457+
* <p>Set LocalDateTimeFormat.</p>
458+
*
459+
* @param dateFormat a {@link java.time.format.DateTimeFormatter} object
460+
* @return a {@link org.openapitools.client.ApiClient} object
461+
*/
462+
public ApiClient setLocalDateTimeFormat(DateTimeFormatter dateFormat) {
463+
JSON.setLocalDateTimeFormat(dateFormat);
464+
return this;
465+
}
466+
456467
/**
457468
* <p>Set LenientOnJson.</p>
458469
*

samples/client/echo_api/java/okhttp-gson-user-defined-templates/src/main/java/org/openapitools/client/JSON.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@
3636
import java.text.ParseException;
3737
import java.text.ParsePosition;
3838
import java.time.LocalDate;
39+
import java.time.LocalDateTime;
3940
import java.time.OffsetDateTime;
4041
import java.time.format.DateTimeFormatter;
42+
import java.time.format.DateTimeParseException;
4143
import java.util.Date;
4244
import java.util.Locale;
4345
import java.util.Map;
@@ -56,6 +58,7 @@ public class JSON {
5658
private static SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter();
5759
private static OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
5860
private static LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
61+
private static LocalDateTimeTypeAdapter localDateTimeTypeAdapter = new LocalDateTimeTypeAdapter();
5962
private static ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter();
6063

6164
@SuppressWarnings("unchecked")
@@ -95,6 +98,7 @@ private static Class getClassByDiscriminator(Map classByDiscriminatorValue, Stri
9598
gsonBuilder.registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter);
9699
gsonBuilder.registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter);
97100
gsonBuilder.registerTypeAdapter(LocalDate.class, localDateTypeAdapter);
101+
gsonBuilder.registerTypeAdapter(LocalDateTime.class, localDateTimeTypeAdapter);
98102
gsonBuilder.registerTypeAdapter(byte[].class, byteArrayAdapter);
99103
gsonBuilder.registerTypeAdapterFactory(new org.openapitools.client.model.Category.CustomTypeAdapterFactory());
100104
gsonBuilder.registerTypeAdapterFactory(new org.openapitools.client.model.ModelApiResponse.CustomTypeAdapterFactory());
@@ -302,6 +306,55 @@ public LocalDate read(JsonReader in) throws IOException {
302306
}
303307
}
304308

309+
/**
310+
* Gson TypeAdapter for JSR310 LocalDateTime type
311+
*/
312+
public static class LocalDateTimeTypeAdapter extends TypeAdapter<LocalDateTime> {
313+
314+
private DateTimeFormatter formatter;
315+
316+
public LocalDateTimeTypeAdapter() {
317+
this(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
318+
}
319+
320+
public LocalDateTimeTypeAdapter(DateTimeFormatter formatter) {
321+
this.formatter = formatter;
322+
}
323+
324+
public void setFormat(DateTimeFormatter dateFormat) {
325+
this.formatter = dateFormat;
326+
}
327+
328+
@Override
329+
public void write(JsonWriter out, LocalDateTime date) throws IOException {
330+
if (date == null) {
331+
out.nullValue();
332+
} else {
333+
out.value(formatter.format(date));
334+
}
335+
}
336+
337+
@Override
338+
public LocalDateTime read(JsonReader in) throws IOException {
339+
switch (in.peek()) {
340+
case NULL:
341+
in.nextNull();
342+
return null;
343+
default:
344+
String date = in.nextString();
345+
try {
346+
return LocalDateTime.parse(date, formatter);
347+
} catch (DateTimeParseException e) {
348+
if (date.length() > 10 && date.charAt(10) == ' ') {
349+
date = date.substring(0, 10) + 'T' + date.substring(11);
350+
return LocalDateTime.parse(date, formatter);
351+
}
352+
throw e;
353+
}
354+
}
355+
}
356+
}
357+
305358
public static void setOffsetDateTimeFormat(DateTimeFormatter dateFormat) {
306359
offsetDateTimeTypeAdapter.setFormat(dateFormat);
307360
}
@@ -310,6 +363,10 @@ public static void setLocalDateFormat(DateTimeFormatter dateFormat) {
310363
localDateTypeAdapter.setFormat(dateFormat);
311364
}
312365

366+
public static void setLocalDateTimeFormat(DateTimeFormatter dateFormat) {
367+
localDateTimeTypeAdapter.setFormat(dateFormat);
368+
}
369+
313370
/**
314371
* Gson TypeAdapter for java.sql.Date type
315372
* If the dateFormat is null, a simple "yyyy-MM-dd" format will be used

samples/client/echo_api/java/okhttp-gson/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,17 @@ public ApiClient setLocalDateFormat(DateTimeFormatter dateFormat) {
381381
return this;
382382
}
383383

384+
/**
385+
* <p>Set LocalDateTimeFormat.</p>
386+
*
387+
* @param dateFormat a {@link java.time.format.DateTimeFormatter} object
388+
* @return a {@link org.openapitools.client.ApiClient} object
389+
*/
390+
public ApiClient setLocalDateTimeFormat(DateTimeFormatter dateFormat) {
391+
JSON.setLocalDateTimeFormat(dateFormat);
392+
return this;
393+
}
394+
384395
/**
385396
* <p>Set LenientOnJson.</p>
386397
*

samples/client/echo_api/java/okhttp-gson/src/main/java/org/openapitools/client/JSON.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@
3636
import java.text.ParseException;
3737
import java.text.ParsePosition;
3838
import java.time.LocalDate;
39+
import java.time.LocalDateTime;
3940
import java.time.OffsetDateTime;
4041
import java.time.format.DateTimeFormatter;
42+
import java.time.format.DateTimeParseException;
4143
import java.util.Date;
4244
import java.util.Locale;
4345
import java.util.Map;
@@ -56,6 +58,7 @@ public class JSON {
5658
private static SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter();
5759
private static OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
5860
private static LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
61+
private static LocalDateTimeTypeAdapter localDateTimeTypeAdapter = new LocalDateTimeTypeAdapter();
5962
private static ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter();
6063

6164
@SuppressWarnings("unchecked")
@@ -95,6 +98,7 @@ private static Class getClassByDiscriminator(Map classByDiscriminatorValue, Stri
9598
gsonBuilder.registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter);
9699
gsonBuilder.registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter);
97100
gsonBuilder.registerTypeAdapter(LocalDate.class, localDateTypeAdapter);
101+
gsonBuilder.registerTypeAdapter(LocalDateTime.class, localDateTimeTypeAdapter);
98102
gsonBuilder.registerTypeAdapter(byte[].class, byteArrayAdapter);
99103
gsonBuilder.registerTypeAdapterFactory(new org.openapitools.client.model.Bird.CustomTypeAdapterFactory());
100104
gsonBuilder.registerTypeAdapterFactory(new org.openapitools.client.model.Category.CustomTypeAdapterFactory());
@@ -306,6 +310,55 @@ public LocalDate read(JsonReader in) throws IOException {
306310
}
307311
}
308312

313+
/**
314+
* Gson TypeAdapter for JSR310 LocalDateTime type
315+
*/
316+
public static class LocalDateTimeTypeAdapter extends TypeAdapter<LocalDateTime> {
317+
318+
private DateTimeFormatter formatter;
319+
320+
public LocalDateTimeTypeAdapter() {
321+
this(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
322+
}
323+
324+
public LocalDateTimeTypeAdapter(DateTimeFormatter formatter) {
325+
this.formatter = formatter;
326+
}
327+
328+
public void setFormat(DateTimeFormatter dateFormat) {
329+
this.formatter = dateFormat;
330+
}
331+
332+
@Override
333+
public void write(JsonWriter out, LocalDateTime date) throws IOException {
334+
if (date == null) {
335+
out.nullValue();
336+
} else {
337+
out.value(formatter.format(date));
338+
}
339+
}
340+
341+
@Override
342+
public LocalDateTime read(JsonReader in) throws IOException {
343+
switch (in.peek()) {
344+
case NULL:
345+
in.nextNull();
346+
return null;
347+
default:
348+
String date = in.nextString();
349+
try {
350+
return LocalDateTime.parse(date, formatter);
351+
} catch (DateTimeParseException e) {
352+
if (date.length() > 10 && date.charAt(10) == ' ') {
353+
date = date.substring(0, 10) + 'T' + date.substring(11);
354+
return LocalDateTime.parse(date, formatter);
355+
}
356+
throw e;
357+
}
358+
}
359+
}
360+
}
361+
309362
public static void setOffsetDateTimeFormat(DateTimeFormatter dateFormat) {
310363
offsetDateTimeTypeAdapter.setFormat(dateFormat);
311364
}
@@ -314,6 +367,10 @@ public static void setLocalDateFormat(DateTimeFormatter dateFormat) {
314367
localDateTypeAdapter.setFormat(dateFormat);
315368
}
316369

370+
public static void setLocalDateTimeFormat(DateTimeFormatter dateFormat) {
371+
localDateTimeTypeAdapter.setFormat(dateFormat);
372+
}
373+
317374
/**
318375
* Gson TypeAdapter for java.sql.Date type
319376
* If the dateFormat is null, a simple "yyyy-MM-dd" format will be used

samples/client/others/java/okhttp-gson-oneOf-array/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,17 @@ public ApiClient setLocalDateFormat(DateTimeFormatter dateFormat) {
377377
return this;
378378
}
379379

380+
/**
381+
* <p>Set LocalDateTimeFormat.</p>
382+
*
383+
* @param dateFormat a {@link java.time.format.DateTimeFormatter} object
384+
* @return a {@link org.openapitools.client.ApiClient} object
385+
*/
386+
public ApiClient setLocalDateTimeFormat(DateTimeFormatter dateFormat) {
387+
JSON.setLocalDateTimeFormat(dateFormat);
388+
return this;
389+
}
390+
380391
/**
381392
* <p>Set LenientOnJson.</p>
382393
*

0 commit comments

Comments
 (0)