第三方库Gson

JSON是一种文本形式的数据交换格式,它比XML更轻量、比二进制容易阅读和编写,调式也更加方便。而Gson就是一种解析JSON文本形式的库。

Gson能够将javaBean转成JSON格式,也能够将JSON转成JavaBean,下面我们来看Gson怎么使用的。

1.基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Test {
private String name;
private int age;
private String see;
private String father;
...
//省略其他toString、get、set、构造方法
}

...
public static void main(String[] s){
/**转json**/
Test test=new Test("大傻逼",11,"男","大蠢货");
//主要下下面两行
Gson gson=new Gson();
String jsonData = gson.toJson(test);
System.out.println(jsonData);

/**
* {"name":"大傻","age":33,"see":"男","father":"大臭"}
* 转javaBean
**/
String jsonData="{\"name\":\"大傻\",\"age\":33,\"see\":\"男\",\"father\":\"大臭\"}";
Gson gson=new Gson();
Test test = gson.fromJson(jsonData, Test.class);
System.out.println(test.toString());
}
...

上面就是一个普通的javaBean的序列化与反序列换功能,用到的是toJson()fromJson()两个方法。有时候我们的对象并不是这样简单的,里面可能有集合有对象有数组,那么该如何使用?这里的化跟上面的使用方法是一样的。

2.Gson注解

主要有两个重要的注解@SerializedName@Expose,前者主要是用来指定该字段在JSON中对应的字段名称,后者能够指定该字段是否能够序列化或者反序列化。

1.首先来看看@SerializedName注解,这个注解可以将改变字段的名字,使用场景,比如:后台给了一串json数据,但是他的字段名跟你的字段名起的不一样,这样子就可以使用这个注解来进行解析,可以不用统一前后端的命名。

1
2
3
4
5
6
7
8
9
public class Test2 {
private String occupation;
private int wages;
private String company;
@SerializedName("测试") //注解修改输出的字段名称
private Test test;
...
//省略其他toString、get、set、构造方法
}

下面序列化输出


下面反序列化,如果后台给的数据是上面样的,但是我们不指定字段名,反序列化输出就是这样的。


可以注意到test这个对象是空的,但是我们指定后呢就可以正常输出了


这里,为POJO字段提供备选属性名
SerializedName注解提供了两个属性,上面用到了其中一个,别外还有一个属性alternate,接收一个String数组。
注:alternate需要2.4版本
1
2
@SerializedName(value="测试",alternate={"a","b"})
private Test test;

当上面的三个属性(测试、a、b)都中出现任意一个时均可以得到正确的结果。当多种情况同时出时,以最后一个出现的值为准。

2.再来看看@Expose这个注解,有时候我们序列化或者反序列化的时候,有一个字段我不想看到他就可以用这个注解来指定,serialize用来指定序列化是否输出,deserialize是用来指定反序列化是否输出,true为输出,false为不输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Expose(serialize =true,deserialize =true)
private String name;
@Expose(serialize =false,deserialize =false)
private int age;
@Expose(serialize =true,deserialize =true)
private String see;
@Expose(serialize =false,deserialize =false)
private String father;
...
//省略其他toString、get、set、构造方法
}
.........................
//这种情况的话,Gson的使用方式就有点变化了
Gson gson=new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); //需要这样来获取

3.Gson使用泛型

当我们想用Gson来输出集合的时候,我们需要使用TypeToken来实现对泛型的支持

1
2
3
Gson gson = new Gson();
...
gson.toJson(arrayList, new TypeToken<ArrayList<String>>() {}.getType());

我们在实际开发中是不可能只有一个Model的,会有多个,但是在使用序列化和反序列化的同时候不可能给每一个Model都写一方法。知道Gson可以支持泛型,那么我们就来进行一下封装。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class TJson<T> {
private String state; //说明
private String code; //状态码
private T date; //这个就是我们实际的数据
...
//省略其他toString、get、set、构造方法
}
...
public static void main(String[] s){
/**泛型封装**/
TJson<Test> testTJson=new TJson<Test>("ok_error","0",new Test("大傻逼",11,"男","大蠢货"));
Gson gson = new Gson();
String s1=gson.toJson(testTJson, new TypeToken<TJson<Test>>() {}.getType());
System.out.println(s1);
}
...

输出后就是下面这个样子


贴一个Gson学习的帖子:https://www.jianshu.com/p/e740196225a4

贴一个封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

public class GsonUtil {
private static Gson gson = null;
static {
if (gson == null) {
gson = new Gson();
}
}

private GsonUtil() {
}

/**
* 转成json
*
* @param object
* @return
*/
public static String GsonString(Object object) {
String gsonString = null;
if (gson != null) {
gsonString = gson.toJson(object);
}
return gsonString;
}

/**
* 转成bean
*
* @param gsonString
* @param cls
* @return
*/
public static <T> T GsonToBean(String gsonString, Class<T> cls) {
T t = null;
if (gson != null) {
t = gson.fromJson(gsonString, cls);
}
return t;
}

/**
* 转成list
* 泛型在编译期类型被擦除导致报错
* @param gsonString
* @param cls
* @return
*/
public static <T> List<T> GsonToList(String gsonString, Class<T> cls) {
List<T> list = null;
if (gson != null) {
list = gson.fromJson(gsonString, new TypeToken<List<T>>() {
}.getType());
}
return list;
}

/**
* 转成list
* 解决泛型问题
* @param json
* @param cls
* @param <T>
* @return
*/
public <T> List<T> jsonToList(String json, Class<T> cls) {
Gson gson = new Gson();
List<T> list = new ArrayList<T>();
JsonArray array = new JsonParser().parse(json).getAsJsonArray();
for(final JsonElement elem : array){
list.add(gson.fromJson(elem, cls));
}
return list;
}


/**
* 转成list中有map的
*
* @param gsonString
* @return
*/
public static <T> List<Map<String, T>> GsonToListMaps(String gsonString) {
List<Map<String, T>> list = null;
if (gson != null) {
list = gson.fromJson(gsonString,
new TypeToken<List<Map<String, T>>>() {
}.getType());
}
return list;
}

/**
* 转成map的
*
* @param gsonString
* @return
*/
public static <T> Map<String, T> GsonToMaps(String gsonString) {
Map<String, T> map = null;
if (gson != null) {
map = gson.fromJson(gsonString, new TypeToken<Map<String, T>>() {
}.getType());
}
return map;
}