Gson泛型封裝

青冘發表於2020-12-26

json格式

1.後臺給的資料格式有兩種:

// data 為 object 的情況
{"code":"0","msg":"message","success":"true","data":{}}
// data 為 array 的情況
{"code":"0","msg":"message","success":"true","data":[]}

2、假定第一種的對應的Java型別為 BaseBean<XXX> ,第二種為 BaseBean<List<XXX>> ,如果每一個資料都去生成一個Bean去進行解析,就十分繁瑣,

而直接使用new TypeToken<XXX>(){}的形式來解析泛型,得到的資料卻是LinkedTreeMap格式的資料,所以深入研究了一下Gson的泛型封裝,終於可以直接拿到泛型的Bean資料了。

封裝原型

// 處理 data 為 object 的情況
public static <T> BaseBean<T> fromJsonObject(String reader, Class<T> clazz) {}
// 處理 data 為 array 的情況
public static <T> BaseBean<List<T>> fromJsonArray(String reader, Class<T> clazz){}

 封裝原理

TypeToken的作用是用於獲取泛型的類,返回的型別為Type,真正的泛型資訊就是放在這個Type裡面。

Type是Java中所有型別的父介面,在1.8以前是一個空介面,自1.8起多了個getTypeName()方法,下面有ParameterizedTypeGenericArrayTypeWildcardTypeTypeVariable 幾個介面,以及Class類。這幾個介面在本次封裝過程中只會用到 ParameterizedType ,所以簡單說一下:

ParameterizedType 簡單說來就是形如“ 型別<> ”的型別,如:Map<String,User>。下面就以 Map<String,User> 為例講一下里面各個方法的作用。

public interface ParameterizedType extends Type {
     // 返回Map<String,User>裡的String和User,所以這裡返回[String.class,User.clas]
    Type[] getActualTypeArguments(); 
    // Map<String,User>裡的Map,所以返回值是Map.class
    Type getRawType();
    // 用於這個泛型上中包含了內部類的情況,一般返回null
    Type getOwnerType(); 
}

 實現過程

 1、實現一個簡易的 ParameterizedType

public class ParameterizedTypeImpl implements ParameterizedType {
    private final Class raw;
    private final Type[] args;
    public ParameterizedTypeImpl(Class raw, Type[] args) {
        this.raw = raw;
        this.args = args != null ? args : new Type[0];
    }
    @Override
    public Type[] getActualTypeArguments() {
        return args;
    }
    @Override
    public Type getRawType() {
        return raw;
    }
    @Override
    public Type getOwnerType() {return null;}
}

 

2、生成Gson需要的泛型

2.1解析data是object的情況

public static <T> BaseBean<T> fromJsonObject(String reader, Class<T> clazz) {
    Type type = new ParameterizedTypeImpl(BaseBean.class, new Class[]{clazz});
    return GSON.fromJson(reader, type);
}

2.2解析data是array的情況

public static <T> BaseBean<List<T>> fromJsonArray(String reader, Class<T> clazz) {
    // 生成List<T> 中的 List<T>
    Type listType = new ParameterizedTypeImpl(List.class, new Class[]{clazz});
    // 根據List<T>生成完整的Result<List<T>>
    Type type = new ParameterizedTypeImpl(BaseBean.class, new Type[]{listType});
    return GSON.fromJson(String , type);
}

舉例

public static <T> BaseBean<List<T>> fromJsonArray(String reader, Class<T> clazz) {
    Type type = TypeBuilder
            .newInstance(BaseBean.class)
            .beginSubType(List.class)
            .addTypeParam(clazz)
            .endSubType()
            .build();
    return GSON.fromJson(reader, type);
}

public static <T> BaseBean<T> fromJsonObject(String reader, Class<T> clazz) {
    Type type = TypeBuilder
            .newInstance(BaseBean.class)
            .addTypeParam(clazz)
            .build();
    return GSON.fromJson(reader, type);
}

 

 

相關文章