Json常用的解析方式

JSON三種數據解析方法

置頂 Zhou Jiang 2020-05-17 21:49:17  79487  收藏 123
分類專欄: 移動端安卓開發 json解析
版權
引言

JSON數據現在是我們開發中用的最多的,百分之八十的數據都是通過JSON方式進行傳輸,那麼想要學好JSON解析就要了解什麼是JSON數據,怎麼快速解析它從而提升開發效率。

什麼是JSON數據?
先看下面,這裏有一段JSON數據,我們根據這段數進行講解:

{
  "paramz": {
    "feeds": [
      {
        "id": 299076,
        "oid": 288340,
        "category": "article",
        "data": {
          "subject": "荔枝新聞3.0:不止是閱讀",
          "summary": "江蘇廣電旗下資訊類手機應用“荔枝新聞”於近期推出全新升級換代的3.0版。",
          "cover": "/Attachs/Article/288340/3e8e2c397c70469f8845fad73aa38165_padmini.JPG",
          "pic": "",
          "format": "txt",
          "changed": "2015-09-22 16:01:41"
        }
      }
    ],
    "PageIndex": 1,
    "PageSize": 20,
    "TotalCount": 53521,
    "TotalPage": 2677
  }
}


其實JSON數據就是一段字符串而已,只不過有不同意義的分隔符將其分割開來而已,我們看上面的符號,裏面有[] ,{}等符號,其中
1 []中括號代表的是一個數組;
2 {}大括號代表的是一個對象
3 雙引號“”表示的是屬性值
4 冒號:代表的是前後之間的關係,冒號前面是屬性的名稱,後面是屬性的值,這個值可以是基本數據類型,也可以是引用數據類型。
瞭解了JSON數據的格式,怎麼對這段數據進行解析呢?
1 JSONObject系統自帶的解析方式解析,我們先來JSONObject(系統自帶的類)類中的方法:
上面用紅框框出來的是我們手動解析最常用的方法了,好了,現在我們想要解析上面的一段數據,該怎麼做呢?這裏我寫了一個解析類如下:

public class JsonUtils {

    /**
     * 根據json數據解析返回一個List<HashMap<String, Object>>集合
     * @param json  json數據
     * @return
     */
    public static List<HashMap<String, Object>> getJsonList(String json) {
        List<HashMap<String, Object>> dataList;
        dataList = new ArrayList<>();
        try {
            JSONObject rootObject = new JSONObject(json);
            JSONObject paramzObject = rootObject.getJSONObject("paramz");
            JSONArray feedsArray = paramzObject.getJSONArray("feeds");
            for (int i = 0; i < feedsArray.length(); i++) {
                JSONObject sonObject = feedsArray.getJSONObject(i);
                JSONObject dataObject = sonObject.getJSONObject("data");
                String subjectStr = dataObject.getString("subject");
                String summaryStr = dataObject.getString("summary");
                String coverStr = dataObject.getString("cover");
                HashMap<String, Object> map = new HashMap<>();
                map.put("subject", subjectStr);
                map.put("summary", summaryStr);
                map.put("cover", coverStr);
                dataList.add(map);
            }
            return dataList;
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }
}


相信很簡單一看就懂了吧,主要是比較費時間罷了,無非就是幾個方法不停的調用而已,所以顯得特別的費時費力,下面我又寫了一個解析的方法,方法中會有一些冗餘的代碼,是爲了更加深刻理解JSON解析而寫的,實際中可以刪掉,也用了一行GSON解析,GSON解析下面會見講到:

其中DataModel對象我是將data對象使用GsonFormat插件工具生成的,使用方式可以自行搜索

public class DataModel {

    /**
     * subject : "荔枝新聞3.0:不止是閱讀"
     * summary : "江蘇廣電旗下資訊類手機應用“荔枝新聞”於近期推出全新升級換代的3.0版。"
     * cover : "/Attachs/Article/288340/3e8e2c397c70469f8845fad73aa38165_padmini.JPG"
     * pic :
     * format : video
     * changed : 2015-11-07 14:35:22
     */

    public String subject;
    public String summary;
    public String cover;
    public String pic;
    public String format;
    public String changed;

    @Override
    public String toString() {
        return "DataModel{" +
                "subject='" + subject + '\'' +
                ", summary='" + summary + '\'' +
                ", cover='" + cover + '\'' +
                ", pic='" + pic + '\'' +
                ", format='" + format + '\'' +
                ", changed='" + changed + '\'' +
                '}';
    }
}

 /**
     * 根據json對象獲取List<DataModel>集合
     * @param json 數據
     * @return
     */
    public static List<DataModel> getGsonList(String json) {
        List<DataModel> dataList;
        try {
            JSONObject rootObject = new JSONObject(json);
            JSONObject paramzObject = rootObject.getJSONObject("paramz");

            /**
             * JSONArray的構造方法獲取JSONArray對象
             */
            JSONArray jsonArray = new JSONArray(paramzObject.getString("feeds"));
            Log.i(TAG, "jsonarray.length():"+jsonArray.length());

            /**
             * 獲取JSONObject對象的屬性關鍵字
             */
            Iterator<String> iterators = paramzObject.keys();
            while (iterators.hasNext()) {
                Log.i(TAG, "iterators: " + iterators.next());
            }
            JSONArray feeds = paramzObject.getJSONArray("feeds");
            dataList = new ArrayList<>();
            for (int i = 0; i < feeds.length(); i++) {
                JSONObject jsonObject = feeds.getJSONObject(i);
                DataModel model = new Gson().fromJson(jsonObject.getString("data"), new TypeToken<DataModel>() {
                }.getType());
                Log.i(TAG, "DataModel: " + model.toString());
                dataList.add(model);
            }
            return dataList;
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }



簡單總結一下上面的解析吧:
1 對於JSONObject對象來說,想要得到一個JSONObject對象通常可以通過
(a):構造方式:JSONObject(String json)-> JSONObject rootObject = new JSONObject(json);
(b):JSONObject getJSONObject(String name){}-> JSONObject paramzObject = rootObject.getJSONObject(“paramz”);

2 對於JSONArray對象來說,想要得到一個JSONArray對象通常可以通過
(a):構造方式:JSONArray(String json)->JSONArray jsonArray = new JSONArray(paramzObject.getString(“feeds”));
(b):JSONObject getJSONObject(String name){}-> JSONArray feeds = paramzObject.getJSONArray(“feeds”);

2 Gson解析
我們如果懂得了上面的手動解析方式的話,那麼對於Gson解析而言,就太簡單了,下面我們就開始解析下面一段JSON數據:

{
    "homeadlist": [
        {
            "id": 1,
            "imgurl": "/img/homead/a73b3f1d-0f14-429d-9d0f-70643fb0f0eb.jpg",
            "jumpflag": 0,
            "jumpurl": "",
            "posflag": 1,
            "remark": "1111",
            "cityid": 1
        },
        {
            "id": 12,
            "imgurl": "/img/homead/eb442fbf-49db-4ba6-a102-d781505f426d.jpg",
            "jumpflag": 0,
            "jumpurl": "",
            "posflag": 2,
            "remark": "",
            "cityid": 1
        },
        {
            "id": 14,
            "imgurl": "/img/homead/68109460-635d-4c5c-8be8-64d7c7889d18.jpg",
            "jumpflag": 0,
            "jumpurl": "http://shiranlife.kuaizhan.com/",
            "posflag": 4,
            "remark": "",
            "cityid": 1
        }
    ]
}



首先我們使用GsonFormat工具生成一個類HomeadListModel:

public class HomeadListModel {

    /**
     * code : 1
     * data : {"homeadlist":[{"id":1,"imgurl":"/img/homead/a73b3f1d-0f14-429d-9d0f-70643fb0f0eb.jpg","jumpflag":0,"jumpurl":"","posflag":1,"remark":"1111","cityid":1},{"id":12,"imgurl":"/img/homead/eb442fbf-49db-4ba6-a102-d781505f426d.jpg","jumpflag":0,"jumpurl":"","posflag":2,"remark":"","cityid":1},{"id":14,"imgurl":"/img/homead/68109460-635d-4c5c-8be8-64d7c7889d18.jpg","jumpflag":0,"jumpurl":"http://shiranlife.kuaizhan.com/","posflag":4,"remark":"","cityid":1}]}
     */

    public int code;
    public DataBean data;

    public static class DataBean {
        public List<HomeadlistBean> homeadlist;

        public static class HomeadlistBean {
            public int id;
            public String imgurl;
            public int jumpflag;
            public String jumpurl;
            public int posflag;
            public String remark;
            public int cityid;
        }
    }
}


我們使用OKHttpClient,代碼如下

OkHttpClient.Builder builder = new OkHttpClient.Builder();

        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();

        builder.build().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Gson gson = new Gson();
                /**
                 * java.lang.IllegalStateException: closed
                 * 因爲OkHttp請求回調中response.body().string()只能有效調用一次
                 *
                 */

                String string = response.body().string();
                Log.i("aaa", "response: " + string);
                /**
                 * 重新構建一個response 因爲response.body().string()調用一次之後流就斷掉了,只能有效調用一次
                 */
                MediaType mediaType = response.body().contentType();
                Response response1 = response.newBuilder().body(ResponseBody.create(mediaType, string)).build();
                String string1 = response1.body().string();
                Log.i("aaa", "response1: " + string1);
                /**
                 * 將json數據轉換爲對象
                 */
                HomeadListModel model = gson.fromJson(string1, HomeadListModel.class);
                //HomeadListModel model2 = gson.fromJson(string1, new TypeToken<HomeadListModel>() {
                }.getType());
                /**
                 * 將對象轉換爲json數據
                 */
                String jsonString = gson.toJson(model);
                Log.i("aaa", "onResponse2: " + jsonString);

                for (HomeadListModel.DataBean.HomeadlistBean data : model.data.homeadlist) {
                    mData.add(imageUrl + data.imgurl);
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mAdapter.notifyDataSetChanged();
                    }
                });
            }
        });


我們想要將一個json數據轉換爲對象的話需要使用fromJson(String json, Class classOfT) /fromJson(String json, Type typeOfT),當我們需要將對象轉換爲String的時候根據String toJson(Object src)方法即可。這裏需要注意一點,如果response.body().string()調用大於一次的話,就會報錯java.lang.IllegalStateException: closed,因爲因爲response.body().string()調用一次之後流就斷掉了,需要重新構建一個response;
3 FastJson解析
這個解析和Gson解析差不多,也是一行就搞定了,也是對上面的Gson數據進行解析,想要將json數據解析成對象需要使用 parseObject()方法,參數可以傳Class,也可以傳Type;當需要通過對象得到String字符串時候使用String json1 = JSONObject.toJSONString(model)即可,下面貼上代碼:

OkHttpClient.Builder builder = new OkHttpClient.Builder();
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        builder.build().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                String json = response.body().string();
                /**
                 * 根據json數據獲取對象
                 */
                HomeadListModel model = JSONObject.parseObject(json, new TypeToken<HomeadListModel>() {
                }.getType());
//                HomeadListModel model2 = JSONObject.parseObject(json, HomeadListModel.class);

                /**
                 * 根據對象獲取json數據
                 */
                String json1 = JSONObject.toJSONString(model);
                Log.i("aaa", "fastJson: " + json1);

                for (HomeadListModel.DataBean.HomeadlistBean data : model.data.homeadlist) {
                    mData.add(imageUrl + data.imgurl);
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mAdapter.notifyDataSetChanged();
                    }
                });
            }
        });



結尾:上面寫了三種解析JSON數據的方法,第一種是最麻煩的,但是不一定是最差的,後面兩種Gson和FastJson都是最常用的方法,本博客裏面用到的API也是最常用的API,基本開發都夠用了,其餘未涉及到的請自行查看源碼學習吧。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章