Gson泛型封裝
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()
方法,下面有ParameterizedType
、 GenericArrayType
、 WildcardType
、 TypeVariable
幾個介面,以及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);
}
相關文章
- Swift 運用協議泛型封裝網路層Swift協議泛型封裝
- Gson通過藉助TypeToken獲取泛型引數的型別的方法泛型型別
- LinkedList重寫(5)LinkedList簡單的封裝和增加泛型封裝泛型
- 封裝和多型封裝多型
- 封裝,特性,多型封裝多型
- 泛型類、泛型方法及泛型應用泛型
- 【java】【泛型】泛型geneticJava泛型
- 封裝多型巢狀封裝多型巢狀
- 泛型類和泛型方法泛型
- 泛型--泛型萬用字元和泛型的上下限泛型字元
- Eclipse安裝GSON,使用GSON轉換Java Object到JSONEclipseJavaObjectJSON
- 物件導向:封裝,多型物件封裝多型
- IM多型別holder封裝多型型別封裝
- 封裝、繼承和多型封裝繼承多型
- 答答租車(封裝+多型)封裝多型
- TypeScript 泛型介面和泛型類TypeScript泛型
- Go 泛型之泛型約束Go泛型
- 泛型泛型
- 泛型最佳實踐:Go泛型設計者教你如何用泛型泛型Go
- Vue Hook 封裝通用型表格VueHook封裝
- TypeScript 泛型型別TypeScript泛型型別
- 型別 VS 泛型型別泛型
- 泛型類、泛型方法、型別萬用字元的使用泛型型別字元
- 泛型(一)泛型
- 泛型(三)泛型
- 泛型(二)泛型
- 泛型(四)泛型
- 泛型(五)泛型
- Java泛型Java泛型
- 泛型viewmodle泛型View
- 泛型(Generic)泛型
- Go 泛型Go泛型
- 【譯】在非泛型類中建立泛型方法泛型
- aardio 實現封裝繼承多型封裝繼承多型
- 面向2-封裝、繼承、多型封裝繼承多型
- 泛型型別(.NET 指南)泛型型別
- Java函式泛型List引數,操作泛型元素Java函式泛型
- Go 官方出品泛型教程:如何開始使用泛型Go泛型