gson解析给大家打开很多便利,封装起来也比较省事,简单的gson解析直接用class或者type解析出来就可以了。
不过一般的服务端返回用户对象封装好多会遇到各种问题各种坑
以下分析常用的gson解析服务器返回的通用方法:
1、客户端和服务器一般gson格式都会定义固定的格式方便接口统一处理
比如类似下边的格式,data可以是array 数组[],也可以是obj{}
{
"code": "0000",
"msg": "成功",
"t": [{
"userid": "1",
"userName": "张三"
}, {
"userid": "1",
"userName": "王五"
}]
}
{
"code": "0000",
"msg": "成功",
"data": {
"userid": "1",
"userName": "张三"
}
}
2、解析这样的数据,一般大家都会把data 分开解析,如果是数组的话怎么解析,如果是对象的话怎么解析。具体这种解析可以看相关的文档。
分开解析可以满足需求,但是对于解析过程多了一步,先解析完成第一级才能判断是否数组,这样效率有所影响
3、其实可以利用泛型及泛型的的一个方法来获取解析的数据类型的
首先我们先一个基础对象封装类
abstract class JsonModels<T> {
private String msg;
private String code;
private T data;
public String getMsg() {
return msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
我们再根据下边的方法获取到t,t其实就是所传到对象的User或者是List<User>;
Type type = getClass().getGenericSuperclass();
Type[] t = ((ParameterizedType) type).getActualTypeArguments();
获取到t后我们怎么拼装成Type呢?查看源码发现Type有几个实现类我们用到ParameterizedType,然后继承这个类之后把jmodel和t设置进去就可以了
class ParameterizedTypeImpl implements ParameterizedType {
Type[] type;
Class raw;
@Override
public Type[] getActualTypeArguments() {
// TODO 自动生成的方法存根
return type;
}
@Override
public Type getOwnerType() {
// TODO 自动生成的方法存根
return null;
}
public ParameterizedTypeImpl(Type[] args, Class raw) {
super();
this.type = args != null ? args : new Type[0];
this.raw = raw;
}
@Override
public Type getRawType() {
// TODO 自动生成的方法存根
return raw;
}
我们可以直接把json解析放到JsonModel中去
public JsonModel<T> toJsonModel(String json) {
Type type = getClass().getGenericSuperclass();
Type[] t = ((ParameterizedType) type).getActualTypeArguments();
Type ty = new ParameterizedTypeImpl(t, JsonModel.class);
return new Gson().fromJson(json, ty );
}
----注意这个方法getGenericSuperclass调用必须是JsonModels为抽象类,我们再写一个实现类,实现类可以为空什么也不写,如下:
class JsonModel<T> extends JsonModels<T>{}
现在基本类已经写完了,以下就是直接调用了。
public static void main(String args[]) {
// String json="{\"code\":\"0000\",\"msg\":\"成功\",\"data\":[{\"userid\":\"1\",\"userName\":\"张三\"},{\"userid\":\"1\",\"userName\":\"王五\"}]}";
String json="{\"code\":\"0000\",\"msg\":\"成功\",\"data\":{\"userid\":\"1\",\"userName\":\"张三\"}}";
JsonModel<List<User>> j=new JsonModel<List<User>>().toJsonModel(json);
System.out.println(j.getData());
}
调用的时候是不是很简单呢,基本的解析就到这里了,其实封装的关键主要是运用了如下几个特性
getGenericSuperclass,ParameterizedType