Android之json複雜資料解析

一個自學的程式設計師發表於2017-11-22

關於json的介紹這裡不提,我們這次只講如何解析較為複雜的json資料,我會通過案例加導圖的方式將方法鋪展開來向大家闡述!力求讓大家深入瞭解json資料的解析方式!

關於複雜json資料:這裡指的複雜json資料並不是指那種多而雜的資料,而是指json資料不是單一的物件或者陣列,而是包含兩者,我們首先看一下json資料

{
    "data": {
        "count": 5,
        "items": [
            {
                "id": 45,
                "title": "堅果"
            },
            {
                "id": 132,
                "title": "炒貨"
            },
            {
                "id": 166,
                "title": "蜜餞"
            },
            {
                "id": 195,
                "title": "果脯"
            },
            {
                "id": 196,
                "title": "禮盒"
            }
        ]
    },
    "rs_code": "1000",
    "rs_msg": "success"
}

這個json資料包含物件和陣列,兩者是互相穿插的,此次我們就以這個json資料為例進行解析!

首先我先貼上此次解析資料的一個簡易思維導圖,方便大家整體把握。

這裡寫圖片描述

解析json資料的時候大家按照一下三大步驟進行書寫程式碼
1. 獲取json資料
2. 解析json資料
3. 顯示json資料

下面我們新建一個工程JsonDemo
首先我們先建立佈局,佈局很簡單,一個button兩個textview,分別用來點選按鈕開始解析資料,分別顯示原始json資料和解析後的json資料,這裡省去建立程式碼。

接下來我們按照解析的三大步驟進行程式碼書寫,第一步獲取我們需要解析的json資料。
程式碼:

        //獲取json資料
        String json = "{\n" +
                "    \"data\": {\n" +
                "        \"count\": 5,\n" +
                "        \"items\": [\n" +
                "            {\n" +
                "                \"id\": 45,\n" +
                "                \"title\": \"堅果\"\n" +
                "            },\n" +
                "            {\n" +
                "                \"id\": 132,\n" +
                "                \"title\": \"炒貨\"\n" +
                "            },\n" +
                "            {\n" +
                "                \"id\": 166,\n" +
                "                \"title\": \"蜜餞\"\n" +
                "            },\n" +
                "            {\n" +
                "                \"id\": 195,\n" +
                "                \"title\": \"果脯\"\n" +
                "            },\n" +
                "            {\n" +
                "                \"id\": 196,\n" +
                "                \"title\": \"禮盒\"\n" +
                "            }\n" +
                "        ]\n" +
                "    },\n" +
                "    \"rs_code\": \"1000\",\n" +
                "    \"rs_msg\": \"success\"\n" +
                "}";

其實就是將json資料複製過去。獲取到json資料之後我們就開始真正的對資料進行解析了,在此之前為了方便我們解析json資料,我們可以先將json資料進行格式化,隨便百度一搜json資料格式化就會找到很多線上工具。
這裡寫圖片描述
格式化之後如圖,我們發現這樣一來我們對json資料的層次就會看的非常清楚,在解析較為複雜的json資料的時候,關鍵一點就是我們要分析json資料的層次,如此一來我們就可以很方便的觀察json資料的各個層級了,如圖所指+號是可以點選的,展開會顯示下一層級內容,解析來我們看如何分層解析。

重點說明一點,我們解析的時候是對照著格式化之後的json資料進行解析的,因為層級很重要。
第一層解析程式碼:

  //第一層解析
            JSONObject jsonObject = new JSONObject(json);
            JSONObject data = jsonObject.optJSONObject("data");
            int rs_code = jsonObject.optInt("rs_code");
            String rs_msg = jsonObject.optString("rs_msg");

這裡用到原生的JsonObJect,可能你使用的是getxxx而我這裡使用的是optxxx,簡單說明一點,getxxx又可能報空指標異常,在文章末尾會詳細說明,我們繼續第二層解析

//第二層解析
            int count = data.optInt("count");
            JSONArray items = data.optJSONArray("items");

當完成第二層解析之後,現在就只剩下items需要解析了,可以看到,items是一個陣列,陣列中的每一個元素又都是一個json物件,因此我們可以對陣列進行遍歷,看第三層解析

  //第三層解析
            for (int i = 0;i<items.length();i++){
                JSONObject jsonObject1 = items.optJSONObject(i);
                if (jsonObject1 != null){
                    int id = jsonObject1.optInt("id");
                    String title = jsonObject1.optString("title");
                }
            }

至此我們已經將json資料全部解析完成了,但是我們會發現,我們解析到的資料似乎有點亂,使用也有點不方便,接下來我們將解析的json資料封裝成Java物件,這樣使用起來就非常方便了,首先我們需要根據json資料構建一個實體類也即是一個JavaBean,這裡我們可以使用AS的一個外掛GsonForMat可以將json資料一鍵生成JavaBean物件

生成的JavaBean物件我們暫且叫做DataInfo,使用方法也很簡單,安裝好GsonForMat外掛之後重啟as,在新建的DataInfo上右擊選擇Generate然後選擇GsonForMat,將json資料複製進去一直ok下去就可以了。

另外可能有些人對javaBean不太瞭解,我比較認同的一個比較直白的說法是JavaBean就是一個資料包,裡面包含各種屬性,並且提供屬性get和set等方法,可以通過set將資料設定進去,然後需要的時候通過get得到資料,具體的大家可以百度瞭解一下。

生成Javabean之後,我們就要將解析得到的json資料封裝到這個Javabean中,下面開始

 try {
            //第一層解析
            JSONObject jsonObject = new JSONObject(json);
            JSONObject data = jsonObject.optJSONObject("data");
            int rs_code = jsonObject.optInt("rs_code");
            String rs_msg = jsonObject.optString("rs_msg");

            //javabean
            dataInfo.setRs_code(rs_code);
            dataInfo.setRs_msg(rs_msg);
            DataInfo.DataBean dataBean = new DataInfo.DataBean();
            dataInfo.setData(dataBean);


            //第二層解析
            int count = data.optInt("count");
            JSONArray items = data.optJSONArray("items");

            //javabean
            dataBean.setCount(count);
            List<DataInfo.DataBean.ItemsBean> itemBean = new ArrayList<>();
            dataBean.setItems(itemBean);

            //第三層解析
            for (int i = 0;i<items.length();i++){
                JSONObject jsonObject1 = items.optJSONObject(i);
                if (jsonObject1 != null){
                    int id = jsonObject1.optInt("id");
                    String title = jsonObject1.optString("title");

                    //javabean
                    DataInfo.DataBean.ItemsBean bean = new DataInfo.DataBean.ItemsBean();
                    bean.setId(id);
                    bean.setTitle(title);
                    itemBean.add(bean);
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

我們注意理解註釋JavaBean的程式碼,執行上述程式碼之後我們就將json資料解析完成並且將資料封裝到javab中,至此我們就可以通過JavaBean得到我們想要的解析之後的json資料了。

比如,你想單獨拿到rs_code的值,你可以這樣做

String a = dataInfo.getRs_msg();
        mNewTv.setText(a);

再比如你只需要“堅果”這個資料,你可以這樣做

 //拿到“堅果”
        DataInfo.DataBean data = dataInfo.getData();
        List<DataInfo.DataBean.ItemsBean> items = data.getItems();
        DataInfo.DataBean.ItemsBean bean = items.get(0);
        String title = bean.getTitle();
        mOldTv.setText(title);

以上就是拿到具體資料的一些示例,接下來我們完成這個demo,拿到所有資料

//顯示資料
        mOldTv.setText(json);
        mNewTv.setText(dataInfo.toString());

在此之前你需要給你的JavaBean加上toString方法才行。至此大功告成。

現在來總結一下,解析按照三個大步驟
1. 獲取資料
2. 解析資料
3. 顯示資料

當資料較為複雜的時候,我們可以藉助json資料格式化工具將資料格式化,方便我們進行分層解析,將解析的資料封裝到JavaBean方便我們使用。

補充:optxxx和getxxx的區別。
optXxx方法會在對應的key中的值不存在的時候返回一個空字串或者返回你指定的預設值,但是getString方法會出現空指標異常的錯誤。

原始碼已經上傳至CSDN下載原始碼

相關文章