Android Gson解析數組中多種類型

最近空閑時間在一款仿某條的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

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末处硬,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子拇派,更是在濱河造成了極大的恐慌荷辕,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件件豌,死亡現場離奇詭異桐腌,居然都是意外死亡,警方通過查閱死者的電腦和手機苟径,發(fā)現死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門案站,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事蟆盐〕斜撸” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵石挂,是天一觀的道長博助。 經常有香客問我,道長痹愚,這世上最難降的妖魔是什么富岳? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮拯腮,結果婚禮上窖式,老公的妹妹穿的比我還像新娘。我一直安慰自己动壤,他們只是感情好萝喘,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著琼懊,像睡著了一般阁簸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哼丈,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天启妹,我揣著相機與錄音,去河邊找鬼醉旦。 笑死饶米,一個胖子當著我的面吹牛,可吹牛的內容都是我干的髓抑。 我是一名探鬼主播咙崎,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吨拍!你這毒婦竟也來了褪猛?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤羹饰,失蹤者是張志新(化名)和其女友劉穎伊滋,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體队秩,經...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡笑旺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了馍资。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片筒主。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出乌妙,到底是詐尸還是另有隱情使兔,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布藤韵,位于F島的核電站虐沥,受9級特大地震影響,放射性物質發(fā)生泄漏泽艘。R本人自食惡果不足惜欲险,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匹涮。 院中可真熱鬧天试,春花似錦、人聲如沸焕盟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脚翘。三九已至,卻和暖如春绍哎,著一層夾襖步出監(jiān)牢的瞬間来农,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工崇堰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留沃于,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓海诲,卻偏偏與公主長得像繁莹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子特幔,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內容