JSON數(shù)據(jù)解析只要看這個就夠了

項目地址:
https://github.com/liaozhoubei/HttpAndParse

JSON是一種類似 XML的語言蝴悉,是用了存儲和交換文本信息的語法。它的全稱為JavaScript Object Notation(JavaScript 對象表示法)秘症。與xml對比,它更小、更快荔燎,更易解析贸诚。

想要更好的解析JSON方庭,必須能看懂JSON數(shù)據(jù),這樣就必須了解JSON語法酱固,好在它的語法非常簡單械念,規(guī)則如下:

JSON 語法是 JavaScript 對象表示法語法的子集。
 - 數(shù)據(jù)在名稱/值對中:如 "firstName" : "John"
 - 數(shù)據(jù)由逗號分隔
 - 花括號保存對象
 - 方括號保存數(shù)組

而組成JSON的值可以為以下幾種:

- 數(shù)字(整數(shù)或浮點數(shù))
- 字符串(在雙引號中)
- 邏輯值(true 或 false)
- 數(shù)組(在方括號中)
- 對象(在花括號中)
- null

簡單的回顧了一下JSON之后运悲,我們就開始正式展開JSON解析之旅了龄减。

傳統(tǒng)的JSON解析

最傳統(tǒng)的JSON解析莫過于直接使用java中的方法,它通過原生的JSONObject和JSONArray來解析json數(shù)據(jù)班眯,下面我們就來解析這段json數(shù)據(jù)吧希停!json數(shù)據(jù)如下:

{
    "personData": [
        {
            "age": 12,
            "name": "nate",
            "schoolInfo": [
                {
                    "School_name": "清華"
                },
                {
                    "School_name": "北大"
                }
            ],
            "url": "http://pic.yesky.com/uploadImages/2014/345/36/E8C039MU0180.jpg"
        },
        {
            "age": 24,
            "name": "jack",
            ···
        }
    ],
    "result": 1
}

分析這段json數(shù)據(jù),

  • 第一層是一個花括號括號署隘,即jsonObect對象宠能,然后這個對象里面有一個personData的JSONArray數(shù)組,以及一個result屬性
  • 第二層personData的JSONArray數(shù)組磁餐,它里面除了屬性之外违崇,還有一個schoolInfo的JSONArray數(shù)組
  • 第三次是schoolInfo的JSONArray數(shù)組里面的JSONObject對象

這時我們已經(jīng)將這段數(shù)據(jù)分析好了,接下來就是寫解析方法解析了诊霹。

創(chuàng)建一個Httpjson繼承Thread的線程類羞延,它能夠打開URL網(wǎng)址,然后獲取網(wǎng)絡(luò)中的JSON數(shù)據(jù)畅哑,在進行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);
            ···
    }

    /**
     * 從網(wǎng)絡(luò)中獲取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解析出現(xiàn)了問題");
        }

        return null;
    }
}

其中JsonAdapter和Person對象請看項目代碼荠呐。

這里將json數(shù)據(jù)解析出來赛蔫,然后放入List<Person>集合中供外部使用。

我們按照之前分析來研究這段json解析方法泥张。

首先是一個大括號呵恢,我們直接從傳過來的json字符串創(chuàng)建出來的jsonObject就行了,然后就可以通過它獲取result參數(shù)媚创,代碼如下:

JSONObject jsonObject = new JSONObject(json);
int result = jsonObject.getInt("result");

然后就是解析personData這個json數(shù)組渗钉,我們直接通過數(shù)組名稱獲取,代碼如下:

JSONArray jsonArray = jsonObject.getJSONArray("personData");

再接著就是解析這個數(shù)組,解析數(shù)組都是用循環(huán)解析的鳄橘,然后這個數(shù)組里面先是一個花括號声离,這又是一個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數(shù)組术徊,我們繼續(xù)按照上述方法獲得JSONArray,然后通過for循環(huán)獲得里面的JSONObject鲸湃,這時已達到最底層赠涮,我們就可以直接獲取School_name屬性的值了,代碼如下:

                for (int j = 0; j < schoolInfoArray.length(); j++) {
                    JSONObject schoolInfojson = schoolInfoArray.getJSONObject(j);
                    String schoolName = schoolInfojson.getString("School_name");
                    ···
                }

這樣暗挑,一個完整的JSON數(shù)據(jù)就解析好了笋除!

當然,這只是解析一個簡單的JSON數(shù)據(jù)的方法炸裆,但是遇到復(fù)雜的json數(shù)據(jù)也可以如此解析垃它,首先是分析JSON數(shù)據(jù),然后就是正式解析json晒衩。

課后習(xí)題:在項目中的res-raw文件夾下嗤瞎,有newjson.txt的json數(shù)據(jù),大家可以使用這個來聯(lián)系一下json解析听系。當然啦,這個json數(shù)據(jù)的傳統(tǒng)解析方式也在項目里面寫好了虹菲,如果不懂也可以參考一下靠胜!

GSON解析

Gson 是 Google 提供的用來在 Java 對象和 JSON 數(shù)據(jù)之間進行映射的 Java 類庫”显矗可以將一個 JSON 字符串轉(zhuǎn)成一個 Java 對象浪漠,或者反過來。

這是關(guān)于GSON的介紹霎褐,相對于傳統(tǒng)的json解析址愿,使用GSON能夠極大的簡化了解析流程。

那么該如何使用GSON解析json數(shù)據(jù)呢冻璃?在這里分為以下幾步:

1响谓、在eclipse環(huán)境下,將gson的jar包復(fù)制到libs中省艳,因為這是Google提供的java類庫娘纷,是不存在java自帶的類庫中的。

2跋炕、獲取json數(shù)據(jù)赖晶,并且分析。

3辐烂、寫出json數(shù)據(jù)對應(yīng)的bean類

4遏插、使用gson解析

好了捂贿,那我們真是開始解析吧!第一步相信大家都會胳嘲,只需要在網(wǎng)上找到一個gson的jar包就可以了眷蜓,所以我們從第二步開始。

從網(wǎng)絡(luò)中獲取json數(shù)據(jù)以及從其他地方獲取數(shù)據(jù)跟普通的獲取數(shù)據(jù)沒什么區(qū)別胎围,只需要使用IO流進行操作就可以了吁系,我們這里著重的研究如何分析json數(shù)據(jù),以及寫出json數(shù)據(jù)對應(yīng)的bean類白魂!

我們在這里獲取的是res-raw目錄下的mogujson.txt數(shù)據(jù)汽纤,數(shù)據(jù)如下:

{
    "date": "2014-04-23",
    ···       
    "name": "蘑菇街",
    "packageName": "com.mogujie",
    "safe": [
        {
            "safeDes": "已通過安智市場官方認證,是正版軟件",
            ···
        },
        {
            "safeDes": "已通過安智市場安全檢測福荸,請放心使用",
            ···
        },
        {
            "safeDes": "無任何形式的廣告",
           ···
        }
    ],
    "screen": [
        "app/com.mogujie/screen0.jpg",
        ···
    ],
    "size": 6746678,
    ···
}

由于行文的關(guān)系蕴坪,省略很比較多的數(shù)據(jù)信息,但是大概的信息已經(jīng)給出敬锐。

首先最外層毫無疑問是一個JSONObject對象背传,然后里面的date、name可通過JSOnObject直接取出台夺。

第二層對象是safe和screen這兩個數(shù)組径玖,然后screen數(shù)組里面直接就是一個個的字符串數(shù)據(jù),也是可以直接取出的颤介。而safe數(shù)組這要通過for循環(huán)梳星,獲得里面的JSONObject對象,然后在通過JSONObject對象獲取safeDes等數(shù)據(jù)滚朵。

那么現(xiàn)在就開始寫對應(yīng)的bean類了冤灾,如果要寫出能讓gson使用的bean類,其中的key也就是名字辕近,如date韵吨、safe這些必須一一對應(yīng)起來。其次就是在bean類中移宅,遇到花括號就寫一個class類归粉,遇到方括號就寫一個Arraylist數(shù)組。這些就是主要規(guī)則了吞杭!

所以最外層的花括號就是一個class類盏浇,所以我們創(chuàng)建一個GsonParseMoGuBean類,然后其中又有date芽狗、name這些key绢掰,所以我們直接寫出它們對應(yīng)的類型和名稱,代碼如下:

public class GsonParseMoGuBean {
    
    public String data;
    ···
    public String name;
    ···
    
}

這是最外層的花括號,以及它里面的值滴劲,使用GSON解析的時候攻晒,它會直接根據(jù)json數(shù)據(jù)中對應(yīng)的key,也就是data班挖、name這些名字鲁捏,從json找到對應(yīng)的key,然后賦值萧芙,如果你key名字錯誤给梅,那么就不能獲得相應(yīng)的數(shù)據(jù)。

然后輪到screen和safe這兩個數(shù)組了双揪,screen相對簡單动羽,它里面就是字符串類型的數(shù)據(jù),所以我們直接添加String類型的ArrayList就可以了渔期,如下:

public ArrayList<String> screen;

而safe數(shù)組就相對復(fù)雜它里面是一個個的花括號运吓,也就是一個個的JSONObject對象,在JSONObject對象里面才是數(shù)據(jù)疯趟,那么該如何解析呢拘哨?

safe數(shù)組中的JSONObject對象是沒有自己的key名字的,而遇到JSONObject對象也就是花括號信峻,就必須是一個class對象倦青,所以我們將這些JSONObject對象對應(yīng)的class類命名為SafeInfo,而SafeInfo則是放置在safe數(shù)組里面的站欺,所以bean類代碼如下:

public ArrayList<SafeInfo> safe;

public class SafeInfo {
    public String safeDes;
    ···
    }
    
}

好的姨夹,這個與GSON對應(yīng)的bean類已經(jīng)寫好了,那么我們就將詳細的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會直接將解析到的數(shù)據(jù)存到內(nèi)存中,然后我們可以直接通過GsonParseMoGuBean獲取峭沦。而且作為一個bean類贾虽,我們不用GSON,而是用JSON的傳統(tǒng)解析方法吼鱼,這個bean類也是可以用的蓬豁。

寫好對應(yīng)的bean類,我們就直接使用GSON來解析吧~

我們在GsonParseActivity這個Activity類中使用菇肃,在點擊bt_mogujson的時候就會開始解析地粪,然后在通過TiextVew控件顯示在屏幕上,用來校驗是否解析正確琐谤,代碼如下:

switch (v.getId()) {
    case R.id.bt_mogujson:
        // 獲取mogujson中的數(shù)據(jù)
        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);
        }
        ····
        // 顯示部分數(shù)據(jù)蟆技,檢驗是否解析成功
        tv_gson.setText(safe.toString());

        break;
···
}

我們說看到使用GSON解析就兩行代碼,如下:

        Gson gson = new Gson();
        GsonParseMoGuBean mogujie = gson.fromJson(jsonData, GsonParseMoGuBean.class);

創(chuàng)建一個GSON對象后,直接用fromJson方法將json數(shù)據(jù)质礼,已經(jīng)json數(shù)據(jù)對應(yīng)的bean類傳入就可以了旺聚!

所以說使用gson解析極大的簡化了解析json的流程!一切只需要兩步眶蕉,寫對應(yīng)的bean類砰粹,然后使用gson解析就完成了!

關(guān)于GSON解析就說到這里造挽,這里也給出一個課后練習(xí)給大家碱璃。

課后練習(xí):在res-raw目錄下,有newjson.txt的json數(shù)據(jù)給大家解析饭入,當然嵌器,這也給出了參考答案,在GsonParseActivity中圣拄。還有一個bilibili.txt的json數(shù)據(jù)則沒有答案嘴秸,需要大家自己解析!

json解析還是相對簡單的庇谆,只需要多練習(xí)就能夠掌握了~~

項目地址:
https://github.com/liaozhoubei/HttpAndParse

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末岳掐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子饭耳,更是在濱河造成了極大的恐慌串述,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寞肖,死亡現(xiàn)場離奇詭異纲酗,居然都是意外死亡,警方通過查閱死者的電腦和手機新蟆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門觅赊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人琼稻,你說我怎么就攤上這事吮螺。” “怎么了帕翻?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵鸠补,是天一觀的道長。 經(jīng)常有香客問我嘀掸,道長紫岩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任睬塌,我火速辦了婚禮泉蝌,結(jié)果婚禮上歇万,老公的妹妹穿的比我還像新娘。我一直安慰自己梨与,他們只是感情好堕花,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著粥鞋,像睡著了一般缘挽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上呻粹,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天壕曼,我揣著相機與錄音,去河邊找鬼等浊。 笑死腮郊,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的筹燕。 我是一名探鬼主播轧飞,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼撒踪!你這毒婦竟也來了过咬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤制妄,失蹤者是張志新(化名)和其女友劉穎掸绞,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耕捞,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡衔掸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了俺抽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敞映。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖磷斧,靈堂內(nèi)的尸體忽然破棺而出驱显,到底是詐尸還是另有隱情,我是刑警寧澤瞳抓,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站伏恐,受9級特大地震影響孩哑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜翠桦,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一横蜒、第九天 我趴在偏房一處隱蔽的房頂上張望胳蛮。 院中可真熱鬧,春花似錦丛晌、人聲如沸仅炊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抚垄。三九已至,卻和暖如春谋逻,著一層夾襖步出監(jiān)牢的瞬間呆馁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工毁兆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留浙滤,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓气堕,卻偏偏與公主長得像纺腊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子茎芭,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容