JSON 利器之 Gson (一)

小伙伴们,还记得之前的[Fastjson 详解]吗?同样,目前JSON的解释库繁多,也系统通过不同的库的学习,了解不同的实现思维与方式,今天为大家介绍另外一款非常优秀的Gson解析库-Gson。希望小伙伴们,能够通过该篇文章了解到以下内容:
① Gson起源。
② Gson的使用方式。
③ Gson的基本使用(数组,集合,bean)。
④ Gson的格式化输出等。

1.1 Gson 起源

Gson来自于Google,主要用来序列化Java对象为JSON字符串,或者反序列化JSON字符串成Java对象。其github地址为:https://github.com/google/gson/

1.2 引入方式

1.2.1 通过Maven添加

1
2
3
4
5
6
7
8
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.7</version>
<scope>compile</scope>
</dependency>
</dependencies>

其中2.7为当前的最新版本号,选择自己项目合适的版本号

1.2.2 通过Gradle添加

1
compile 'com.google.code.gson:gson:2.7'

1.2.3 通过jar方式添加

通过以下链接下载jar Gson lib库

1.3 基本使用

1.3.1 基本使用

序列化:

1
2
3
4
5
6
Gson gson = new Gson();
gson.toJson(1); // ==> 1
gson.toJson("abcd"); // ==> "abcd"
gson.toJson(new Long(10)); // ==> 10
int[] values = { 1 };
gson.toJson(values); // ==> [1]

反序列化:

1
2
3
4
5
6
int one = gson.fromJson("1", int.class);
Integer one = gson.fromJson("1", Integer.class);
Long one = gson.fromJson("1", Long.class);
Boolean false = gson.fromJson("false", Boolean.class);
String str = gson.fromJson("\"abc\"", String.class);
String[] anotherStr = gson.fromJson("[\"abc\"]", String[].class);

1.3.2 数组

1
2
3
4
5
6
7
8
9
10
11
/**
* 序列化数组
*/
@Test
public void testSerilzableGsonArray(){
Gson gson = new Gson();
int[] ints = {1, 2, 3, 4, 5};
String[] strings = {"abc", "def", "ghi"};
System.out.println(gson.toJson(ints)); // ==> [1,2,3,4,5]
System.out.println(gson.toJson(strings)); // ==> ["abc", "def", "ghi"]
}

反序列化:

1
2
3
4
5
6
7
8
/**
* 反序列化数组
*/
@Test
public void testDecSerilzableGsonArray(){
Gson gson = new Gson();
int[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class);
}

1.3.1 集合对象

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 序列化集合
*/
@Test
public void testSeriazableCollection(){
Gson gson = new Gson();
List<String> list = new ArrayList<String>();
list.add("12");
list.add("13");
list.add("14");
String jsonData = gson.toJson(list);
System.out.println(jsonData);
}

结果为:

1
["12","13","14"]

反序列化:

1
2
3
4
5
6
7
8
9
10
@Test
public void testDecSeriazableCollection(){
Gson gson = new Gson();
Type collectionType = new TypeToken<List<Integer>>(){}.getType();
String jsonData = "['12','13','14']";
List<Integer> ints2 = gson.fromJson(jsonData, collectionType);
for(Integer item:ints2){
System.out.print(item+",");
}
}

结果为:

1
12,13,14,

1.3.2 带日期Bean对象

我们在这里方便测试,新建bean,命名为User,其属性结构如下:

1
2
3
4
5
6
7
8
9
10
public class User {

private String name = "";
private int age = 0;
private Date createTime;

public User() {
super();
}
.........

为了篇幅,此处省去set与get方法,首先该User类中,有三个属性,其中有string类型的name,有int类型的age,有java.util.Date类型的createTime。分别会给出序列化与反序列化后的结果对象,(一切不以代码讲解的都是耍流氓…);代码如下:
① 使用默认日期转换方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 显示默认格式的日期
*/
@Test
public void testUserDefaultFormat(){
User user = new User();
user.setAge(10);
user.setCreateTime(new Date());
user.setName("andyqian");
Gson gson = new Gson();
String jsonData = gson.toJson(user);
System.out.println(jsonData);
}

返回结果:

1
{"name":"andyqian","age":10,"createTime":"Oct 21, 2016 12:13:39 AM"}

咦,日期是转换出来了,但是这个并不是我们想得到的,我们一般的需求是需要将Date日期格式转换指定的日期格式转换出来,如: 2016-10-21 00:20:18,那么,既然有这个需求,就让Gson来解决,代码如下:
指定日期转换格式:

1
2
3
4
5
6
7
8
9
10
 @Test
public void testUser(){
User user = new User();
user.setAge(10);
user.setCreateTime(new Date());
user.setName("andyqian");
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
String jsonData = gson.toJson(user);
System.out.println(jsonData);
}

返回结果:

1
{"name":"andyqian","age":10,"createTime":"2016-10-21 00:21:37"}

看,Gson帮我们实现了,在这里需要简单的讲解一下,这里我们使用到了GsonBuilder对象,其中的setDateFormat()方法,在该方法中设置了日期的转换格式,这里采用的是: yyyy-MM-dd HH:mm:ss,可根据实际需要来进行书写。
我们上面中的返回结果作为我们的反序列化参数:
反序列化方法:

1
2
3
4
5
6
7
8
9
10
11
12
 /**
* 将带日期格式的字符串转换为对象
*/
@Test
public void testUserFormJsonData(){
String jsonData = testFrom();
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
User user = gson.fromJson(jsonData,User.class);
System.out.println("age: "+user.getAge());
System.out.println("createTime:"+user.getCreateTime());
System.out.println("name:"+user.getName());
}

反序列化结果:

1
2
3
age: 10
name:andyqian
createTime:Fri Oct 21 00:29:03 CST 2016

1.34 嵌套使用

以上几种方式都是比较基本的,在实际项目中,其复杂度,远远超过上面的基本操作,那么,我们在这里模拟一个稍复杂的对象嵌套使用。我们采用了两个类,Company,以及Employee类,其中一个Company中包括多个Employee,具体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* @site: www.andyqian.com
* @email: andytohome@gmai.com
* @author andy
*/
public class Company {

private String companyName; //
private Date createTime;
private String address;
private List<Employee> list;
...
}

职员类:

1
2
3
4
5
6
7
8
9
10
11
/**
* @site: www.andyqian.com
* @email: andytohome@gmai.com
* @author andy
*/
public class Employee{

private String name;
private int age;
private Date birthday;
}

序列化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Test
public void testList(){
List<Employee> list = new ArrayList<Employee>();
list.add(new Employee("张三",10,new Date()));
list.add(new Employee("李四",20,new Date()));
list.add(new Employee("王五",30,new Date()));
//
Company company = new Company();
company.setAddress("上海");
company.setCompanyName("xxx科技有限公司");
company.setCreateTime(new Date());
company.setList(list);
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
String data = gson.toJson(company);
System.out.println(data);
}

其结果如下所示:

1
{"companyName":"xxx科技有限公司","createTime":"2016-10-21 00:56:22","address":"上海","list":[{"name":"张三","age":10,"birthday":"2016-10-21 00:56:22"},{"name":"李四","age":20,"birthday":"2016-10-21 00:56:22"},{"name":"王五","age":30,"birthday":"2016-10-21 00:56:22"}]}

我们发现已经操作成功

1.3.5 格式化输出

我们通过1.3.4看到,如果数据量复杂时,默认返回的JSON字符串是紧凑型的,对结构的构成是非常不容易理解的,那么,此刻,我们想得到的是格式化输出后的JSON数据,怎么来实现呢?…….别急,Gson早已经为我们考虑到了,只需一个方法就可以实现,如下:
测试方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Test
public void testList(){
List<Employee> list = new ArrayList<Employee>();
list.add(new Employee("张三",10,new Date()));
list.add(new Employee("李四",20,new Date()));
list.add(new Employee("王五",30,new Date()));
//
Company company = new Company();
company.setAddress("上海");
company.setCompanyName("xxx科技有限公司");
company.setCreateTime(new Date());
company.setList(list);
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
String data = gson.toJson(company);
System.out.println(data);
}

默认返回(紧凑型):

1
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();

返回结果:

1
{"companyName":"xxx科技有限公司","createTime":"2016-10-21 00:56:22","address":"上海","list":[{"name":"张三","age":10,"birthday":"2016-10-21 00:56:22"},{"name":"李四","age":20,"birthday":"2016-10-21 00:56:22"},{"name":"王五","age":30,"birthday":"2016-10-21 00:56:22"}]}

格式型(setPrettyPrinting())

1
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").setPrettyPrinting().create();

返回结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"companyName": "xxx科技有限公司",
"createTime": "2016-10-21 01:01:46",
"address": "上海",
"list": [
{
"name": "张三",
"age": 10,
"birthday": "2016-10-21 01:01:46"
},
{
"name": "李四",
"age": 20,
"birthday": "2016-10-21 01:01:46"
},
{
"name": "王五",
"age": 30,
"birthday": "2016-10-21 01:01:46"
}
]
}

在这里,我们得益于GsonBuilder对象中的setPrettyPrinting()方法。