JSON数据解析只要看这个就够了

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

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://pic.yesky.com/uploadImages/2014/345/36/E8C039MU0180.jpg"
        },
        {
            "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解析就说到这里,这里也给出一个课后练习给大家。

课后练习:在res-raw目录下,有newjson.txt的json数据给大家解析,当然,这也给出了参考答案,在GsonParseActivity中。还有一个bilibili.txt的json数据则没有答案,需要大家自己解析!

json解析还是相对简单的,只需要多练习就能够掌握了~~

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容