初衷
項目中與服務(wù)器端的數(shù)據(jù)交互采用的是json豫领,服務(wù)器返回的數(shù)據(jù)格式比較統(tǒng)一等恐,都是下面這種樣子的
{resultCode:10000,
resultContent:"登錄成功",
obj:{...} //或者[...]
}
對于這段json的解析郊尝,我覺得有下面幾種方式:
- 通過android自帶的JSONObject以及JSONArray采用原生的方式一層一層的解析;
- 通過android自帶的JSONObject解析到obj 然后配合Gson解析obj對應(yīng)的具體內(nèi)容;
- 為每一種格式的json寫對應(yīng)的實體類(包括json的所有字斷)然后通過gson或者其他解析工具解析成對象扎即。
通過對比發(fā)現(xiàn),第一種方式對于obj結(jié)構(gòu)復(fù)雜的情況會出現(xiàn)代碼龐大的問題刁绒;第二種在解析每個json的時候會出現(xiàn)重復(fù)代碼知市;第三種需要為每個json寫實體類,會出現(xiàn)屬性重復(fù)的情況如果采用繼承的話會出現(xiàn)某些實體類中就一個屬性的情況莫杈。
本文的目標就是針對第三種方式的一種封裝筝闹,開發(fā)者可以只提供obj對應(yīng)的實體類即可关顷。當(dāng)然更希望本文提供的是解決一類問題的思路议双。
想法
如果有一個類 包含3個字段平痰,分別是:int resultCode,String resultContent,Object obj; 然后根據(jù)返回的json的需求昂芜,將obj替換成對應(yīng)的具體的類,可想而知需要用到泛型(obj應(yīng)該是T類型的即T obj)泌神。
實現(xiàn)
按照本文最開始的json結(jié)構(gòu)舉例,定義一個實體類如下:
public class Results<T>{
private int resultCode;//結(jié)果碼
private String resultContent;//服務(wù)器端返回的結(jié)果碼說明欢际,可以用于toast顯示
private T Object;//具體的數(shù)據(jù),可以是對象或者list
//getter setter...
}
下面到本文的主角出場了损趋,我一般喜歡用google的Gson作為json的解析工具,本文也已gson作為示例(PS:Gson是個非常強大的工具舶沿,強烈推薦使用)括荡。
定義一個公共方法供外部調(diào)用畸冲,也是解析的主要方法邑闲,代碼如下:
public static Results fromJson(String json, Type clazz) {
Gson gson = new Gson();
Type objectType = type(Results.class, clazz);
return gson.fromJson(json, objectType);
}
下面是type方法的實現(xiàn):
static ParameterizedType type(final Class raw, final Type... args){
return new ParameterizedType() {
public Type getRawType() {
return raw;
}
public Type[] getActualTypeArguments() {
return args;
}
public Type getOwnerType() {
return null;
}
};
}
簡單解釋一下,type方法的作用就是把Results類里面的T類型的變量obj轉(zhuǎn)換成傳入的Type clazz 對應(yīng)的類型,里面的兩個參數(shù)第一個代表包含泛型類的類儡陨,本例中就是Results了;第二個參數(shù)代表的是泛型變量對應(yīng)的具體的類型,需要說明的是如果是list類型的需要通過Gson提供的方法得到正確的type值傳入嫌褪,如果是普通的Object類只需要傳入對應(yīng)類的class即可笼痛,比如User.class
ParameterizedType和Type都是java.lang.reflect包里面的類缨伊,查看源碼可以發(fā)現(xiàn)Type是個接口刻坊,class實現(xiàn)了該接口。
用法
假設(shè)有個User類漏益,包含String id,String name兩個字段绰疤。
1.如果obj對應(yīng)的是List<User>,則對應(yīng)的son解析的用法如下:
Results<List<User>> results=Results.fromJson(json,
new TypeToken<List<User>>() {}.getType());
List<User> list2=results.getObj();
2.如果obj對應(yīng)的是User,則對應(yīng)的json解析的用法如下:
Results<User> results = Results.fromJson(json,User.class);
User user = results.getObj();
總結(jié)與補充
1.本文適用范圍是對于json結(jié)構(gòu)相同或相似的情況,當(dāng)然type方法可以用于很多其他的情況(type方法很強大)余爆。
2.使用Gson解析json需要注意字段名的對應(yīng),Gson提供了@SerializedName("obj")的注解用于解決客戶端與服務(wù)器端實體類字段不一致的問題蛾方。
3.本文實現(xiàn)的效果是對于結(jié)構(gòu)相同或者類似的json提供了更多一層的封裝桩砰,使得開發(fā)者可以只提供obj對應(yīng)的實體類(如果是list只需要提供list包含的類型對應(yīng)的實體類)即可亚隅。
4.大家可以根據(jù)具體的需求在本文的基礎(chǔ)上進行改造懂鸵。
希望本文能為大家提供一種思路或者一種問題的解決方案,對于本文中涉及到的一些說法或者做法醉途,如果有不同見解的或者更好的實現(xiàn)方式的歡迎留言交流隘擎。遇到問題的也可以留言或者聯(lián)系QQ:1654088754货葬。