【问题标题】:GSON to serialize/deserialize to/from a custom generic collection typeGSON 对自定义泛型集合类型进行序列化/反序列化
【发布时间】:2017-01-04 16:22:23
【问题描述】:

我正在寻找一种方法来配置 GSON 以序列化和反序列化自定义泛型集合类型。

有问题的集合是LibGDX' Array 类型。

我找不到有关如何实现此目的的文档。有人可以帮忙吗?

【问题讨论】:

    标签: java json libgdx gson deserialization


    【解决方案1】:

    解决方案 1:

    转换为标准 Java 数组。由于 Array 实际上只是标准 Java 数组的包装器,因此我们不会丢失转换它的数据,而且 Gson 可以轻松地为我们处理标准数组的序列化和反序列化。

    Array<Human> array = new Array<Human>();
    array.add(new Human("Jack"));
    array.add(new Human("Tom"));
    array.add(new Human("Mel"));
    array.add(new Human("Anne"));
    
    Gdx.app.log("JSON", "To json");
    for (Human human : array) {
        Gdx.app.log("Human", human.name);
    }
    
    Gson gson = new Gson();
    String json = gson.toJson(array.toArray(), Human[].class);
    Array<Human> arrayFromJson = new Array<Human>(gson.fromJson(json, Human[].class));
    
    Gdx.app.log("JSON", "From json");
    for (Human human : arrayFromJson) {
        Gdx.app.log("Human", human.name);
    }
    

    输出:

    JSON: To json
    Human: Jack
    Human: Tom
    Human: Mel
    Human: Anne
    JSON: From json
    Human: Jack
    Human: Tom
    Human: Mel
    Human: Anne
    

    解决方案 2:

    如果您在某种对象中有Array&lt;Human&gt;,则需要手动从 Java 数组转换为 LibGDX 数组,这会有点混乱。

    编写自己的序列化程序是解决这个问题的方法,但是用泛型编写序列化程序很复杂,但可能。

    最难的部分是反序列化器:

    public class ArrayDeserializer<T> implements JsonDeserializer<Array<T>> {
        Class<T[]> tClass;
    
        public ArrayDeserializer(Class<T[]> tClass) {
            this.tClass = tClass;
        }
    
        @Override
        public Array<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            T[] objects = context.deserialize(json, tClass);
            return new Array<T>(objects);
        }
    }
    

    序列化器很笨。

    public class ArraySerializer implements JsonSerializer<Array> {
        @Override
        public JsonElement serialize(Array src, Type typeOfSrc, JsonSerializationContext context) {
            return context.serialize(src.toArray(), src.toArray().getClass());
        }
    }
    

    然后在代码中使用:

    Type type = TypeToken.get(array.getClass()).getType(); //Array<Human>
    ...
    gsonBuilder.registerTypeAdapter(type, new ArrayDeserializer<Human>(Human[].class));
    gsonBuilder.registerTypeAdapter(type, new ArraySerializer());
    

    然后构建能够序列化 libGDX 数组的新 Gson 实例。

    【讨论】:

    • 是否可以以通用方式添加 ArrayDeserializer,这样我就不需要为每个要序列化的 Array 实例化一个实例?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-26
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    相关资源
    最近更新 更多