JSON格式數據解析看這一個就足夠了


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,格式進行優美了一下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM