使用Gson轻松解决复杂结构的Json数据解析

转载请注明来源: http://blog.csdn.net/kjunchen/article/details/50961803

JSON简介

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。JSON 是存储和交换文本信息的语法,类似XML,但是比XML更小、更快,更易解析。


JSON语法

JSON构建于两种结构:

  • “名称/值”对的集合(A collection of name/value pairs)。不同的编程语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。

  • 值的有序列表(An ordered list of values)。在大部分语言中,它被实现为数组(array),矢量(vector),列表(list),序列(sequence)。

对象(object) 是一个无序的“‘名称/值’对”集合。一个对象以“ { ”(左括号)开始,“ } ”(右括号)结束。每个“名称”后跟一个“ : ”(冒号);“‘名称/值’ 对”之间使用“ , ”(逗号)分隔。通过对象.名称获取值,值的类型可以是数字、字符串、数组、对象几种。

数组(array) 是值(value)的有序集合。一个数组以“ [ ”(左中括号)开始,“ ] ”(右中括号)结束。值之间使用“ , ”(逗号)分隔。使用索引获取,值的类型可以是数字、字符串、数组、对象几种。

经过对象、数组两种结构可以组合成复杂的数据结构。

json语法规则是:数据在键值对中,数据由逗号分隔,花括号保存对象,方括号保存数组。

json数据书写格式是:名称/值。名称写在前面,值写在后面,都在双引号中,中间用冒号隔开。如

<code class="language-json hljs  has-numbering"><span class="hljs-string">"name"</span>:<span class="hljs-string">"JunkChen"</span></code><ul style="display: block;" class="pre-numbering"><li>1</li></ul>

json的值可以是:数字(整数或浮点数)、 字符串(在双引号中)、逻辑值(true或false)、 数组(在方括号中)、 对象(在花括号中)、 null


Json数据示例

Json对象

<code class="language-json hljs  has-numbering">{
    "<span class="hljs-attribute">firstName</span>":<span class="hljs-value"><span class="hljs-string">"Junk"</span></span>,
    "<span class="hljs-attribute">lastNmae</span>":<span class="hljs-value"><span class="hljs-string">"Chen"</span></span>,
    "<span class="hljs-attribute">sex</span>":<span class="hljs-value"><span class="hljs-string">"male"</span></span>,
    "<span class="hljs-attribute">age</span>":<span class="hljs-value"><span class="hljs-number">23</span>
</span>}</code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul>

那么,如何取值呢?假设我们给这个对象取名personObj,personObj.firstName = Junk , personObj.age = 23 。

如果用xml表示,如:

<code class="language-xml hljs  has-numbering"><span class="hljs-pi"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-title">person</span>></span>
    <span class="hljs-tag"><<span class="hljs-title">firstName</span>></span>Junk<span class="hljs-tag"></<span class="hljs-title">firstName</span>></span>
    <span class="hljs-tag"><<span class="hljs-title">lastName</span>></span>Chen<span class="hljs-tag"></<span class="hljs-title">lastName</span>></span>
    <span class="hljs-tag"><<span class="hljs-title">sex</span>></span>male<span class="hljs-tag"></<span class="hljs-title">sex</span>></span>
    <span class="hljs-tag"><<span class="hljs-title">sec</span>></span>23<span class="hljs-tag"></<span class="hljs-title">sex</span>></span>
<span class="hljs-tag"></<span class="hljs-title">person</span>></span></code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul>

使用xml描述就比Json显得臃肿,xml中都是标记对形式,数据量肯定比Json大。如果用Json数组表示那就更简单了(如下)。

Json数组

<code class="language-json hljs  has-numbering">[
    <span class="hljs-string">"Junk"</span>,<span class="hljs-string">"Chen"</span>,<span class="hljs-string">"male"</span>,<span class="hljs-number">23</span>
]</code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul>

如果这个数组取名为personArray,则 personArray[0] = Junk, personArray[2] = male 。

复合结构

<code class="language-json hljs  has-numbering">{
    "<span class="hljs-attribute">person</span>":<span class="hljs-value">[<span class="hljs-string">"Junk"</span>,<span class="hljs-string">"Chen"</span>,<span class="hljs-string">"male"</span>,<span class="hljs-number">23</span>]</span>,
    "<span class="hljs-attribute">cat</span>":
    <span class="hljs-value">{
        "<span class="hljs-attribute">name</span>":<span class="hljs-value"><span class="hljs-string">"Jon"</span></span>,
        "<span class="hljs-attribute">age</span>":<span class="hljs-value"><span class="hljs-number">3</span>
    </span>}</span>,
    "<span class="hljs-attribute">province</span>":
    <span class="hljs-value">[{
        "<span class="hljs-attribute">name</span>":<span class="hljs-value"><span class="hljs-string">"广东"</span></span>,
        "<span class="hljs-attribute">cities</span>":<span class="hljs-value">[<span class="hljs-string">"深圳"</span>,<span class="hljs-string">"广州"</span>,<span class="hljs-string">"珠海"</span>]
    </span>},
    {
        "<span class="hljs-attribute">name</span>":<span class="hljs-value"><span class="hljs-string">"陕西"</span></span>,
        "<span class="hljs-attribute">cities</span>":<span class="hljs-value">[<span class="hljs-string">"西安"</span>,<span class="hljs-string">"汉中"</span>,<span class="hljs-string">"咸阳"</span>]
    </span>}]
</span>}  </code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li></ul>

这个示例中,首先是一个Json对象,对象里面包含Json数组,Json数组里面又包含有Json对象,这样就构成了一个复杂结构的Json数据。


使用Gson快速解析Json数据

解析简单的Json数据使用JsonObject和JsonArray还可以,但是遇到复杂结构的Json数据,就很费力了,这时我们可以采用Gson进行Json数据解析。Gson是谷歌推出的Json解析的工具包。接下来就看个实例:

1、导入Gson jar包

下载Gson jar包,新建Java工程将下载jar包导入自己的工程。
Gson 2.6.2 Jar包下载: http://download.csdn.net/detail/kjunchen/9469938   
最新版Gson下载查找:https://github.com/google/gson

2、创建Java Bean类

新建Cat类,如下:
Cat.java

<code class="language-java hljs  has-numbering"><span class="hljs-keyword">package</span> me.jc.gson;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span> {</span>
    <span class="hljs-keyword">private</span> String name;
    <span class="hljs-keyword">private</span> String sex;

    <span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span>() {
        <span class="hljs-keyword">return</span> name;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setName</span>(String name) {
        <span class="hljs-keyword">this</span>.name = name;
    }

    <span class="hljs-keyword">public</span> String <span class="hljs-title">getSex</span>() {
        <span class="hljs-keyword">return</span> sex;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setSex</span>(String sex) {
        <span class="hljs-keyword">this</span>.sex = sex;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-title">Cat</span>(String name, String sex) {
        <span class="hljs-keyword">super</span>();
        <span class="hljs-keyword">this</span>.name = name;
        <span class="hljs-keyword">this</span>.sex = sex;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-title">Cat</span>() {
        <span class="hljs-keyword">super</span>();
    }

    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">public</span> String <span class="hljs-title">toString</span>() {
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Cat [name="</span> + name + <span class="hljs-string">", sex="</span> + sex + <span class="hljs-string">"]"</span>;
    }

}</code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li></ul>

Cat类中设置字段名为name和sex。

新建Dog类,如下:
Dog.java

<code class="language-java hljs  has-numbering"><span class="hljs-keyword">package</span> me.jc.gson;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> {</span>
    <span class="hljs-keyword">private</span> String name;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> age;

    <span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span>() {
        <span class="hljs-keyword">return</span> name;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setName</span>(String name) {
        <span class="hljs-keyword">this</span>.name = name;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getAge</span>() {
        <span class="hljs-keyword">return</span> age;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setAge</span>(<span class="hljs-keyword">int</span> age) {
        <span class="hljs-keyword">this</span>.age = age;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-title">Dog</span>(String name, <span class="hljs-keyword">int</span> age) {
        <span class="hljs-keyword">super</span>();
        <span class="hljs-keyword">this</span>.name = name;
        <span class="hljs-keyword">this</span>.age = age;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-title">Dog</span>() {
        <span class="hljs-keyword">super</span>();
    }

    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">public</span> String <span class="hljs-title">toString</span>() {
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Dog [name="</span> + name + <span class="hljs-string">", age="</span> + age + <span class="hljs-string">"]"</span>;
    }

}</code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li></ul>

Dog类中同样设置字段名为name和sex。

新建Person类,如下:
Person.java

<code class="language-java hljs  has-numbering"><span class="hljs-keyword">package</span> me.jc.gson;

<span class="hljs-keyword">import</span> java.util.Arrays;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> {</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> id;
    <span class="hljs-keyword">private</span> String name;
    <span class="hljs-keyword">private</span> String sex;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">long</span>[] phone;
    <span class="hljs-keyword">private</span> Cat cat;
    <span class="hljs-keyword">private</span> Object object;

    <span class="hljs-keyword">public</span> <span class="hljs-title">Person</span>() {
    }

    <span class="hljs-keyword">public</span> <span class="hljs-title">Person</span>(<span class="hljs-keyword">int</span> id, String name, String sex) {
        <span class="hljs-keyword">super</span>();
        <span class="hljs-keyword">this</span>.id = id;
        <span class="hljs-keyword">this</span>.name = name;
        <span class="hljs-keyword">this</span>.sex = sex;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getId</span>() {
        <span class="hljs-keyword">return</span> id;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setId</span>(<span class="hljs-keyword">int</span> id) {
        <span class="hljs-keyword">this</span>.id = id;
    }

    <span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span>() {
        <span class="hljs-keyword">return</span> name;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setName</span>(String name) {
        <span class="hljs-keyword">this</span>.name = name;
    }

    <span class="hljs-keyword">public</span> String <span class="hljs-title">getSex</span>() {
        <span class="hljs-keyword">return</span> sex;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setSex</span>(String sex) {
        <span class="hljs-keyword">this</span>.sex = sex;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">long</span>[] <span class="hljs-title">getPhone</span>() {
        <span class="hljs-keyword">return</span> phone;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setPhone</span>(<span class="hljs-keyword">long</span>[] phone) {
        <span class="hljs-keyword">this</span>.phone = phone;
    }

    <span class="hljs-keyword">public</span> Cat <span class="hljs-title">getCat</span>() {
        <span class="hljs-keyword">return</span> cat;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setCat</span>(Cat cat) {
        <span class="hljs-keyword">this</span>.cat = cat;
    }

    <span class="hljs-keyword">public</span> Object <span class="hljs-title">getObject</span>() {
        <span class="hljs-keyword">return</span> object;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setObject</span>(Object object) {
        <span class="hljs-keyword">this</span>.object = object;
    }

    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">public</span> String <span class="hljs-title">toString</span>() {
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Person [</span> + sex
                + <span class="hljs-string">", phone="</span> + Arrays.toString(phone) + <span class="hljs-string">", cat="</span> + cat
                + <span class="hljs-string">", object="</span> + object + <span class="hljs-string">"]"</span>;
    }

}</code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li></ul>

Person类中设置字段名为id、name、sex、phone、cat、object,这个Person中包含了Cat对象,还有个Object对象,从而构成了一个相对复杂的对象。到目前为止,似乎好像跟Json没什么关系,那么接下来我们看看如何使用Gson解析Json数据。

注意:

  • 1、如果Java Bean类中有内部嵌套的类必须用static进行修饰;
  • 2、类中的属性名必须跟Json字段里面的名称(Key)是一样的。

3、使用Gson解析Json

新建测试类GsonTest,创建Gson对象,Gson提供toJson()方法将一个JavaBean实例对象转换成Json数据,通过Gson.fromJson()方法将Json数据还原成JavaBean实例对象。

GsonTest.java

<code class="language-java hljs  has-numbering"><span class="hljs-keyword">package</span> me.jc.gson;

<span class="hljs-keyword">import</span> com.google.gson.Gson;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GsonTest</span> {</span>

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(String[] args) {
        Gson gson = <span class="hljs-keyword">new</span> Gson();<span class="hljs-comment">//实例化Gson对象</span>

        Person person = <span class="hljs-keyword">new</span> Person(<span class="hljs-number">1</span>, <span class="hljs-string">"JunkChen"</span>, <span class="hljs-string">"male"</span>);<span class="hljs-comment">//实例化Person对象</span>
        person.setPhone(<span class="hljs-keyword">new</span> <span class="hljs-keyword">long</span>[] { <span class="hljs-number">17802900000</span>l, <span class="hljs-number">17802900001</span>l });
        Cat cat = <span class="hljs-keyword">new</span> Cat(<span class="hljs-string">"wangwang"</span>, <span class="hljs-string">"female"</span>);<span class="hljs-comment">//实例化Cat对象</span>
        Dog dog = <span class="hljs-keyword">new</span> Dog();<span class="hljs-comment">//实例化Dog对象</span>
        dog.setAge(<span class="hljs-number">20</span>);
        person.setCat(cat);
        person.setObject(dog);
        System.out.println(gson.toJson(person));<span class="hljs-comment">//将Person对象转换成Json对象数据</span>
        System.out.println();

        String json = <span class="hljs-string">"{"phone":[17802900000, 17802900001],"id":1,"cat":{"name":"wangwang"},"sex":"female","name":"Junk","object":{"name":"doggg","age":12}}"</span>;<span class="hljs-comment">//Json格式的数据</span>
        Person fromJson = gson.fromJson(json, Person.class);<span class="hljs-comment">//使用Gson将Json数据转换成Person对象</span>
        System.out.println(fromJson.toString());
        System.out.println();

        System.out.println(gson.fromJson(gson.toJson(fromJson.getObject()), Dog.class));
    }
}</code><ul style="display: block;" class="pre-numbering"><li>1<span ></span></li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li></ul>

运行结果如下图所示:
使用Gson轻松解决复杂结构的Json数据解析

OK,如果你之前是使用JsonObjectJsonArray进行Json数据解析的,那么看了这个是不是觉得Json数据解析很简单呢。只要根据Json数据创建相应的Java Bean对象,然后使用Gson轻轻松松搞定Json数据解析。赶快去试试吧。

Json解析的工具类还有很多,除了谷歌Gson外,还有阿里的FastJson也很好用。使用方法大同小异,具体用哪个自己决定。


欢迎加qq群讨论:365532949
HomePage:http://junkchen.com