add java.util.Date ISO-8601 GSON type adapter (FINERACT-926) (#816)

* minor clean-up in existing JsonSerializer implementations (FINERACT-926)

* centralize registration of GSON type adapters (FINERACT-926)

* add java.util.Date ISO-8601 GSON type adapter (FINERACT-926)
This commit is contained in:
Michael Vorburger ⛑️
2020-05-08 19:56:19 +01:00
committed by GitHub
parent f049892600
commit bee3fb7ce5
8 changed files with 73 additions and 72 deletions
@@ -0,0 +1,46 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.api;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import java.time.format.DateTimeFormatter;
import java.util.Date;
/**
* GSON Serializer for JUL Dates (java.util.Date) in ISO-8601 format using {@link DateTimeFormatter#ISO_INSTANT} (see FINERACT-926).
*
* @author Michael Vorburger.ch
*/
public class DateAdapter implements JsonSerializer<Date> {
private final static DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
@Override
@SuppressWarnings("unused")
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
if (src == null) {
return null;
}
return new JsonPrimitive(formatter.format(src.toInstant()));
}
}
@@ -26,15 +26,14 @@ import java.lang.reflect.Type;
import org.joda.time.DateTime; import org.joda.time.DateTime;
/** /**
* Serializer for joda time {@link DateTime} that returns date as long to match * Serializer for Joda Time {@link DateTime} that returns the date as long to
* previous functionality. * match previous (Jackson) functionality.
*/ */
public class JodaDateTimeAdapter implements JsonSerializer<DateTime> { public class JodaDateTimeAdapter implements JsonSerializer<DateTime> {
@SuppressWarnings("unused")
@Override @Override
@SuppressWarnings("unused")
public JsonElement serialize(final DateTime src, final Type typeOfSrc, final JsonSerializationContext context) { public JsonElement serialize(final DateTime src, final Type typeOfSrc, final JsonSerializationContext context) {
JsonElement element = null; JsonElement element = null;
if (src != null) { if (src != null) {
element = new JsonPrimitive(src.getMillis()); element = new JsonPrimitive(src.getMillis());
@@ -27,15 +27,14 @@ import java.lang.reflect.Type;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
/** /**
* Serializer for joda time {@link LocalDate} that returns date in array format * Serializer for Joda Time {@link LocalDate} that returns the date in array format
* to match previous jackson functionality. * to match previous Jackson functionality.
*/ */
public class JodaLocalDateAdapter implements JsonSerializer<LocalDate> { public class JodaLocalDateAdapter implements JsonSerializer<LocalDate> {
@SuppressWarnings("unused")
@Override @Override
@SuppressWarnings("unused")
public JsonElement serialize(final LocalDate src, final Type typeOfSrc, final JsonSerializationContext context) { public JsonElement serialize(final LocalDate src, final Type typeOfSrc, final JsonSerializationContext context) {
JsonArray array = null; JsonArray array = null;
if (src != null) { if (src != null) {
array = new JsonArray(); array = new JsonArray();
@@ -43,7 +42,6 @@ public class JodaLocalDateAdapter implements JsonSerializer<LocalDate> {
array.add(new JsonPrimitive(src.getMonthOfYear())); array.add(new JsonPrimitive(src.getMonthOfYear()));
array.add(new JsonPrimitive(src.getDayOfMonth())); array.add(new JsonPrimitive(src.getDayOfMonth()));
} }
return array; return array;
} }
} }
@@ -27,22 +27,20 @@ import java.lang.reflect.Type;
import org.joda.time.MonthDay; import org.joda.time.MonthDay;
/** /**
* Serializer for joda time {@link MonthDay} that returns date in array format * Serializer for Joda Time {@link MonthDay} that returns the date in array format
* to match previous jackson functionality. * to match previous Jackson functionality.
*/ */
public class JodaMonthDayAdapter implements JsonSerializer<MonthDay> { public class JodaMonthDayAdapter implements JsonSerializer<MonthDay> {
@SuppressWarnings("unused")
@Override @Override
@SuppressWarnings("unused")
public JsonElement serialize(final MonthDay src, final Type typeOfSrc, final JsonSerializationContext context) { public JsonElement serialize(final MonthDay src, final Type typeOfSrc, final JsonSerializationContext context) {
JsonArray array = null; JsonArray array = null;
if (src != null) { if (src != null) {
array = new JsonArray(); array = new JsonArray();
array.add(new JsonPrimitive(src.getMonthOfYear())); array.add(new JsonPrimitive(src.getMonthOfYear()));
array.add(new JsonPrimitive(src.getDayOfMonth())); array.add(new JsonPrimitive(src.getDayOfMonth()));
} }
return array; return array;
} }
} }
@@ -20,23 +20,12 @@ package org.apache.fineract.infrastructure.core.serialization;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import org.apache.fineract.infrastructure.core.api.JodaDateTimeAdapter;
import org.apache.fineract.infrastructure.core.api.JodaLocalDateAdapter;
import org.apache.fineract.infrastructure.core.api.JodaMonthDayAdapter;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.MonthDay;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* <p> * A Google GSON implementation of contract.
* A google gson implementation of
* contract.
* </p>
* *
* <p>
* It serializes all fields of any Java {@link Object} passed to it. * It serializes all fields of any Java {@link Object} passed to it.
* </p>
*/ */
@Component @Component
public final class CommandProcessingResultJsonSerializer { public final class CommandProcessingResultJsonSerializer {
@@ -45,11 +34,8 @@ public final class CommandProcessingResultJsonSerializer {
public CommandProcessingResultJsonSerializer() { public CommandProcessingResultJsonSerializer() {
final GsonBuilder builder = new GsonBuilder(); final GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(LocalDate.class, new JodaLocalDateAdapter()); GoogleGsonSerializerHelper.registerTypeAdapters(builder);
builder.registerTypeAdapter(DateTime.class, new JodaDateTimeAdapter());
builder.registerTypeAdapter(MonthDay.class, new JodaMonthDayAdapter());
builder.serializeNulls(); builder.serializeNulls();
this.gson = builder.create(); this.gson = builder.create();
} }
@@ -20,23 +20,12 @@ package org.apache.fineract.infrastructure.core.serialization;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import org.apache.fineract.infrastructure.core.api.JodaDateTimeAdapter;
import org.apache.fineract.infrastructure.core.api.JodaLocalDateAdapter;
import org.apache.fineract.infrastructure.core.api.JodaMonthDayAdapter;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.MonthDay;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* <p> * A Google GSON implementation of contract.
* A google gson implementation of
* contract.
* </p>
* *
* <p>
* It serializes all fields of any Java {@link Object} passed to it. * It serializes all fields of any Java {@link Object} passed to it.
* </p>
*/ */
@Component @Component
public final class ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson { public final class ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson {
@@ -45,9 +34,7 @@ public final class ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson {
public ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson() { public ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson() {
final GsonBuilder builder = new GsonBuilder(); final GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(LocalDate.class, new JodaLocalDateAdapter()); GoogleGsonSerializerHelper.registerTypeAdapters(builder);
builder.registerTypeAdapter(DateTime.class, new JodaDateTimeAdapter());
builder.registerTypeAdapter(MonthDay.class, new JodaMonthDayAdapter());
this.gson = builder.create(); this.gson = builder.create();
} }
@@ -20,23 +20,12 @@ package org.apache.fineract.infrastructure.core.serialization;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import org.apache.fineract.infrastructure.core.api.JodaDateTimeAdapter;
import org.apache.fineract.infrastructure.core.api.JodaLocalDateAdapter;
import org.apache.fineract.infrastructure.core.api.JodaMonthDayAdapter;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.MonthDay;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* <p> * A Google GSON implementation of contract.
* A google gson implementation of
* contract.
* </p>
* *
* <p>
* It serializes all fields of any Java {@link Object} passed to it. * It serializes all fields of any Java {@link Object} passed to it.
* </p>
*/ */
@Component @Component
public final class ExcludeNothingWithPrettyPrintingOnJsonSerializerGoogleGson { public final class ExcludeNothingWithPrettyPrintingOnJsonSerializerGoogleGson {
@@ -45,9 +34,7 @@ public final class ExcludeNothingWithPrettyPrintingOnJsonSerializerGoogleGson {
public ExcludeNothingWithPrettyPrintingOnJsonSerializerGoogleGson() { public ExcludeNothingWithPrettyPrintingOnJsonSerializerGoogleGson() {
final GsonBuilder builder = new GsonBuilder(); final GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(LocalDate.class, new JodaLocalDateAdapter()); GoogleGsonSerializerHelper.registerTypeAdapters(builder);
builder.registerTypeAdapter(DateTime.class, new JodaDateTimeAdapter());
builder.registerTypeAdapter(MonthDay.class, new JodaMonthDayAdapter());
builder.setPrettyPrinting(); builder.setPrettyPrinting();
this.gson = builder.create(); this.gson = builder.create();
@@ -24,6 +24,7 @@ import com.google.gson.GsonBuilder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.apache.fineract.infrastructure.core.api.DateAdapter;
import org.apache.fineract.infrastructure.core.api.JodaDateTimeAdapter; import org.apache.fineract.infrastructure.core.api.JodaDateTimeAdapter;
import org.apache.fineract.infrastructure.core.api.JodaLocalDateAdapter; import org.apache.fineract.infrastructure.core.api.JodaLocalDateAdapter;
import org.apache.fineract.infrastructure.core.api.JodaMonthDayAdapter; import org.apache.fineract.infrastructure.core.api.JodaMonthDayAdapter;
@@ -36,16 +37,14 @@ import org.joda.time.MonthDay;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/** /**
* Helper class for serialization of java objects into JSON using google-gson. * Helper class for serialization of Java objects into JSON using Google's GSON.
*/ */
@Service @Service
public final class GoogleGsonSerializerHelper { public final class GoogleGsonSerializerHelper {
public Gson createGsonBuilder(final boolean prettyPrint) { public Gson createGsonBuilder(final boolean prettyPrint) {
final GsonBuilder builder = new GsonBuilder(); final GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(LocalDate.class, new JodaLocalDateAdapter()); registerTypeAdapters(builder);
builder.registerTypeAdapter(DateTime.class, new JodaDateTimeAdapter());
builder.registerTypeAdapter(MonthDay.class, new JodaMonthDayAdapter());
if (prettyPrint) { if (prettyPrint) {
builder.setPrettyPrinting(); builder.setPrettyPrinting();
} }
@@ -53,13 +52,10 @@ public final class GoogleGsonSerializerHelper {
} }
public Gson createGsonBuilderForPartialResponseFiltering(final boolean prettyPrint, final Set<String> responseParameters) { public Gson createGsonBuilderForPartialResponseFiltering(final boolean prettyPrint, final Set<String> responseParameters) {
final ExclusionStrategy strategy = new ParameterListInclusionStrategy(responseParameters); final ExclusionStrategy strategy = new ParameterListInclusionStrategy(responseParameters);
final GsonBuilder builder = new GsonBuilder().addSerializationExclusionStrategy(strategy); final GsonBuilder builder = new GsonBuilder().addSerializationExclusionStrategy(strategy);
builder.registerTypeAdapter(LocalDate.class, new JodaLocalDateAdapter()); registerTypeAdapters(builder);
builder.registerTypeAdapter(DateTime.class, new JodaDateTimeAdapter());
builder.registerTypeAdapter(MonthDay.class, new JodaMonthDayAdapter());
if (prettyPrint) { if (prettyPrint) {
builder.setPrettyPrinting(); builder.setPrettyPrinting();
} }
@@ -72,7 +68,6 @@ public final class GoogleGsonSerializerHelper {
final Set<String> parameterNamesToSkip = new HashSet<>(); final Set<String> parameterNamesToSkip = new HashSet<>();
if (!responseParameters.isEmpty()) { if (!responseParameters.isEmpty()) {
// strip out all known support parameters from expected response to // strip out all known support parameters from expected response to
// see if unsupported parameters requested for response. // see if unsupported parameters requested for response.
final Set<String> differentParametersDetectedSet = new HashSet<>(responseParameters); final Set<String> differentParametersDetectedSet = new HashSet<>(responseParameters);
@@ -88,9 +83,7 @@ public final class GoogleGsonSerializerHelper {
final ExclusionStrategy strategy = new ParameterListExclusionStrategy(parameterNamesToSkip); final ExclusionStrategy strategy = new ParameterListExclusionStrategy(parameterNamesToSkip);
final GsonBuilder builder = new GsonBuilder().addSerializationExclusionStrategy(strategy); final GsonBuilder builder = new GsonBuilder().addSerializationExclusionStrategy(strategy);
builder.registerTypeAdapter(LocalDate.class, new JodaLocalDateAdapter()); registerTypeAdapters(builder);
builder.registerTypeAdapter(DateTime.class, new JodaDateTimeAdapter());
builder.registerTypeAdapter(MonthDay.class, new JodaMonthDayAdapter());
if (prettyPrint) { if (prettyPrint) {
builder.setPrettyPrinting(); builder.setPrettyPrinting();
} }
@@ -104,4 +97,11 @@ public final class GoogleGsonSerializerHelper {
public String serializedJsonFrom(final Gson serializer, final Object singleDataObject) { public String serializedJsonFrom(final Gson serializer, final Object singleDataObject) {
return serializer.toJson(singleDataObject); return serializer.toJson(singleDataObject);
} }
public static void registerTypeAdapters(final GsonBuilder builder) {
builder.registerTypeAdapter(java.util.Date.class, new DateAdapter());
builder.registerTypeAdapter(LocalDate.class, new JodaLocalDateAdapter());
builder.registerTypeAdapter(DateTime.class, new JodaDateTimeAdapter());
builder.registerTypeAdapter(MonthDay.class, new JodaMonthDayAdapter());
}
} }