美文网首页
使用Gson的一些感悟——解析复杂json

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

作者: 夜雨声眠 | 来源:发表于2018-11-04 18:26 被阅读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的内部处理也是让人眼界大开,对反射的用法可谓精深,等有时间再好好总结下。

    相关文章

      网友评论

          本文标题:使用Gson的一些感悟——解析复杂json

          本文链接:https://www.haomeiwen.com/subject/oqkdxqtx.html