使用Gson解析json

什么是json?

简单来说,json就是用来进行网络数据传输的一种格式,目前的使用很广泛,其格式就是一种键值对的形式,很方便进行解析。json有JsonObject和JsonArray两种形式,如何进行区分呢?

凡是看到 { 就是一个JsonObject
凡是看到 [ 就是一个JsonArray
牢记以上两点可以减少很多解析json过程中的问题

什么是Gson?

Gson是谷歌开发的一个用来解析json的库,简单好用。源码可见github而且里面还有详细的说明文档。

如何使用Gson?

首先需要根据json的格式来定义对应的bean。有下面的几种情况:

1. JsonObejct

如下面的json,是一个JsonObeject类型。json使用来分割一个键值对,使用来分割不同的键值对。

1
{"name":"Jerry","score":"100"}

我们可以定义一个Student bean,其成员变量就是对应的key值:

1
2
3
4
class Student{
public String name;
public Integer score:
}

然后使用Gson解析:

1
2
Gson gson = new Gson();
Student student = gson.fromJson(yourJson, Student.class);

这样我们就可以得到一个Student的类,里面的成员变量会被Gson自动写好数据。需要注意的的是由于score是Integer类型的,Gson会自动帮我们进行类型的转换,但是如果反回的json中socre的值不是一个正确的数据,如”100a”,Gson解析的时候就会报错。为了保险也可以将score的类型定义为String类型,在使用的时候自己做一下类型的转换。

2. JsonObejcet嵌套JsonObejcet

如下面的json

1
{"name":"Jerry","score":"100", curriculum:{"title":"English"}}

我们只需要在Student类里面定义一个对应的静态内部类就可以了,Gson还是会自动帮我们解析并填充好数据。

1
2
3
4
5
6
7
8
9
class Student{
public String name;
public Integer score:
public Curriculum curriculum

public static class Curriculum{
public String title;
}
}

3. JsonObejcet嵌套JsonArray

如下面的json,curriculum是一个JsonArray类型,即里面包含的内容可能有多个。

1
{"name":"Jerry","score":"100", curriculum:{["title":"English"]}}

我们只需要在Student类里面curriculum的类型改为List的即可。

1
2
3
4
5
6
7
8
9
class Student{
public String name;
public Integer score:
public List<Curriculum> curriculum

public static class Curriculum{
public String title;
}
}

4. JsonArray

如果反回的json字符串是一个纯的JsonArray,解析起来就稍微有点麻烦了。如下所示,这种格式是不推荐使用的。

1
[{"name":"Jerry","score":"100"},{"name":"Tom","score":"100"}]

这种情况下我们就需要明确地告诉Gson来解析成什么样的类型:

1
2
3
Type type = new TypeToken<List<Student>>() {}.getType();
Object fromJson2 = gson.fromJson(json, type);
List<Student> list = (List<Student>) fromJson2;

可能遇到的错误

在使用Gson解析json的过程中,很可能遇到下面这种错误:

1
java.lang.IllegalStateException: Expected STRING but was BEGIN_ARRAY

还有其它的Expected xxx bug was xxx
这种情况就是Gson解析对应的类型不对,如上面JsonObjcet嵌套JsonArray的时候,如果将curriculum的类型定义为String

1
public String curriculum

Gson解析到这里的时候类型就对应不上了,会报上面的错误。

总之,出现类似上述的错误就检查Bean里面对应的类型的定义是否正确,一般会发现问题的。