JSON是一種類似 XML的語言,是用了存儲和交換文本信息的語法。它的全稱為JavaScript Object Notation(JavaScript 對象表示法)。與xml對比,它更小、更快,更易解析。
想要更好的解析JSON,必須能看懂JSON數據,這樣就必須了解JSON語法,好在它的語法非常簡單,規則如下:
JSON 語法是 JavaScript 對象表示法語法的子集。
- 數據在名稱/值對中:如 "firstName" : "John" - 數據由逗號分隔 - 花括號保存對象 - 方括號保存數組
而組成JSON的值可以為以下幾種:
- 數字(整數或浮點數) - 字符串(在雙引號中) - 邏輯值(true 或 false) - 數組(在方括號中) - 對象(在花括號中) - null
簡單的回顧了一下JSON之后,我們就開始正式展開JSON解析之旅了。
傳統的JSON解析
最傳統的JSON解析莫過於直接使用java中的方法,它通過原生的JSONObject和JSONArray來解析json數據,下面我們就來解析這段json數據吧!json數據如下:
{ "personData": [ { "age": 12, "name": "nate", "schoolInfo": [ { "School_name": "清華" }, { "School_name": "北大" } ], "url": "http://www.itxm.cn/img3/3413eedb-58a0-4dfb-b446-6a2f9c9892e3.png" }, { "age": 24, "name": "jack", ··· } ], "result": 1 }
分析這段json數據,
第一層是一個花括號括號,即jsonObect對象,然后這個對象里面有一個personData的JSONArray數組,以及一個result屬性 第二層personData的JSONArray數組,它里面除了屬性之外,還有一個schoolInfo的JSONArray數組 第三次是schoolInfo的JSONArray數組里面的JSONObject對象
這時我們已經將這段數據分析好了,接下來就是寫解析方法解析了。
創建一個Httpjson繼承Thread的線程類,它能夠打開URL網址,然后獲取網絡中的JSON數據,在進行JSON解析,代碼如下:
public class Httpjson extends Thread { private String url; private Context context; private ListView listView; private JsonAdapter adapter; private Handler handler; public Httpjson(String url, ListView listView, JsonAdapter adapter, Handler handler) { super(); this.url = url; this.listView = listView; this.adapter = adapter; this.handler = handler; } @Override public void run() { URL httpUrl; try { httpUrl = new URL(url); ··· } /** * 從網絡中獲取JSON字符串,然后解析 * @param json * @return */ private List<Person> jsonParse(String json) { try { List<Person> personlist = new ArrayList<Person>(); JSONObject jsonObject = new JSONObject(json); int result = jsonObject.getInt("result"); if (result == 1) { JSONArray jsonArray = jsonObject.getJSONArray("personData"); for (int i = 0; i < jsonArray.length(); i++) { Person person = new Person(); JSONObject personData = jsonArray.getJSONObject(i); int age = personData.getInt("age"); String url = personData.getString("url"); String name = personData.getString("name"); ··· JSONArray schoolInfoArray = personData.getJSONArray("schoolInfo"); for (int j = 0; j < schoolInfoArray.length(); j++) { JSONObject schoolInfojson = schoolInfoArray.getJSONObject(j); String schoolName = schoolInfojson.getString("School_name"); ··· } ··· } return personlist; } else { Toast.makeText(context, "erro", Toast.LENGTH_SHORT).show(); } } catch (JSONException e) { e.printStackTrace(); Log.e("JsonParseActivity", "json解析出現了問題"); } return null; } }
其中JsonAdapter和Person對象請看項目代碼。
這里將json數據解析出來,然后放入List<Person>集合中供外部使用。
我們按照之前分析來研究這段json解析方法。
首先是一個大括號,我們直接從傳過來的json字符串創建出來的jsonObject就行了,然后就可以通過它獲取result參數,代碼如下:
JSONObject jsonObject = new JSONObject(json); int result = jsonObject.getInt("result");
然后就是解析personData這個json數組,我們直接通過數組名稱獲取,代碼如下:
JSONArray jsonArray = jsonObject.getJSONArray("personData");
再接着就是解析這個數組,解析數組都是用循環解析的,然后這個數組里面先是一個花括號,這又是一個jsonObject對象,代碼如下:
JSONArray jsonArray = jsonObject.getJSONArray("personData"); for (int i = 0; i < jsonArray.length(); i++) { JSONObject personData = jsonArray.getJSONObject(i); int age = personData.getInt("age"); String url = personData.getString("url"); String name = personData.getString("name"); ··· }
在personData這個JSONObject對象中,又有一個schoolInfo的JSONArray數組,我們繼續按照上述方法獲得JSONArray,然后通過for循環獲得里面的JSONObject,這時已達到最底層,我們就可以直接獲取School_name屬性的值了,代碼如下:
for (int j = 0; j < schoolInfoArray.length(); j++) { JSONObject schoolInfojson = schoolInfoArray.getJSONObject(j); String schoolName = schoolInfojson.getString("School_name"); ··· }
這樣,一個完整的JSON數據就解析好了!
當然,這只是解析一個簡單的JSON數據的方法,但是遇到復雜的json數據也可以如此解析,首先是分析JSON數據,然后就是正式解析json。
課后習題:在項目中的res-raw文件夾下,有newjson.txt的json數據,大家可以使用這個來聯系一下json解析。當然啦,這個json數據的傳統解析方式也在項目里面寫好了,如果不懂也可以參考一下!
GSON解析:Gson 是 Google 提供的用來在 Java 對象和 JSON 數據之間進行映射的 Java 類庫。可以將一個 JSON 字符串轉成一個 Java 對象,或者反過來。
這是關於GSON的介紹,相對於傳統的json解析,使用GSON能夠極大的簡化了解析流程。那么該如何使用GSON解析json數據呢?在這里分為以下幾步:
1、在eclipse環境下,將gson的jar包復制到libs中,因為這是Google提供的java類庫,是不存在java自帶的類庫中的。 2、獲取json數據,並且分析。 3、寫出json數據對應的bean類 4、使用gson解析
好了,那我們真是開始解析吧!第一步相信大家都會,只需要在網上找到一個gson的jar包就可以了,所以我們從第二步開始。
從網絡中獲取json數據以及從其他地方獲取數據跟普通的獲取數據沒什么區別,只需要使用IO流進行操作就可以了,我們這里着重的研究如何分析json數據,以及寫出json數據對應的bean類!我們在這里獲取的是res-raw目錄下的mogujson.txt數據,數據如下:
{ "date": "2014-04-23", ··· "name": "蘑菇街", "packageName": "com.mogujie", "safe": [ { "safeDes": "已通過安智市場官方認證,是正版軟件", ··· }, { "safeDes": "已通過安智市場安全檢測,請放心使用", ··· }, { "safeDes": "無任何形式的廣告", ··· } ], "screen": [ "app/com.mogujie/screen0.jpg", ··· ], "size": 6746678, ··· }
由於行文的關系,省略很比較多的數據信息,但是大概的信息已經給出。
首先最外層毫無疑問是一個JSONObject對象,然后里面的date、name可通過JSOnObject直接取出。
第二層對象是safe和screen這兩個數組,然后screen數組里面直接就是一個個的字符串數據,也是可以直接取出的。而safe數組這要通過for循環,獲得里面的JSONObject對象,然后在通過JSONObject對象獲取safeDes等數據。那么現在就開始寫對應的bean類了,如果要寫出能讓gson使用的bean類,其中的key也就是名字,如date、safe這些必須一一對應起來。其次就是在bean類中,遇到花括號就寫一個class類,遇到方括號就寫一個Arraylist數組。這些就是主要規則了!所以最外層的花括號就是一個class類,所以我們創建一個GsonParseMoGuBean類,然后其中又有date、name這些key,所以我們直接寫出它們對應的類型和名稱,代碼如下:
public class GsonParseMoGuBean { public String data; ··· public String name; ··· }
這是最外層的花括號,以及它里面的值,使用GSON解析的時候,它會直接根據json數據中對應的key,也就是data、name這些名字,從json找到對應的key,然后賦值,如果你key名字錯誤,那么就不能獲得相應的數據。然后輪到screen和safe這兩個數組了,screen相對簡單,它里面就是字符串類型的數據,所以我們直接添加String類型的ArrayList就可以了,如下:
public ArrayList<String> screen;
而safe數組就相對復雜它里面是一個個的花括號,也就是一個個的JSONObject對象,在JSONObject對象里面才是數據,那么該如何解析呢?
safe數組中的JSONObject對象是沒有自己的key名字的,而遇到JSONObject對象也就是花括號,就必須是一個class對象,所以我們將這些JSONObject對象對應的class類命名為SafeInfo,而SafeInfo則是放置在safe數組里面的,所以bean類代碼如下:
public ArrayList<SafeInfo> safe; public class SafeInfo { public String safeDes; ··· } }
好的,這個與GSON對應的bean類已經寫好了,那么我們就將詳細的bean類代碼放出來吧:
public class GsonParseMoGuBean { public String data; public String name; public String packageName; ··· public ArrayList<SafeInfo> safe; public class SafeInfo { public String safeDes; ··· } public ArrayList<String> screen; }
值得一說的是這個bean類在被GSON使用的時候,GSON會直接將解析到的數據存到內存中,然后我們可以直接通過GsonParseMoGuBean獲取。而且作為一個bean類,我們不用GSON,而是用JSON的傳統解析方法,這個bean類也是可以用的。寫好對應的bean類,我們就直接使用GSON來解析吧,我們在GsonParseActivity這個Activity類中使用,在點擊bt_mogujson的時候就會開始解析,然后在通過TiextVew控件顯示在屏幕上,用來校驗是否解析正確,代碼如下:
switch (v.getId()) { case R.id.bt_mogujson: // 獲取mogujson中的數據 InputStream inputStream = getResources().openRawResource(R.raw.mogujson); String jsonData = StreamUtils.getDecodeString(inputStream, "utf-8"); // 使用Gson解析 Gson gson = new Gson(); GsonParseMoGuBean mogujie = gson.fromJson(jsonData, GsonParseMoGuBean.class); ArrayList<SafeInfo> safe = mogujie.safe; for (SafeInfo info : safe) { System.out.println(info); } ···· // 顯示部分數據,檢驗是否解析成功 tv_gson.setText(safe.toString()); break; ··· }
我們說看到使用GSON解析就兩行代碼,如下:
Gson gson = new Gson(); GsonParseMoGuBean mogujie = gson.fromJson(jsonData, GsonParseMoGuBean.class);
創建一個GSON對象后,直接用fromJson方法將json數據,已經json數據對應的bean類傳入就可以了!
所以說使用gson解析極大的簡化了解析json的流程!一切只需要兩步,寫對應的bean類,然后使用gson解析就完成了!
關於GSON解析就說到這里總的來說json解析還是相對簡單的,只需要多練習就能夠掌握了。
原文出處:簡書 https://www.jianshu.com/p/6096e6740ac9,格式進行優美了一下。