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);
}