JSON数据的格式和解析(使用GSON)入门

本文是为初学者准备的JSON数据解析入门指南,主要介绍了JSON的基本格式和使用GSON在Java中解析JSON数据的方法。通过实例展示了如何建立与JSON数据对应的类,以及如何进行JSON数据与对象的转化。文章强调了数据结构与类结构的一致性,并提供了简单的示例代码。

序:本文的读者对象可以是第一次接触Json数据并且想用Gson来简单实现Json数据的解析(Json数据可以转化成对象,对象亦可转化成Json数据)的新手,也可以是已有工作经验并不吝赐教的前辈。如果你是苦苦寻找更好地技术,正如本文标题所言,这篇文章可能不适合你。希望本篇能为新手们带来“众里寻他千百度,蓦然回首,那人却在灯火阑珊处”的发现,也能为有经验的前辈们带来那时年少的感觉。衷心希望你是耐心地愉快地读完本文!

0 偶遇JSON

{
    “flag”:”00”,
    “message”:”传感器”,
    “property“:{“voltage”:”10V”,
               “current”:”5A”},
    “sensors”:[{“Date”:”time”,
             ”id”:”1527”}],
 }

在这里还可见到更多的他:
http://www.tlink.io/web/developer-documentation-all.htm?type=1#api_1

1 认识JSON格式

    JSON数据本质上是一种字符串,不过这个字符串有其特定的格式,一种分层形式的格式。最基本(最内层)的格式是键值对模型(如果不明白的话可以看看本文后面的附1,也可以在网上搜索相关内容,不过即使现在不清楚也不用着急,这不影响你理解JSON的数据形式),只是键需要被双引号包围,如:”Name0”:”lixiaobing0”,其中Name0为键,lixiaobing0为值,键和值都是自己定义的。这就是基本形式,为了下面的叙述的方便,以自己定义的符号base-type来代替”Name0”:”lixiaobing0”这个基本形式,这种代替是为了更方便地了解到JSON数据的全貌。于是细心的我们会看到,一个JSON数据里可以不止一个基本形式,可以有许多个,不过这些个基本形式之间要以逗号(,)分隔的,比如:base-type,base-type,┅。

    如果将视野放得开阔点就会看到,这些基本形式可以被花括符{}或者中括号[]包围,如:{base-type}或者[base-type]。当然也可以被{}和[]同时包围,如:[{base-type}],但同时也要注意到,[{base-type}]形式里也可以有多个{base-type}形式,这些个{base type}形式之间以逗号(,)分隔,如:[{base-type},{base-type},{base type},┅],这和一个JSON数据里有多个基本形式是一样的。

    通常,我们称被{}包围的数据为一个对象,被[]包围的数据我们成为数组,有一点要明白,不同对象的键都是一样的,不同的只是值,正如不同的人有不同性格爱好以及身高体重罢了。好了,我们跳出符号[]的限制,来到[]的外边看看,我们又会惊奇的发现这样的形式,”my_Array”:[{base-type},{base-type},{base type},┅],和这样的形式,”Object”:{base-type,base-type,┅},确实挺有意思,细细一看这不正和基本形式保持了一致吗。于是,用符号Array[]来代替”my_Array”:[{base-type},{base-type},{base-type},┅],用符号Object{}来代替”Object”:{base-type,base-type,┅}后,我们就看到了最外层的情况是这样的{ Object{},Array[],base-type}。

    最外层的{}符号不能少,并且符号{} 里的Array[]、base-type和Object{}的数量都是任意的,可以为零,也可很多,也没什么顺序,更重要的是,Array[]和Object{}可以相互融合,做到你中有我,我中有你,即:Array[Object{}],Object{Array[]},这也被称为嵌套,嵌套可以多层,就像你的镜里有我的镜,我的镜里有你,镜里的还是镜,如此反复映射,不过嵌套多少层,映射多少次,当然这些都要视具体情况而定。注意到了吗,视具体情况而定,毕竟数据要用在某个场合里,至于如何用JSON数据这个问题将在后面JSON数据解析的部分讲解,这里还得举举JSON数据格式的例子,让我们具体感受一下JSON的魅力。

    我会从简单到复杂,从单层到多层的顺序来举例子,因为这样也是符合人接受新事物的顺序。这些例子我是站在最基本形式的角度来阐述的,你也可以把自己当做最基本的形式,这样就可以经历一次有趣的旅程了。

1.1 最简洁的JSON数据(我也称为孤单的基本形式)
{”Name0”:”lixiaobing0”}
1.2 不再孤单的基本形式
{
    ”Name0”:”lixiaobing0”
    ”Name1”:”lixiaobing1”,
    ”Name2”:”lixiaobing2”,
     ... ...
}
1.3 从未见过的新伙伴age_Array
{
    ”age_Array”:[{”Age0”:”beautiful_24”}],
    ”Name0”:”lixiaobing0”
    ”Name1”:”lixiaobing1”,
    ”Name2”:”lixiaobing2”,
    ... ...
}
1.4 新伙伴不止秀一面
{
    ”age_Array”:[{”Age0”:”beautiful_24”,
                  ”Age1”:”terrible_24”,
                  ”Age2”:”wonderful_24”,
                   ... ...}],
    ”Name0”:”lixiaobing0”
    ”Name1”:”lixiaobing1”,
    ”Name2”:”lixiaobing2”,
    ... ...
}
1.5 好多的新伙伴哇
{
    ”age_Array”:[{”Age0”:”beautiful_24”,
                   ”Age1”:”terrible_24”,
                   ”Age2”:”wonderful_24”,
                    ... ...
                    },
                    {”Age0”:”beautiful_23”,
                     ”Age1”:”terrible_23”,
                     ”Age2”:”wonderful_23”,
                     ... ...
                    },
                ... ...],
    ”Name0”:”lixiaobing0”
    ”Name1”:”lixiaobing1”,
    ”Name2”:”lixiaobing2”,
    ... ...
}
1.6 基本形式商量着结盟了
{
        ”age_Array”:[{”Age0”:”beautiful_24”,
                        ”Age1”:”terrible_24”,
                        ”Age2”:”wonderful_24”,
                        ... ...},
                     {”Age0”:”beautiful_23”,
                        ”Age1”:”terrible_23”,
                        ”Age2”:”wonderful_23”,
                        ... ...},
                    ... ...],
        ”Name0”:{”Name00”:”lixiaobing00”
                  ”Name01”:”lixiaobing01”,
                  ”Name02”:”lixiaobing02”,
                  ... ...},
        ”Name1”:{”Name13”:”lixiaobing13”
                  ”Name14”:”lixiaobing14”,
                  ”Name15”:”lixiaobing15”,
                  ... ...},
   ... ...
}
1.7 原来新伙伴深藏不露
{
   ”age_Array”:[{”Hide_age_Array”:[{
                                ”HeepAge0”:”H_beautiful_24”,
                                ”HeepAge1”:”H_terrible_24”,
                                ... ...},
                              {”HeepAge0”:”H_beautiful_23”,
                               ”HeepAge1”:”H_terrible_23”,
                                ... ...},
                            ... ...],
                                     ... ...},
                {”Age0”:”beautiful_24”,
                  ”Age1”:”terrible_24”,
                  ”Age2”:”wonderful_24”,
                 ... ...},
                {”Age0”:”beautiful_23”,
                  ”Age1”:”terrible_23”,
                  ”Age2”:”wonderful_23”,
                   ... ...},
             ... ...],
    ”Name0”:{”Name00”:”lixiaobing00”
             ”Name01”:”lixiaobing01”,
             ”Name02”:”lixiaobing02”,
              ... ...},
    ”Name1”:{”Name13”:”lixiaobing13”
              ”Name14”:”lixiaobing14”,
              ”Name15”:”lixiaobing15”,
              ... ...},
    ... ...
}
1.8 我们都拿着一把镜子一起玩耍
{
   ”age_Array”:[{”Hide_age_Array”:[{”HeepAge0”:”H_beautiful_24”,    
                                 ”HeepAge1”:”H_terrible_24”,
                                ... ...},                                               
                                HeepAge0”:”H_beautiful_23”,                                                                           
                                ”HeepAge1”:”H_terrible_23”,
                                ... ...},
                                ... ...],
                    ... ...},
                {”Age0”:”beautiful_24”,
                 ”Age1”:”terrible_24”,
                 ”Age2”:”wonderful_24”,
                  ... ...},
                {”Age0”:”beautiful_23”,
                 ”Age1”:”terrible_23”,
                 ”Age2”:”wonderful_23”,
                  ... ...},
                ... ...],
  ”Name0”:{”Name00”:[{”Name_Age00”:”lixiaobing00_24”,
                     ”Name_Age01”:”lixiaobing01_24”,
                      .. ...},
                     {”Name_Age00”:”lixiaobing00_23”,
                      ”Name_Age01”:”lixiaobing01_23”,
                      ... ...},
                    ... ...],
          ”Name01”:”lixiaobing01”,
          ”Name02”:”lixiaobing02”,
            ... ...},
  ”Name1”:{”Name13”:[{”Name_Age10”:”lixiaobing10_24”,
                    ”Name_Age11”:”lixiaobing11_24”,
                    ... ...},
                    {”Name_Age10”:”lixiaobing10_23”,                                                                 
                    ”Name_Age11”:”lixiaobing11_23”,
                     ... ...},
                    ... ...],
            ”Name14”:”lixiaobing14”,
            ”Name15”:”lixiaobing15”,
            ... ...},
... ...
}

    注:这里再说明一下,JSON中值(value)存在的数据类型可以是数字型(整数或浮点数),字符串型,逻辑值型(true/false),数组,对象,或者为空。

2 GSON解析JSON数据

    本文采用JAVA语言编程,使用Google的GSON类库里的方法,在eclipse集成环境里来析JSON数据,当然需要再建的的项目里导入GSON包,至于如何导入可参考百度里的经验。这里解析数据正如我们吃西瓜一样,一刀一刀地去切或是一勺一勺地取,只要方法对了,不管怎样,西瓜会越来越少(数据会越来越简单),直到最后整个西瓜都到我们的肚子里去了。既然是使用类库的方法就解析了JSON数据,那我们要干些什么事呢?我们干的事自然是在解析数据之前我们得确立规则,即确立JSON数据对应着怎样的类,这就好比确立怎么切怎么或取西瓜。不废话了,开始来解析数据咯!

2.1 建立与JSON数据对应的类

    规则:基本形式base-type定义成类中的字段。

               形式Object{}定义成一个类Object,形式Array[{}]里的对象{}定义成一个类Array。

               形式Object{Array[]}定义为有个字段为数组或列表的类Object。

               整个{ Object{},Array[],base-type}定义成一个主类Example。

               注:类中字段的名字要和JSON数据键的写法保持一致。

    目的 : 要使构建的类之间的组织结构与JSON数据的结构保持一致。

    举例:

    还是用最初偶遇到的那个JSON举例吧,只是改动了一下,在property里嵌套了个数组,增加了结构的复杂性,这样可以具有一般的参考性。

   {
    “flag”:”00”,
    “message”:”传感器”,
    “property”:{“electricity”:[{
                            “voltage”:”10V”,
                            “current”:”5A”}],
                “temp”:”temperature”},
    “sensors”:[{“Date”:”time”,
                “id”:”9527”}]                       
    }

    这里,从里向外依次定义类,首先定义类Electricity,Electricity类有两个字符串型的字段voltage和current。定义类Property,这个类有一个字符串型String的字段temp和要装载Electricity类的列表electricity。然后接着定义类Sensor,也有两个字符串型的字段Date和id,最后整个JSON数据建立一个类,取名为Example,包含字符串型String的字段flag和message,以及Property类型的property字段和装载Sensors类型对象的列表sensors。类定义时,要特别注意Json数据中的键名和类中的字段名的书写要对应,不然在解析的时候会报异常。好了,具体的类定义如下所示:

####2.1.1 类Electricity:
public class Electricity {

    private String voltage;
    private String current;

    public Electricity() {
        super();
    }

    public Electricity(String voltage, String current) {
        super();
        this.voltage = voltage;
        this.current = current;
    }

    public String getVoltage() {
        return voltage;
    }

    public void setVoltage(String voltage) {
        this.voltage = voltage;
    }

    public String getCurrent() {
        return current;
    }

    public void setCurrent(String current) {
        this.current = current;
    }

    @Override
    public String toString() {
        return "Electricity [voltage=" + voltage + ", current=" + current+"]";
    }

}
####2.1.2 类Property
public class Property {

    private List <Electricity> electricity;
    private String temp;

    public Property() {
        super();
    }

    public Property(List<Electricity> electricity, String temp) {
        super();
        this.electricity = electricity;
        this.temp = temp;
    }

    public List<Electricity> getElectricity() {
        return electricity;
    }

    public void setElectricity(List<Electricity> electricity) {
        this.electricity = electricity;
    }

    public String getTemp() {
        return temp;
    }

    public void setTemp(String temp) {
        this.temp = temp;
    }

    @Override
    public String toString() {
        return "Property [electricity=" + electricity + " temp="+temp+"]";
    }

}
####2.1.3 类Sensor
public class Sensor {

    private String Date;
    private String id;

    public Sensor() {
        super();
    }

    public Sensor(String date, String id) {
        super();
        Date = date;
        this.id = id;
    }

    public String getDate() {
        return Date;
    }

    public void setDate(String date) {
        Date = date;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Sensor [Date=" + Date + ", id=" + id + "]";
    }

}
####2.1.4 类Example
public class Example {

    private String flag;
    private String message;
    private Property property;
    private List<Sensor> sensors;

    public Example() {
        super();
    }

    public Example(String flag, String message, Property property,
            List<Sensor> sensors) {
        super();
        this.flag = flag;
        this.message = message;
        this.property = property;
        this.sensors = sensors;
    }

    public String getFlag() {
        return flag;
    }

    public void setFlag(String flag) {
        this.flag = flag;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Property getProperty() {
        return property;
    }

    public void setProperty(Property property) {
        this.property = property;
    }

    public List<Sensor> getSensors() {
        return sensors;
    }

    public void setSensors(List<Sensor> sensors) {
        this.sensors = sensors;
    }

    @Override
    public String toString() {
        return "Example [flag=" + flag + ", message=" + message + ", property="
                + property + ", sensors=" + sensors + "]";
        }   
     }

    好了,该定义的类都定义完了,接下来就是第二步了,定义运行程序的主类Example_Test。

2.2 JSON数据与对象的转化

2.2.1 运行程序的主类Example_Test:
public class ExampleTest {         
    public static void main(String[] args) {                
     String json = "{\"flag\":\"00\",\"message\":\"传感器\"," +"\"property\"   {\"electricity\":[{\"voltage\":\"10V\",\"current\":\"5A\"   }],\"temp\":\"temperature\"},"  +"\"sensors\":[{\"Date\":\"time\",\"id\":\"9527\"}]}";

        Gson gson = new Gson(); //创建Gson类的对象
        Example example = new Example(); //创建与json数据对应的类的对象
        example = gson.fromJson(json, Example.class); //将json数据解析成对象

        System.out.println(example.getFlag());
        System.out.println(example.getMessage());
        System.out.println(example.getProperty());
        System.out.println(example.getSensors().toString());

        String json1 = gson.toJson(example); //将对象解析成Json数据
        System.out.println(json1);

    }
}

    注意:与JSON数据相对应的类Electricity、Property、Sensor、Example建议放在同一个包里,如果没放在同一个包里,应在Example那个类里导入相应的类Electricity、Property、Sensor,导入的形式为:import another. Electricity,这里another为存放类Electricity的包。另外,类Electricity、Property、Sensor也可以作为类Example的内部类。这里使用简单形式的内部类就可以了,至于有关内部类的知识,在这里就不详谈了,读者可参考Java入门书籍。

2.2.2 程序运行结果:
    00
    传感器
    Property [electricity=[Electricity [voltage=10V, current=5A]] temp=temperature]
    [Sensor [Date=time, id=9527]]
    {"flag":"00","message":"传感器","property":{"electricity":[{"voltage":"10V","current":"5A"}],"temp":"temperature"},"sensors":[{"Date":"time","id":"9527"}]}

    运行结果中,前四行是JSON数据转化为对象后通过get()方法获得的字段,最后一行是把对象转化为JSON字符串,和开始的那个JSON数据字符串一样,也说明了GSON已成功解析了这个JSON字符串。

    本运行程序的主类Example_Test还有值得完善的地方,比如如果JSON数据是非常多的时候就不能在程序里直接写JSON数据,需要使用文件流来读取。还有一个值得完善的地方是考虑异常的情况,常见的异常如:JSON数据的格式错误,JSON数据的键名和对象的字段名不相匹配等等。JSON数据的解析方法不止使用GSON,还有JSONObject和JSONArray类,这个同样需要导入相应的包,当然你可以去试试。

    通常的情况下,人们不会通俗的说将JSON数据转化为对象这一过程,或者将对象转化为JSON数据,人们更多提到的是序列化和反序列化(如果暂时不清楚的话也没关系,因为在多次打交道后就会慢慢理解了,也可参考http://kb.cnblogs.com/page/515982/)。在这里,如果不要求严格地概念的话,也可通俗地把对象转化为JSON数据这一过程叫做序列化,把JSON数据转化为对象叫做反序列化。

    当你看到这里的时候是不是认识到使用Gson类来解析JSON数据没什么难度了呢,就两步而已,第一步先定义与GSON数据格式对应的类,第二步在主类中使用gson.fromJson()和gson.toJson()方法就可以实现JSON数据和对象之间的转换了。最后再说明一下,本文的源码的下载地址可在本文尾部的附2里找到,以供参考。

3 终点与起点

    到了这次旅程的终点了,也许现在你已是兴趣盎然,打算迈进新的旅途,这里我提供了有关JSON数据及GSON的一些驿站,希望对你有所帮助:

http://jsonapi.org.cn/format/
http://www.json.org/json-zh.html
https://github.com/google/gson
http://www.w3school.com.cn/json/json_intro.asp
http://baike.baidu.com/link?url=TOZY8cSwFBQc0011WK7ccHd6umlhXGTqo6YKaLKGVaZBEBI uSjVCn3Sg8D_tEQcg39ZMsiljA2Z095H2GzJ4_
http://www.cnblogs.com/tianzhijiexian/p/4246497.html

附1    键值对模型简要:键盘上的一个键对应着一个符号,每个人都对应着一个名,每一个公司的名字都对应着一个图标(Logo),每一把钥匙都对应着一把锁等等,像这之类的数据形式被称为键值对Key/Value,键值对模型本质上是一种一一映射的关系模型。在JSON数据中,键值对模型的格式为 “Key”:Value,其中值取值可以是数字(整数/浮点数)、字符串、逻辑值(true/false)、数组、对象或者空null。 键(Key)和值(Value)的书写格式可参考程序的命名规则。

附2    本文源码地址1:http://download.youkuaiyun.com/detail/huangdoudecsdn/9466453,名称叫做Gson解析JSON数据的入门级源码。
       本文源码地址2:http://pan.baidu.com/s/1eRefHBG , 这是一个名称为GsonExplainJson的压缩包。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值