在項目開發(fā)中和服務(wù)端使用json數(shù)據(jù)格式進(jìn)行交互的時候,通常服務(wù)端返回的數(shù)據(jù)會約定一個數(shù)據(jù)格式,例如:
{"code":"0","message":"success","data":{}}
我們真正需要的data所包含的數(shù)據(jù),而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;
}
}
當(dāng)其它接口的時候又重新定義一個XXResponse將data的類型改成XX,很明顯code,和message被重復(fù)定義了多次,通過泛型的話我們可以將code和message字段抽取到一個Result的類中,這樣我們只需要編寫data字段所對應(yīng)的Model即可,更專注于我們的業(yè)務(wù)邏輯。如:
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);
如果你信心滿滿的按照上面這種寫法的話發(fā)現(xiàn)解析出來的UserModel對象里面的屬性都沒有值,如果你調(diào)試的話就會發(fā)現(xiàn)UserModel 中的data 字段是有值的。
正確的做法:
public class UserModel {
public int name;
public int age;
public int sex;
}
//解析的時候這樣解析
//gson.fromJson(json, new TypeToken<Result<UserModel>>(){}.getType());
泛型封裝統(tǒng)一的Model就講到這了,Gson框架其實是很強大的,在這里再介紹一個開發(fā)中可能碰到的關(guān)于JSON解析的問題。
有次我們服務(wù)端的人員很操蛋的將一個字段的Key定義為了short,當(dāng)我封裝model模型的時候懵逼了,what?不帶這樣玩的。當(dāng)然你可以很理直氣壯的讓服務(wù)端的開發(fā)人員將字段改一下,但萬一此接口還有其他的平臺使用,比如PHP,你這樣要求別人改那PHP的哥們已經(jīng)寫好了可能就不樂意了,那我們有沒有什么辦法自己解決這個問題呢?當(dāng)然利用Gson是可以實現(xiàn)的。
我們知道Gson在序列化和反序列化時需要使用反射,說到反射就不得不想到注解,一般各類庫都將注解放到annotations包下,打開源碼在com.google.gson包下果然有一個annotations,里面有一個SerializedName的注解類,這應(yīng)該就是我們要找的。
那么對于json中short這個屬性我們可以這樣定義:
@SerializedName("short")
public String mshort;
這樣的話,很好的保留了前端、后臺、Android/java各自的命名習(xí)慣。