引言
JSON數(shù)據(jù)現(xiàn)在是我們開發(fā)中用的最多的,百分之八十的數(shù)據(jù)都是通過JSON方式進行傳輸,那么想要學(xué)好JSON解析就要了解什么是JSON數(shù)據(jù),怎么快速解析它從而提升開發(fā)效率。
先看下面,這里有一段JSON數(shù)據(jù),我們根據(jù)這段數(shù)進行講解:
{ "paramz": { "feeds": [ { "id": 299076, "oid": 288340, "category": "article", "data": { "subject": "荔枝新聞3.0:不止是閱讀", "summary": "江蘇廣電旗下資訊類手機應(yīng)用“荔枝新聞”于近期推出全新升級換代的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數(shù)據(jù)就是一段字符串而已,只不過有不同意義的分隔符將其分割開來而已,我們看上面的符號,里面有[] ,{}等符號,其中
1 []中括號代表的是一個數(shù)組;
2 {}大括號代表的是一個對象
3 雙引號“”表示的是屬性值
4 冒號:代表的是前后之間的關(guān)系,冒號前面是屬性的名稱,后面是屬性的值,這個值可以是基本數(shù)據(jù)類型,也可以是引用數(shù)據(jù)類型。
上面用紅框框出來的是我們手動解析最常用的方法了,好了,現(xiàn)在我們想要解析上面的一段數(shù)據(jù),該怎么做呢?這里我寫了一個解析類如下:
public class JsonUtils { /** * 根據(jù)json數(shù)據(jù)解析返回一個List<HashMap<String, Object>>集合 * @param json json數(shù)據(jù) * @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; } }
相信很簡單一看就懂了吧,主要是比較費時間罷了,無非就是幾個方法不停的調(diào)用而已,所以顯得特別的費時費力,下面我又寫了一個解析的方法,方法中會有一些冗余的代碼,是為了更加深刻理解JSON解析而寫的,實際中可以刪掉,也用了一行GSON解析,GSON解析下面會見講到:
其中DataModel對象我是將data對象使用GsonFormat插件工具生成的,使用方式可以自行搜索
public class DataModel { /** * subject : "荔枝新聞3.0:不止是閱讀" * summary : "江蘇廣電旗下資訊類手機應(yīng)用“荔枝新聞”于近期推出全新升級換代的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 + '\'' + '}'; } }
/** * 根據(jù)json對象獲取List<DataModel>集合 * @param json 數(shù)據(jù) * @return */ public static List<DataModel> getGsonList(String json) { List<DataModel> dataList; try { JSONObject rootObject = new JSONObject(json); JSONObject paramzObject = rootObject.getJSONObject("paramz"); /** * JSONArray的構(gòu)造方法獲取JSONArray對象 */ JSONArray jsonArray = new JSONArray(paramzObject.getString("feeds")); Log.i(TAG, "jsonarray.length():"+jsonArray.length()); /** * 獲取JSONObject對象的屬性關(guān)鍵字 */ 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; }
簡單總結(jié)一下上面的解析吧:
1 對于JSONObject對象來說,想要得到一個JSONObject對象通常可以通過
(a):構(gòu)造方式:JSONObject(String json)-> JSONObject rootObject = new JSONObject(json);
(b):JSONObject getJSONObject(String name){}-> JSONObject paramzObject = rootObject.getJSONObject(“paramz”);
2 對于JSONArray對象來說,想要得到一個JSONArray對象通??梢酝ㄟ^
(a):構(gòu)造方式:JSONArray(String json)->JSONArray jsonArray = new JSONArray(paramzObject.getString(“feeds”));
(b):JSONObject getJSONObject(String name){}-> JSONArray feeds = paramzObject.getJSONArray(“feeds”);
我們?nèi)绻昧松厦娴氖謩咏馕龇绞降脑挘敲磳τ贕son解析而言,就太簡單了,下面我們就開始解析下面一段JSON數(shù)據(jù):
{ "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請求回調(diào)中response.body().string()只能有效調(diào)用一次 * */ String string = response.body().string(); Log.i("aaa", "response: " + string); /** * 重新構(gòu)建一個response 因為response.body().string()調(diào)用一次之后流就斷掉了,只能有效調(diào)用一次 */ 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數(shù)據(jù)轉(zhuǎn)換為對象 */ HomeadListModel model = gson.fromJson(string1, HomeadListModel.class); //HomeadListModel model2 = gson.fromJson(string1, new TypeToken<HomeadListModel>() { }.getType()); /** * 將對象轉(zhuǎn)換為json數(shù)據(jù) */ 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數(shù)據(jù)轉(zhuǎn)換為對象的話需要使用fromJson(String json, Class classOfT) /fromJson(String json, Type typeOfT),當我們需要將對象轉(zhuǎn)換為String的時候根據(jù)String toJson(Object src)方法即可。這里需要注意一點,如果response.body().string()調(diào)用大于一次的話,就會報錯java.lang.IllegalStateException: closed,因為因為response.body().string()調(diào)用一次之后流就斷掉了,需要重新構(gòu)建一個response;
這個解析和Gson解析差不多,也是一行就搞定了,也是對上面的Gson數(shù)據(jù)進行解析,想要將json數(shù)據(jù)解析成對象需要使用 parseObject()方法,參數(shù)可以傳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(); /** * 根據(jù)json數(shù)據(jù)獲取對象 */ HomeadListModel model = JSONObject.parseObject(json, new TypeToken<HomeadListModel>() { }.getType()); // HomeadListModel model2 = JSONObject.parseObject(json, HomeadListModel.class); /** * 根據(jù)對象獲取json數(shù)據(jù) */ 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(); } }); } });
結(jié)尾:上面寫了三種解析JSON數(shù)據(jù)的方法,第一種是最麻煩的,但是不一定是最差的,后面兩種Gson和FastJson都是最常用的方法,本博客里面用到的API也是最常用的API,基本開發(fā)都夠用了,其余未涉及到的請自行查看源碼學(xué)習(xí)吧。(完)
聯(lián)系客服