在项目开发中和服务端使用json数据格式进行交互的时候,通常服务端返回的数据会约定一个数据格式,例如:
{"code":"0","message":"success","data":{}}
我们真正需要的data所包含的数据,而code只使用一次,message很少用到。如果Gson不支持泛型或不知道Gson支持泛型的一定会这么定义Model。
public class UserModel {
public int code;
public String message;
public User data;
public static class User {
public int name;
public int age;
public int sex;
}
}
当其它接口的时候又重新定义一个XXResponse将data的类型改成XX,很明显code,和message被重复定义了多次,通过泛型的话我们可以将code和message字段抽取到一个Result的类中,这样我们只需要编写data字段所对应的Model即可,更专注于我们的业务逻辑。如:
public class Result<T> {
public int code;
public String message;
public T data;
}
到了这一步接下来肯定有些伙伴会这样写
public class UserModel extends Result<UserModel> {
public int name;
public int age;
public int sex;
}
//解析的时候这样解析
//gson.fromJson(json, UserModel.class);
如果你信心满满的按照上面这种写法的话发现解析出来的UserModel对象里面的属性都没有值,如果你调试的话就会发现UserModel 中的data 字段是有值的。
正确的做法:
public class UserModel {
public int name;
public int age;
public int sex;
}
//解析的时候这样解析
//gson.fromJson(json, new TypeToken<Result<UserModel>>(){}.getType());
泛型封装统一的Model就讲到这了,Gson框架其实是很强大的,在这里再介绍一个开发中可能碰到的关于JSON解析的问题。
有次我们服务端的人员很操蛋的将一个字段的Key定义为了short,当我封装model模型的时候懵逼了,what?不带这样玩的。当然你可以很理直气壮的让服务端的开发人员将字段改一下,但万一此接口还有其他的平台使用,比如PHP,你这样要求别人改那PHP的哥们已经写好了可能就不乐意了,那我们有没有什么办法自己解决这个问题呢?当然利用Gson是可以实现的。
我们知道Gson在序列化和反序列化时需要使用反射,说到反射就不得不想到注解,一般各类库都将注解放到annotations包下,打开源码在com.google.gson包下果然有一个annotations,里面有一个SerializedName的注解类,这应该就是我们要找的。
那么对于json中short这个属性我们可以这样定义:
@SerializedName("short")
public String mshort;
这样的话,很好的保留了前端、后台、Android/java各自的命名习惯。