Gson

Last modified date

Comments: 0

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();
        }
    }
jimschenchen

即使苍天陨落,契约必须完成

Share

Leave a Reply