Gson usability utilities. It's designed to add additional features like easy and centralized configuration, builder or static method set. Artifact does not include direct
Gsondependencies. It is up to you to add them into your project.
- Encapsulate all checked exceptions from Gson with custom runtime exception;
- A central place for configuration;
- A central place for holding
Gsoninstances; - Utility class to make most common operations much more comfortable to use;
- Ability to change
Zoneto saveZonedDateTimeindependently of original zone; Reader/Writersupport for objects, lists and maps;- Lazy read support for list and maps from
Writer; - Read numeric as
Integer,Long,BigIntegerorDouble(but not only asDouble). - Advanced
Reader/Writersupport forenum.
compile 'ru.oleg-cherednik.gson:gson-utils:2.2'<dependency>
<groupId>ru.oleg-cherednik.gson</groupId>
<artifactId>gson-utils</artifactId>
<version>2.2</version>
</dependency>In the version, first part is the major version of Gson that is used in this utils.
The second part is the gson-utils version. This number is unique.
Note: gson-utils does not contain dependency to the specific gson version, so you have to
add it additionally:
compile 'com.google.code.gson:gson:2.8.7'<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.7</version>
</dependency>- GsonUtils - utility class with set of methods to use json transformation;
- GsonUtilsBuilder - builder for Gson instance contains all configuration properties;
- GsonDecorator - decorator class to hold Gson instance with additional methods;
- GsonUtilsHelper - helper class is used as a holder for default properties;
- EnumId - advanced enum serialization support;
Data class for examples
package ru.olegcherednik.utils.gson.data;
public class Data {
private int intVal;
private String strVal;
public Date() {}
public Data(int intValue, String strValue) {
this.intValue = intValue;
this.strValue = strValue;
}
public int getIntValue() {
return intValue;
}
public String getStrVal() {
return strValue;
}
}details
public class Snippet {
public static Data jsonStringToObj() {
String json = """
{
"intVal": 666,
"strVal": "omen"
}
""";
return GsonUtils.readValue(json, Data.class);
}
}public class Snippet {
public static List<Data> jsonStringToList() {
String json = """
[
{
"intVal" : 555,
"strVal" : "victory"
},
{
"intVal" : 666,
"strVal" : "omen"
}
]
""";
return GsonUtils.readList(json, Data.class);
}
}public class Snippet {
public static Map<String, ?> jsonStringToMap() {
String json = """
{
"victory" : {
"intVal" : 555,
"strVal" : "victory"
},
"omen" : {
"intVal" : 666,
"strVal" : "omen"
}
}
""";
return GsonUtils.readMap(json);
}
}Note: Map values have either primitive type or Map or List.
public class Snippet {
public static Map<String, Data> jsonStringToMap() {
String json = """
{
"victory" : {
"intVal" : 555,
"strVal" : "victory"
},
"omen" : {
"intVal" : 666,
"strVal" : "omen"
}
}
""";
return GsonUtils.readMap(json, Data.class);
}
}public class Snippet {
public static Map<Integer, Data> jsonStringToMap() {
String json = """
{
"1" : {
"intVal" : 555,
"strVal" : "victory"
},
"2" : {
"intVal" : 666,
"strVal" : "omen"
}
}
""";
return GsonUtils.readMap(json, Integer.class, Data.class);
}
}{
"intVal" : 666,
"strVal" : "omen"
}public class Snippet {
public static Data readJsonFromFileToObj(File file) {
try (Reader in = new FileReader(file)) {
return GsonUtils.readValue(in, Data.class);
}
}
}[
{
"intVal" : 555,
"strVal" : "victory"
},
{
"intVal" : 666,
"strVal" : "omen"
}
]public class Snippet {
public static List<Data> readJsonEdgerFromFileToList(File file) {
try (Reader in = new FileReader(file)) {
return GsonUtils.readList(in, Data.class);
}
}
}[
{
"intVal" : 555,
"strVal" : "victory"
},
{
"intVal" : 666,
"strVal" : "omen"
}
]public class Snippet {
public static List<Data> readJsonLazyFromFileToList(File file) {
try (Reader in = new FileReader(file)) {
List<Data> res = new ArrayList<>();
Iterator<Data> it = GsonUtils.readListLazy(in, Data.class);
while (it.hasNext())
res.add(it.next());
return res;
}
}
}{
"victory" : {
"intVal" : 555,
"strVal" : "victory"
},
"omen" : {
"intVal" : 666,
"strVal" : "omen"
}
}public class Snippet {
public static Map<String, ?> readJsonFromFileToMap(File file) {
try (Reader in = new FileReader(file)) {
return GsonUtils.readMap(in);
}
}
}Note: map values have either primitive type or Map or List.
{
"victory" : {
"intVal" : 555,
"strVal" : "victory"
},
"omen" : {
"intVal" : 666,
"strVal" : "omen"
}
}public class Snippet {
public static Map<String, Data> readJsonFromFileToMap(File file) {
try (Reader in = new FileReader(file)) {
return GsonUtils.readMap(in, Data.class);
}
}
}{
"1" : {
"intVal" : 555,
"strVal" : "victory"
},
"2" : {
"intVal" : 666,
"strVal" : "omen"
}
}public class Snippet {
public static Map<Integer, Data> readJsonFromFileToMap(File file) {
try (Reader in = new FileReader(file)) {
return GsonUtils.readMap(in, Integer.class, Data.class);
}
}
}details
public class Snippet {
public static String objToJsonString() {
Data data = new Data(555, "victory");
return GsonUtils.writeValue(data);
}
}{"intVal":555,"strVal":"victory"}public class Snippet {
public static String listToJsonString() {
List<Data> data = List.of(new Data(555, "victory"), new Data(666, "omen"));
return GsonUtils.writeValue(map);
}
}[{"intVal":555,"strVal":"victory"},{"intVal":666,"strVal":"omen"}]public class Snippet {
public static String mapToJsonString() {
Map<String, Data> data = Map.of(
"victory", new Data(555, "victory"),
"omen", new Data(666, "omen"));
return GsonUtils.writeValue(data);
}
}{"victory":{"intVal":555,"strVal":"victory"},"omen":{"intVal":666,"strVal":"omen"}}public class Snippet {
public static String mapToPrettyPrintJsonString() {
Map<String, Data> data = Map.of(
"victory", new Data(555, "victory"),
"omen", new Data(666, "omen"));
return GsonUtils.prettyPrint().writeValue(data);
}
}{
"victory": {
"intVal": 555,
"strVal": "victory"
},
"omen": {
"intVal": 666,
"strVal": "omen"
}
}details
By default, Gson serializes or deserializes enums by the case-sensitive name.
It could give a problem as well as sometime it's better to change name of the
constant when serialize it into json.
To solve these issues, GsonUtils provides an interface EnumId with range of
method to serialize or deserialize enums. To use it, you have to declare your
enums according to the following snippet:
public enum Auto implements EnumId {
AUDI("audi"),
BMW("bmw"),
MERCEDES("mercedes");
private final String id;
Auto(String id) {
this.id = id;
}
@Override
public String getId() {
return id;
}
@JsonCreator
public static Auto parseId(String id) {
return EnumId.parseId(Auto.class, id);
}
}Where @JsonCreator is an optional annotation to mark a single method that
accepts exactly one string parameter to deserialize an enum constant.
That's it! You can use gson-utils methods as usual.
details
GsonUtilsHelper class contains default gson configuration. This configuration
can be used to create gson bean:
@Configuration
public class AppConfig {
@Bean
public GsonDecorator gsonDecorator() {
return GsonUtilsHelper.createGsonDecorator();
}
}To customize gson configuration, a new instance of GsonUtilsBuilder should be
created and configured. Then this instance should be used to create GsonDecorator.
@Configuration
public class AppConfig {
@Bean
public GsonUtilsBuilder gsonUtilsBuilder() {
// customize Gson here
return new GsonUtilsBuilder();
}
@Bean
public GsonDecorator gsonDecorator(GsonUtilsBuilder gsonUtilsBuilder) {
return GsonUtilsHelper.createGsonDecorator(gsonUtilsBuilder);
}
}A new GsonDecorator should be used to work with json instead of using a Gson instance.
@Service
public class SpringBootService {
@Autowired
private GsonDecorator gson;
public String toJson(Data data) {
return gson.writeValue(data);
}
public Data fromJson(String json) {
return gson.readValue(json, Data.class);
}
}details
The class provides ability to customize Gson instance and create a new Gson
instances with current settings.
Following snippet shows how to serialize Date to UTC time zone and format "HH:mm:ss yyyy-MM-dd".
You have to create a new instance of GsonUtilsBuilder and add custom implementation.
public class Snippet {
public static Gson createCustomGson() {
UnaryOperator<ZoneId> zoneModifier = GsonUtilsBuilder.ZONE_MODIFIER_TO_UTC;
DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm:ss yyyy-MM-dd");
TypeAdapter<Date> typeAdapter = new DateTypeAdapter(zoneModifier, dateTimeFormatter);
GsonUtilsBuilder builder = new GsonUtilsBuilder().registerTypeAdapter(Data.class, typeAdapter);
return builder.gson();
}
}details
This is a decorator over the standard Gson class with more additional method. GsonUtils chooses required Gson
instance and delegates all work to the GsonDecorator.
details
This class provides set of methods to create a Gson instances based on given GsonUtilsBulder.