1. 程式人生 > >Android:使用Gson解析複雜的JSON資料

Android:使用Gson解析複雜的JSON資料

JSON(JavaScript Object Notation) 是一種輕量級的資料交換格式,目前廣泛使用。本文主要講解android如何解析複雜格式的JSON資料,適合android初學者和初步接觸JSON的人。
1.JSON相關介紹:
首先了解一下JSON的相關內容,JSON中的資料是以鍵值對的形式出現的。例如”name”:”jack”;這就是一個鍵值對,可以理解為name=jack。JSON中很重要的兩個概念就是陣列(array)和物件(object),初學者們很容易會把這兩個概念搞錯。區分是陣列還是物件最簡單的辦法就是看是在{ ……}(大括號中),還是在 …… 。Object在大括號中,陣列在中括號中。所有的JSON資料都是建立在陣列和物件的基礎上經過不同的組合而生成的。因此,可以說理解了陣列和物件,就可以解析出各種複雜的JSON資料。
2.Android中使用Gson進行JSON解析。
Android解析JSON資料的方法有很多,例如:原生android的解析方法就是JSONObject和JSONArray,這樣的解析有些繁瑣。還有就是利用第三方的包,本文主要是使用Gson對JSON資料進行解析,當然還有FastJson,這個也很不錯,大家可以試一試。
首先自然要下載GSON包了,這個網上有很多,我就不貼出連線了。下載完GSON包之後匯入到專案中(project),就行了,如圖:
這裡寫圖片描述


這樣就可以使用Gson包了。
3.如何使用GSON解析
解析JSON資料最重要的一步就是根據JSON資料構建出bean檔案,這裡一步一步教大家如何構建出bean檔案。
JSON資料如下:

{
    "showapi_res_code":0,
    "showapi_res_error":"",
    "showapi_res_body":{
        "pagebean":{
            "allNum":577,
            "allPages":29,
            "contentlist":[
                {
                    "channelId
":"5572a108b3cdc86cf39001cd", "channelName":"國內焦點", "desc":"   中國警察網北京4月22日電中國共產黨的優秀黨員,公安部原部長、黨委書記陶駟駒同志,因病醫治無效,於2016年4月18日0時36分在北京逝世, 享年81歲。22日上午,陶駟駒同志遺體送別儀式在北京舉行。  習近平、李克強、劉雲山、張高麗、劉延東、李源潮、孟建柱、趙樂際、胡錦....", "imageurls":[ { "height
":480, "url":"http://n.sinaimg.cn/news/transform/20160423/P7Jb-fxrqhar9853560.jpg", "width":400 } ]
, "link":"http://news.sina.com.cn/c/nd/2016-04-23/doc-ifxrpvea1126476.shtml", "pubDate":"2016-04-23 10:16:54", "source":"新浪", "title":"公安部原部長陶駟駒逝世 習近平胡錦濤等送花圈" }, { "channelId":"5572a108b3cdc86cf39001cd", "channelName":"國內焦點", "desc":"   原標題:山東3縣市購房補錢!繼鄒城、壽光後,即墨也加入資料圖  日前,即墨市制定《關於促進房地產市場持續健康平穩發展的實施意見》,即墨市財政 將對購房者予以補貼。從《意見》出臺之日起到今年年底前,在即墨首次購新建商品房的市民,每平米可領取補貼50到200元。對購....", "imageurls":[ { "height":327, "url":"http://ww4.sinaimg.cn/mw690/77de9208jw1f36aamk03mj20go093406.jpg", "width":600 } ], "link":"http://news.sina.com.cn/c/nd/2016-04-23/doc-ifxrpvea1122744.shtml", "pubDate":"2016-04-23 07:52:13", "source":"新浪", "title":"山東3縣市對購房者予以財政補貼" }, { "channelId":"5572a108b3cdc86cf39001cd", "channelName":"國內焦點", "desc":"   原標題:首家商業火箭公司成立  京華時報訊(記者潘珊菊)昨天下午,記者從航天科工集團獲悉,在成功發射首顆衛星“東方紅一號”46年後,中國航天 技術步入“商用時代”,我國首家商業模式開展研發和應用的專業化火箭公司已於今年2月16日在武漢註冊成立。  據介紹,該公....", "imageurls":[ ], "link":"http://news.sina.com.cn/o/2016-04-23/doc-ifxrpvqz6479220.shtml", "pubDate":"2016-04-23 03:19:35", "source":"新浪", "title":"中國首家商業火箭公司成立 註冊時曾引官方爭議" } ]
, "currentPage":1, "maxResult":20 }
, "ret_code":0 }
}

一步一步來:
這裡寫圖片描述
這是把所有的括號都收起來的樣子
1展開大括號:
這是第一層,我們給一個標記為A。
這裡寫圖片描述
2展開showapi_res_body後面的大括號:
這是第二層,我們給一個標記為B。
這裡寫圖片描述
3展開pagebean後面的大括號:
這是第三層,我們給一個標記為C。
這裡寫圖片描述
4展開contentlist後面的中括號,這是一個數組
這是第四層,我們給一個標記為D。
這裡寫圖片描述
5展開contentlist裡面的object中的大括號
這是第五層,我們給一個標記為E。
這裡寫圖片描述
6展開imageurls的中括號
這是第六層,我們給一個標記為F
這裡寫圖片描述
7展開imageurls裡面object的大括號
這是第七層,我們給一個標記為G
這裡寫圖片描述
到此,所有的括號全部展開,所有的結構也非常清晰。contentlist和imageurls是兩個JSON陣列而且陣列的元素是JSON物件。
下面就開始構建bean檔案了。
首先,建一個包 com.example.bean
包內放的就是bean檔案。
如圖A所示,第一層構建一個類:
1.我們構建一個java類HomeNewsBean

package com.example.bean.homenews;

public class HomeNewsBean {
    private String showapi_res_code;
    private String showapi_res_error;
    private HomeNewsBeanBody showapi_res_body;
    public String getShowapi_res_code() {
        return showapi_res_code;
    }
    public void setShowapi_res_code(String showapi_res_code) {
        this.showapi_res_code = showapi_res_code;
    }
    public String getShowapi_res_error() {
        return showapi_res_error;
    }
    public void setShowapi_res_error(String showapi_res_error) {
        this.showapi_res_error = showapi_res_error;
    }
    public HomeNewsBeanBody getShowapi_res_body() {
        return showapi_res_body;
    }
    public void setShowapi_res_body(HomeNewsBeanBody showapi_res_body) {
        this.showapi_res_body = showapi_res_body;
    }
    @Override
    public String toString() {
        return "HomeNewsBean [showapi_res_code=" + showapi_res_code
                + ", showapi_res_error=" + showapi_res_error
                + ", showapi_res_body=" + showapi_res_body + "]";
    }
}

2.類中HomeNewsBeanBody是第二層B中的類。

package com.example.bean.homenews;

public class HomeNewsBeanBody {
    private HomeNewsPageBean pagebean;
    private String ret_code;
    public HomeNewsPageBean getPagebean() {
        return pagebean;
    }
    public void setPagebean(HomeNewsPageBean pagebean) {
        this.pagebean = pagebean;
    }
    public String getRet_code() {
        return ret_code;
    }
    public void setRet_code(String ret_code) {
        this.ret_code = ret_code;
    }
    @Override
    public String toString() {
        return "HomeNewsBeanBody [pagebean=" + pagebean + ", ret_code="
                + ret_code + "]";
    }
}

3.類中HomeNewsPageBean是第三層C中的類

package com.example.bean.homenews;

import java.util.List;

public class HomeNewsPageBean {
    private String allNum;
    private String allPages;
    private String currentPage;
    private String maxResult;
    private List<HomeNewsContentList> contentlist;
    public String getAllNum() {
        return allNum;
    }
    public void setAllNum(String allNum) {
        this.allNum = allNum;
    }
    public String getAllPages() {
        return allPages;
    }
    public void setAllPages(String allPages) {
        this.allPages = allPages;
    }
    public String getCurrentPage() {
        return currentPage;
    }
    public void setCurrentPage(String currentPage) {
        this.currentPage = currentPage;
    }
    public String getMaxResult() {
        return maxResult;
    }
    public void setMaxResult(String maxResult) {
        this.maxResult = maxResult;
    }
    public List<HomeNewsContentList> getContentlist() {
        return contentlist;
    }
    public void setContentlist(List<HomeNewsContentList> contentlist) {
        this.contentlist = contentlist;
    }
    @Override
    public String toString() {
        return "HomeNewsPageBean [allNum=" + allNum + ", allPages=" + allPages
                + ", currentPage=" + currentPage + ", maxResult=" + maxResult
                + ", contentlist=" + contentlist + "]";
    }
}

4.類中HomeNewsContentList是第和第四層D和第五層E中的類,這裡注意:JSON資料中,這是陣列,因此要使用List來存放。

package com.example.bean.homenews;

import java.util.List;

public class HomeNewsContentList {
    private String channelId;
    private String channelName;
    private String desc;
    private List<HomeNewsImages> imageurls; 
    private String link;
    private String pubDate;
    private String source;
    private String title;
    public String getChannelId() {
        return channelId;
    }
    public void setChannelId(String channelId) {
        this.channelId = channelId;
    }
    public String getChannelName() {
        return channelName;
    }
    public void setChannelName(String channelName) {
        this.channelName = channelName;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
    public List<HomeNewsImages> getImageurls() {
        return imageurls;
    }
    public void setImageurls(List<HomeNewsImages> imageurls) {
        this.imageurls = imageurls;
    }
    public String getLink() {
        return link;
    }
    public void setLink(String link) {
        this.link = link;
    }
    public String getPubDate() {
        return pubDate;
    }
    public void setPubDate(String pubDate) {
        this.pubDate = pubDate;
    }
    public String getSource() {
        return source;
    }
    public void setSource(String source) {
        this.source = source;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    @Override
    public String toString() {
        return "HomeNewsContentList [channelId=" + channelId + ", channelName="
                + channelName + ", desc=" + desc + ", imageurls=" + imageurls
                + ", link=" + link + ", pubDate=" + pubDate + ", source="
                + source + ", title=" + title + "]";
    }
}

5.同理類中HomeNewsImages是第六層F和第七層G中的類,也是List存放。

package com.example.bean.homenews;

public class HomeNewsImages {
    private String height;
    private String url;
    private String width;
    public String getHeight() {
        return height;
    }
    public void setHeight(String height) {
        this.height = height;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getWidth() {
        return width;
    }
    public void setWidth(String width) {
        this.width = width;
    }
    @Override
    public String toString() {
        return "HomeNewsImages [height=" + height + ", url=" + url + ", width="
                + width + "]";
    }
}

到此為止,所有的bean檔案全部構建完畢。
注意:所有的JSON資料的key:value鍵值對中的key要和bean檔案中的物件一一對應,名字要完全一樣!不然無法解析!!!
例如 這裡面的
showapi_res_body要和JSON資料中的 一模一樣。
接下來就是解析的過程了,最難的地方已經過去,接下來就是幾行程式碼的事情了。
首先:傳入URL,傳送http請求,從伺服器獲取JSON資料。

public static String netLink(String URL) {
        HttpClient httpClient = new DefaultHttpClient();
        //訪問指定的伺服器
        HttpGet httpGet = new HttpGet(URL);
        HttpResponse httpResponse = null;
        String response = null;
        try {
            httpResponse = httpClient.execute(httpGet);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if (httpResponse.getStatusLine().getStatusCode() == 200) {
            //200說明請求和響應都是成功的
            HttpEntity entity = httpResponse.getEntity();
            try {
                response = EntityUtils.toString(entity,"utf-8");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return response;
    }

返回的JSON資料在response中。然後,對返回的JSON進行解析。

Gson gson = new Gson();
        HomeNewsBean homeNewsBean = gson.fromJson(response, HomeNewsBean.class);

兩句話完成解析。
我把解析過程寫成了一個函式

public static List<HomeNewsContentList> parseJsonWithGson2(List<HomeNewsContentList> newsLists,String jsonData){
        Gson gson = new Gson();
        HomeNewsBean homeNewsBean = gson.fromJson(jsonData, HomeNewsBean.class);        for(int i = 0;i<homeNewsBean.getShowapi_res_body().getPagebean().getContentlist().size();i++){
            newsLists.add(homeNewsBean.getShowapi_res_body().getPagebean().getContentlist().get(i));
        }
        return newsLists;
    }

這樣JSON資料就存在了List中。到此,解析結束。想要拿出資料只需呼叫newsLists.get()就可以了。
該文的JSON例項應該算比較複雜的JSON資料了,如果能掌握文中的複雜JSON解析,那麼其他的複雜JSON資料解析應該沒有問題。
最後,感謝閱讀,賣個萌o(∩_∩)o 哈哈!