• 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,格式进行优美了一下。


    作者:虾米哥
    微信公众号:IT虾米,左侧为二维码
    个人技术网站-IT虾米网:http://www.itxm.cn
    个人技术网站-编程符号网:http://www.itfh.cn
    个人技术网站-IT源码网:http://www.itym.cn
    新浪微博:https://weibo.com/u/2814576687
    如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号。
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    contentSize、contentInset和contentOffset区别 分类: iphone开发
    iOS设计模式——Category
    如何更好地限制一个UITextField的输入长度
    UIApplication sharedApplication详细解释-IOS
    IOS --- 对象归档
    iOS 数据持久化之使用NSUserDefaults存储数据
    判断素数 一个数的约数 一个整数的幂次约分
    埃氏筛法
    双六(扩展欧几里得算法)
    矩阵快速幂 模板
  • 原文地址:https://www.cnblogs.com/wangyayun/p/15194978.html
Copyright © 2020-2023  润新知