最近空閑時間在一款仿某條的app冗懦,一開始嫁艇,采用的是api store中的數據源铣缠,但是這樣舵盈,好多功能因為不能得到接口支持不能實現徙缴,因此只能志电。摔寨。闲询。袍祖。底瓣。。通過fiddler抓 某條 的接口了蕉陋。濒持。
在抓一個接口的時候,發(fā)現接口的json格式并不是常規(guī)的json格式寺滚,如下:
{
//字段太多柑营,省略非關鍵部分代碼
"digg_count": 6,
"ordered_info": [{
"data": [{
"link": "鏈接。村视。官套。",
"word": "海南大學"
},
{
"link": "鏈接。蚁孔。奶赔。",
"word": "海南航空"
}
],
"name": "labels"
},
{
"data": {
"like_num": 1312,
"user_like": 0
},
"name": "like_and_rewards"
},
{
"ad_data": "xxxx",
"name": "ad"
},
{
"data": [{
"aggr_type": 1,
"group_id": 6519344328546976260,
"impr_id": "260",
"item_id": 6519344328546976260,
"log_pb": {
"impr_id": "201802241624280100100"
},
"open_page_url": "url",
"title": "阿司匹林腸溶片是終身吃,還是吃一段時間就不吃了杠氢?",
"type_name": ""
},
{
"aggr_type": 1,
"group_id": 6523892928937460231,
"impr_id": "31",
"item_id": 6523892928937460231,
"log_pb": {
"impr_id": "20180224162428010010023222209F57"},
"open_page_url": "url",
"title": "中國戰(zhàn)機不如土耳其站刑?巴鐵為何棄中國戰(zhàn)機而選擇土耳其戰(zhàn)機",
"type_name": ""
}
],
"name": "related_news"
}
]
}
可以發(fā)現,ordered_info是一個數組鼻百,常規(guī)的數組绞旅,里面的bean應該是一樣的字段,但是ordered_info中需要四個bean温艇,有一種比較笨的方法因悲,是寫一個實體類,把所有的字段全部包含進去勺爱,但是如果遇到數據字段特別龐大的時候晃琳,那就呵呵噠了。
仔細觀察ordered_info下的四種類型的數據,會發(fā)現他們有一個共同的字段卫旱,那就是 name
人灼,那就好辦了,可以通過name
這個字段讓程序知道應該用哪個bean去解析顾翼。
首先建立六個bean類:BaseOrderedInfoBean投放、OrderedInfoBean1、OrderedInfoBean2暴构、OrderedInfoBean3跪呈、OrderedInfoBean4段磨、AuthorInfoBean取逾。其中OrderedInfoBeanX是ordered_info數組下的四種類型對應的bean,BaseOrderedInfoBean是其余四個bean類的子類苹支,AuthorInfoBean是最外層json對應的bean砾隅。
public class BaseOrderedInfoBean {
//空類
}
public class OrderedInfoBean1 extends BaseOrderedInfoBean {
private String name;
private List<DataBean> data;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<DataBean> getData() {
return data;
}
public void setData(List<DataBean> data) {
this.data = data;
}
public static class DataBean {
private String link;
private String word;
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
}
public class OrderedInfoBean2 extends BaseOrderedInfoBean {
//具體省略。债蜜。
}
public class OrderedInfoBean3 extends BaseOrderedInfoBean {
//具體省略晴埂。。
}
public class OrderedInfoBean4 extends BaseOrderedInfoBean {
//具體省略寻定。儒洛。
}
注意:AuthorInfoBean 中的數組中必須為BaseOrderedInfoBean
類型,實體類字段名應該通過@SerializedName("")來規(guī)范成java標準命名格式狼速。
public class AuthorInfoBean{
@SerializedName("digg_count")
private int diggCount;
@SerializedName("ordered_info")
private List<BaseOrderedInfoBean> orderedInfos;
public int getDiggCount() {
return diggCount;
}
public void setDiggCount(int diggCount) {
this.diggCount = diggCount;
}
public List<BaseOrderedInfoBean> getOrderedInfos() {
return orderedInfos;
}
public void setOrderedInfos(List<BaseOrderedInfoBean> orderedInfos) {
this.orderedInfos= orderedInfos;
}
}
下面開始最關鍵的反序列化琅锻,需要一個類來實現JsonDeserializer
接口,在里面處理不同的類型數據即可向胡。
public class OrderedInfoDeserializer implements JsonDeserializer<BaseOrderedInfoBean> {
private static final String LABELS = "labels";
private static final String LIKE_END_REWARDS = "like_and_rewards";
private static final String AD = "ad";
private static final String RELATED_NEWS = "related_news";
@Override
public BaseOrderedInfoBean deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
//獲取里面的name字段恼蓬,用作區(qū)分的標志
String name = jsonObject.get("name").getAsString();
switch (name) {
case LABELS:
return new Gson().fromJson(json, OrderedInfoBean1.class);
case LIKE_END_REWARDS:
return new Gson().fromJson(json, OrderedInfoBean2.class);
case AD:
return new Gson().fromJson(json, OrderedInfoBean3.class);
case RELATED_NEWS:
return new Gson().fromJson(json, OrderedInfoBean4.class);
default:
return null;
}
}
}
最后一步,把整個解析器注冊到Gson實例中去:
Gson gson = new GsonBuilder()
.registerTypeAdapter(BaseOrderedInfoBean.class, new OrderedInfoDeserializer())
.create();
由于網絡請求采用的是Retrofit僵芹,因此需要需要設置一下:
new Retrofit.Builder()addConverterFactory(GsonConverterFactory.create(gson)).create();
這樣就能愉快的進行解析了O(∩_∩)O