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
Gson
dependencies. 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
Gson
instances; - Utility class to make most common operations much more comfortable to use;
- Ability to change
Zone
to saveZonedDateTime
independently of original zone; Reader
/Writer
support for objects, lists and maps;- Lazy read support for list and maps from
Writer
; - Read numeric as
Integer
,Long
,BigInteger
orDouble
(but not only asDouble
). - Advanced
Reader
/Writer
support 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
.