Deserializing an abstract class in Gson

前端 未结 4 1995
盖世英雄少女心
盖世英雄少女心 2020-11-27 16:10

I have a tree object in JSON format I\'m trying to deserialize with Gson. Each node contains its child nodes as fields of object type Node. Node is an interface, which has

4条回答
  •  南笙
    南笙 (楼主)
    2020-11-27 16:47

    You will need to register both JSONSerializer and JSONDeserializer. Also you can implement a generic adapter for all your interfaces in the following way:

    • During Serialization : Add a META-info of the actual impl class type.
    • During DeSerialization : Retrieve that meta info and call the JSONDeserailize of that class

    Here is the implementation that I have used for myself and works fine.

    public class PropertyBasedInterfaceMarshal implements
            JsonSerializer, JsonDeserializer {
    
        private static final String CLASS_META_KEY = "CLASS_META_KEY";
    
        @Override
        public Object deserialize(JsonElement jsonElement, Type type,
                JsonDeserializationContext jsonDeserializationContext)
                throws JsonParseException {
            JsonObject jsonObj = jsonElement.getAsJsonObject();
            String className = jsonObj.get(CLASS_META_KEY).getAsString();
            try {
                Class clz = Class.forName(className);
                return jsonDeserializationContext.deserialize(jsonElement, clz);
            } catch (ClassNotFoundException e) {
                throw new JsonParseException(e);
            }
        }
    
        @Override
        public JsonElement serialize(Object object, Type type,
                JsonSerializationContext jsonSerializationContext) {
            JsonElement jsonEle = jsonSerializationContext.serialize(object, object.getClass());
            jsonEle.getAsJsonObject().addProperty(CLASS_META_KEY,
                    object.getClass().getCanonicalName());
            return jsonEle;
        }
    
    }
    
    
    

    Then you could register this adapter for all your interfaces as follows

    Gson gson = new GsonBuilder()
            .registerTypeAdapter(IInterfaceOne.class,
                    new PropertyBasedInterfaceMarshal())
            .registerTypeAdapter(IInterfaceTwo.class,
                    new PropertyBasedInterfaceMarshal()).create();
    

    提交回复
    热议问题