Gson

What is Gson?
A Java tool Lib for Serialization and deserialization of class in the format of JSON.
Official Repo:
https://github.com/google/gson
Usage
General Usage (Based on V2.8.6):
// create a Gson Builder
GsonBuilder builder = new GsonBuilder();
// add config to builder
// builder.xxx();
// create a Gson Object from Gson builder
Gson gson = builder.create();
// dump json / serialization
String jsonStr = gson.toJson(data);
// load json / deserialization
<Class> data = gson.fromJson(reader, <Class>.class);
Config of Builder:
// Serializa Null Value
builder.serializeNulls();
// Register Adapter
builder.registerTypeAdapter(<Class>.class, <Adapter>);
List of Abstract Class / Interface
Problem: Store subclass of AC/I to a list, the Gson does not know which actual type of that subclass.
Also, one solution `RuntimeTypeAdapterFactory` had been banned in the current Gson version.
Intuition:
// Changing the json format when deserialization and serialization
{
"CLASSNAME": "OutItems",
"DATA": {
}
}
InterfaceAdapter:
import com.google.gson.*;
import java.lang.reflect.Type;
public class InterfaceAdapter implements JsonSerializer, JsonDeserializer {
private static final String CLASSNAME = "CLASSNAME";
private static final String DATA = "DATA";
public Object deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject jsonObject = jsonElement.getAsJsonObject();
JsonPrimitive prim = (JsonPrimitive) jsonObject.get(CLASSNAME);
String className = prim.getAsString();
Class klass = getObjectClass(className);
return jsonDeserializationContext.deserialize(jsonObject.get(DATA), klass);
}
public JsonElement serialize(Object jsonElement, Type type, JsonSerializationContext jsonSerializationContext) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty(CLASSNAME, jsonElement.getClass().getName());
jsonObject.add(DATA, jsonSerializationContext.serialize(jsonElement));
return jsonObject;
}
/****** Helper method to get the className of the object to be deserialized *****/
public Class getObjectClass(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
//e.printStackTrace();
throw new JsonParseException(e.getMessage());
}
}
}
Add config to Builder:
builder.registerTypeAdapter(User.class, new InterfaceAdapter());
Then, the Gson will automatically convert the object of the abstract class and interface.
Reference:
https://technology.finra.org/code/serialize-deserialize-interfaces-in-java.html
https://medium.com/@ezralazuardy/gson-custom-interface-adapter-3f3b863e063d
Other Implement
/*
* IO in sequence
*/
public static void readStream() {
try {
JsonReader reader = new JsonReader(new FileReader("<path>"));
Gson gson = new GsonBuilder().create();
// Read file in stream mode
reader.beginArray();
while (reader.hasNext()) {
// Read data into object model
Person person = gson.fromJson(reader, Person.class);
// if (person.getId() == 0 ) {}
System.out.println("Stream mode: " + person);
}
reader.close();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException ex) {
e.printStackTrace();
}
}
/*
* JsonWriter
*/
public static void writeStream() {
try (JsonWriter writer = new JsonWriter(new FileWriter(<Path>))) {
writer.beginObject(); // {
writer.name("name").value("mkyong"); // "name" : "mkyong"
writer.name("age").value(29); // "age" : 29
writer.name("messages"); // "messages" :
writer.beginArray(); // [
writer.value("msg 2"); // "msg 1"
writer.value("msg 2"); // "msg 2"
writer.value("msg 3"); // "msg 3"
writer.endArray(); // ]
writer.endObject(); // }
} catch (IOException e) {
e.printStackTrace();
}
}