Android中解析json数据的方式之一:Gson

Android中解析json数据的方式之一:Gson

标签(空格分隔): Android开发 Json数据 Gson解析


Gson简介

Gson是Google推出的开源Java库,主要作用是将JSON格式的数据序列化和反序列化,反序列化后直接就能生成Java对象,解析简单方便高效。

Gson下载地址
http://download.csdn.net/detail/itachi85/8617065

github上的开源gson地址https://github.com/google/gson

Gson的API文档和用户指南以及Gson的设计思路在上面也可以找到。

JSON语法简介

在做解析JSON的工作前,先花一点时间来了解下Json简单的语法。

  • JSON是以键值对的形式来存储数据的,冒号前的是键(在双引号中),后面的是值(在双引号中的是字符串类型),
    "name":"Jack"
  • 对象放在{}中,键值对以逗号相隔。
    {"name":"Jack","age":"20"}
  • 对象的数组放在[]中。
    [{"name":"Jack"},{"name","David"}]
  • 值除了可以是 字符串,数组,对象还可以是数字,布尔值,null等等大部分编程语言都支持的数据类型。
    {"persons":[
    {"name":"Jack"},
    {"name":"David"}
    ],
    "requsetcode":"200"
    }

Gson的使用方法

1. 导入Gson库。
  • 上面的地址下载后可以得到三个文件,但只需要将gson-2.3.1.jar文件放入到项目工作下的libs文件夹下,在Project工程目录中对gson-2.3.1.jar文件右键,点击add as library作为外部库载入即可。
2. 分析json文件嵌套的结构。
  • 出现一个{}代表有一个对象,而Gson解析出这个对象前,首先需要我们定义这个对象的javaBean形式的类。

  • 出现[]代表对象的数组,定义时需要使用List<>来装载对象。比如这个JSON数据:
    {"persons":[ {"name":"Jack"},{"name":"David"}],"requsetcode":"200"}

  • 可以看得出来这是有两层数据,外面{}一层,里面[]一层,所以我们需要定义两个类。
3.按照json分层的结构来定义类。
  • 先定义最外层的类,类名可以任意取,但是成员变量名和内部类的引用名字必须和Json中对应key相同。Gson利了java中的反射机制,使得它在创建对象时可以访问到私有变量。
        public class Response {
            private String requestcode;
            private List persons;

            public String getRequestcode(){
                return requestcode;
            }
            public void setRequestcode(String requestcode){
                this.requestcode = requestcode;
            }
            public List getPersons(){
                return persons;
            }
            public void setPersons(List persons){
                this.persons = persons;
            }
        }
  • 依次定义里面的类。JavaBean形式的类成员变量私有化,通过get,set公共方法来访问内部成员属性。
        public class Person {
            private String name;
            public void setName(String name){
                this.name=name;
            }
            public String getName(){
                return name;
            }
        }
4.调用Gson的库的方法进行解析。
  • 只需要几行代码就能将JSON数据解析成对象了,核心方法是fromJson(),需要两个参数:json格式的字符串和要解析成的目标类型。
        String responseText = "{\"persons\":[ {\"name\":\"Jack\"},{\"name\":\"David\"}]," + "\"requsetcode\":\"200\"}";
        Gson gson = new Gson();
        Response response = gson.fromJson(responseText, Response.class);
        List persons = response.getPersons();
        for (Person p : persons) {
            Log.d("text", "name:" + p.getName());
        }
        Log.d("text", "response:" + response.getRequestcode());
  • 如果解析的是json数组,像下方这种形式,[]在最外面,则需要TpyeToken把想要解析成的目标类型,作为参数传入fromJson()方法。
        [{"name":"Jack"},{"name":"David"}]
        List persens = gson.fromJson(responseText,new TpyeToken>(){}.getType());

使用Gson需要注意的问题

  • 如果在解析过程中出现这样的空指针异常,提示是在空对象引用中出现的。则很可能是成员变量和KEY不匹配,未能生成对象造成的。这时候需要仔细检查目标类里面的变量名是否出错,甚至是划分结构时出了错,定义成员变量的位置到其它无关类去了。
    java.lang.NullPointerException: Attempt to invoke interface method 'java.util.Iterator ``java.util.List.iterator()' on a null object reference

  • 如果json中的key为纯数字或是java中关键字如new时,按照Gson的规则要求成员变量的名称必须和json中的key相同,那么结果可想而知,编译时会报错。这时需要Gson中提供的方法,注解@SerializedName()来标示变量,之后变量名可以任意修改,编译时就不会报错了。如果key不符合java格式规范的话,这方法也可以用来统一java格式上。

        {"persons":[ {"123":"Jack"},{"123":"David"}],"requsetcode":"200"}
        public class Person {
            @SerializedName("123")
            private String name;
            public void setName(String name){
                this.name=name;
            }
            public String getName(){
                return name;
            }
        }
  • 如果读取json格式的文件,是系统自带的记事本创建的,文件中会带有BOM,解析时会出错。需要Notopad++记事本来转换成UTF-8无BOM格式。

配套的代码例程下载地址 http://download.csdn.net/detail/chaosminds/9167745

技术无关的个人后记

这篇技术总结是我在CSDN上第一篇文章,值得纪念一下。我,平日很喜欢来CSDN仰望技术大牛们的博客,一直想有朝一日像他们一样分享高质量的技术文章。但目前还是只学了几个星期从零基础开始的Android小菜鸟,因为最近对稍复杂Json数据的解析时遇到了较大的问题,花了较长的时间多方查找资料才解决问题,于是萌生了写一篇技术总结的想法。平时看博客的不知道写博客辛苦,写这第一篇博客花了我整整一天的时间,用Markdown编辑器,磨了几个小时才熟悉基本用法_(:з」∠)_。写的过程中,为了不误导别人,每写一个我不熟悉的术语都要查找下相关资料,尽量用自己的话描述出来,通过总结发现自己对相关技术的理解也提高了,但最后发现文章显得有些生硬,说明自己的表达方式还需要提高啊。还有考虑到后来的人也会遇到问题,我会把自己使用过程中的遇到问题尽量描述出来,希望能对读者有些价值。以后学习过程中我也会尽量发表原创文章,希望自己能坚持下去,加油(๑•̀ㅂ•́)و✧

你可能感兴趣的:(Android)