使用Gson的一些感悟——解析复杂json

2018-11-04  本文已影响0人  夜雨声眠

使用Gson的一些感悟——解析复杂json

将json解析为泛型对象时,发现Gson有种很特别的写法,因此学习了下。

需要将如下json解析为对象

{
    "acs-engine-autoscaler": [
        {
            "apiVersion": "v1",
            "version": "2.1.4"
        }
    ],
    "aerospike": [
        {
            "appVersion": "v3.14.1.2",
            "version": "0.1.7"
        }
    ],
    "anchore-engine": [
        {
            "appVersion": "0.2.4",
            "version": "0.2.6"
        }
    ]
}

阅读Gson的官方指引,有如下用法:

Collection Type

Gson gson = new Gson();
Collection<Integer> ints = Lists.immutableList(1,2,3,4,5);

// Serialization
String json = gson.toJson(ints);  // ==> json is [1,2,3,4,5]

// Deserialization
Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
Collection<Integer> ints2 = gson.fromJson(json, collectionType);

重点在这句:

Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();

定义一个继承于泛型参数类型为Collection<Integer>Typetoken类的子类(语文不好,我重新说,定义一个匿名类,它的父类是泛型参数类型为
Collection<Integer>TypeToken泛型类)。

之所以要这么写,是因为java的泛型类型擦除导致的(网上资料很多),直接看下面例子。

package com.yu;

import java.lang.reflect.Type;

public class testGenericClass {

    private static class F<T>{
        public T name;
    }

    public static void main(String args[]) {
        F<String> obj = new F<String>();
        Type subclassType = new F<String>(){}.getClass().getGenericSuperclass();
        Type type = obj.getClass().getGenericSuperclass();
        System.out.println(type.getTypeName());
        System.out.println(subclassType.getTypeName());
    }
}

运行结果:

java.lang.Object
com.yu.testGenericClass$F<java.lang.String>

显而易见,泛型类F的对象obj的泛型参数类型String已经被擦除,现在就知道是Object了。而继承自泛型参数为StringF的匿名类的对象subclassType的直接父类信息上还保留着泛型参数的信息。

其实还有一种写法就是将泛型参数作为实参传递,无奈Gson的Typetoken这个类的构造函数是protected(不过仔细想想,还是Gson的处理方式更优雅,就是丑了点...)

回到开始的问题,要解析开头这段json就两句即可。

Type t = new TypeToken<Map<String, VersionDO[]>>() {}.getType();
Map<String, VersionDO[]> result = new Gson().fromJson(jsonContent, t);

class VersionDO {

    private String apiVersion;
    private String version;
}

Gson的内部处理也是让人眼界大开,对反射的用法可谓精深,等有时间再好好总结下。

上一篇下一篇

猜你喜欢

热点阅读