跳到主要内容

Java Gson库

什么是Gson

Gson是由Google开发的一个Java库,用于在Java对象和JSON表示之间进行转换。它可以将Java对象转换为JSON格式(序列化),也可以将JSON字符串转换为等效的Java对象(反序列化)。

提示

Gson的全称是Google JSON,它是一个功能强大且使用简单的JSON解析库,特别适合初学者学习JSON处理。

Gson的主要特点

  • 简单易用: API设计简洁,容易上手
  • 无需注解: 不需要为类添加任何特殊注解即可工作
  • 高性能: 高效处理大型JSON数据
  • 良好的类型安全: 提供强类型支持
  • 支持任意复杂对象: 能处理嵌套类、集合等复杂对象
  • 可定制性: 提供多种自定义选项

添加Gson依赖

在使用Gson之前,需要先将Gson库添加到项目中。以下是使用Maven或Gradle添加依赖的方式:

Maven:

xml
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>

Gradle:

gradle
implementation 'com.google.code.gson:gson:2.10.1'

Gson基本用法

创建Gson对象

使用Gson的第一步是创建一个Gson对象:

java
import com.google.gson.Gson;

public class GsonExample {
public static void main(String[] args) {
// 创建Gson实例
Gson gson = new Gson();

// 后续代码...
}
}

对象序列化 (Java对象 → JSON)

将Java对象转换为JSON字符串:

java
import com.google.gson.Gson;

class Person {
private String name;
private int age;
private String email;

// 构造函数
public Person(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}

// Getters和Setters (省略,但实际使用时应加上)
}

public class GsonSerializationExample {
public static void main(String[] args) {
// 创建一个Person对象
Person person = new Person("张三", 25, "zhangsan@example.com");

// 创建Gson实例
Gson gson = new Gson();

// 将对象转换为JSON字符串
String json = gson.toJson(person);

// 输出JSON
System.out.println(json);
}
}

输出:

{"name":"张三","age":25,"email":"zhangsan@example.com"}

对象反序列化 (JSON → Java对象)

将JSON字符串转换回Java对象:

java
import com.google.gson.Gson;

public class GsonDeserializationExample {
public static void main(String[] args) {
// JSON字符串
String json = "{\"name\":\"张三\",\"age\":25,\"email\":\"zhangsan@example.com\"}";

// 创建Gson实例
Gson gson = new Gson();

// 将JSON转换为Person对象
Person person = gson.fromJson(json, Person.class);

// 使用转换后的对象
System.out.println("姓名: " + person.getName());
System.out.println("年龄: " + person.getAge());
System.out.println("邮箱: " + person.getEmail());
}
}

输出:

姓名: 张三
年龄: 25
邮箱: zhangsan@example.com

处理集合类型

Gson可以轻松处理Java集合类型,如List、Set、Map等。

序列化和反序列化List

java
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

public class GsonCollectionsExample {
public static void main(String[] args) {
// 创建Gson实例
Gson gson = new Gson();

// 创建并填充List
List<Person> personList = new ArrayList<>();
personList.add(new Person("张三", 25, "zhangsan@example.com"));
personList.add(new Person("李四", 30, "lisi@example.com"));
personList.add(new Person("王五", 35, "wangwu@example.com"));

// 序列化List到JSON
String json = gson.toJson(personList);
System.out.println("序列化List结果:");
System.out.println(json);

// 反序列化JSON到List
Type personListType = new TypeToken<List<Person>>(){}.getType();
List<Person> recoveredList = gson.fromJson(json, personListType);

System.out.println("\n反序列化后的数据:");
for(Person p : recoveredList) {
System.out.println(p.getName() + ", " + p.getAge() + ", " + p.getEmail());
}
}
}

输出:

序列化List结果:
[{"name":"张三","age":25,"email":"zhangsan@example.com"},{"name":"李四","age":30,"email":"lisi@example.com"},{"name":"王五","age":35,"email":"wangwu@example.com"}]

反序列化后的数据:
张三, 25, zhangsan@example.com
李四, 30, lisi@example.com
王五, 35, wangwu@example.com
注意

当处理泛型集合时,需要使用TypeToken来正确捕获完整的泛型类型信息,这样Gson才能正确地反序列化对象。

处理嵌套对象

Gson可以很好地处理嵌套对象和复杂数据结构:

java
import com.google.gson.Gson;
import java.util.Arrays;
import java.util.List;

class Address {
private String street;
private String city;
private String zipCode;

public Address(String street, String city, String zipCode) {
this.street = street;
this.city = city;
this.zipCode = zipCode;
}

// Getters和Setters (省略)
}

class Employee {
private String name;
private int id;
private Address address;
private List<String> skills;

public Employee(String name, int id, Address address, List<String> skills) {
this.name = name;
this.id = id;
this.address = address;
this.skills = skills;
}

// Getters和Setters (省略)
}

public class NestedObjectsExample {
public static void main(String[] args) {
// 创建嵌套对象
Address address = new Address("人民路123号", "北京", "100000");
List<String> skills = Arrays.asList("Java", "SQL", "HTML");
Employee employee = new Employee("李明", 1001, address, skills);

// 序列化
Gson gson = new Gson();
String json = gson.toJson(employee);
System.out.println(json);

// 反序列化
Employee parsedEmployee = gson.fromJson(json, Employee.class);
System.out.println("员工名: " + parsedEmployee.getName());
System.out.println("城市: " + parsedEmployee.getAddress().getCity());
System.out.println("技能: " + parsedEmployee.getSkills());
}
}

输出:

{"name":"李明","id":1001,"address":{"street":"人民路123号","city":"北京","zipCode":"100000"},"skills":["Java","SQL","HTML"]}
员工名: 李明
城市: 北京
技能: [Java, SQL, HTML]

自定义序列化与反序列化

在某些情况下,你可能需要自定义序列化或反序列化过程。Gson提供了TypeAdapterJsonSerializerJsonDeserializer接口来实现这一点。

使用TypeAdapter

以下是一个自定义日期格式的例子:

java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CustomDateAdapterExample {

// 自定义Date类型适配器
static class DateTypeAdapter extends TypeAdapter<Date> {
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

@Override
public void write(JsonWriter out, Date value) throws IOException {
if (value == null) {
out.nullValue();
} else {
out.value(dateFormat.format(value));
}
}

@Override
public Date read(JsonReader in) throws IOException {
try {
return dateFormat.parse(in.nextString());
} catch (ParseException e) {
throw new IOException(e);
}
}
}

static class Event {
private String name;
private Date date;

public Event(String name, Date date) {
this.name = name;
this.date = date;
}

// Getters和Setters (省略)
}

public static void main(String[] args) throws ParseException {
// 创建一个包含日期的对象
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date eventDate = format.parse("2023-05-15");
Event event = new Event("技术讲座", eventDate);

// 使用自定义TypeAdapter创建Gson实例
Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, new DateTypeAdapter())
.create();

// 序列化
String json = gson.toJson(event);
System.out.println(json);

// 反序列化
Event parsedEvent = gson.fromJson(json, Event.class);
System.out.println("活动: " + parsedEvent.getName());
System.out.println("日期: " + format.format(parsedEvent.getDate()));
}
}

输出:

{"name":"技术讲座","date":"2023-05-15"}
活动: 技术讲座
日期: 2023-05-15

Gson高级配置

Gson库提供了GsonBuilder类,允许你配置Gson实例的行为:

java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class GsonConfigurationExample {
public static void main(String[] args) {
// 创建配置化的Gson实例
Gson gson = new GsonBuilder()
.setPrettyPrinting() // 美化输出
.serializeNulls() // 序列化null值
.setDateFormat("yyyy-MM-dd") // 设置日期格式
.disableHtmlEscaping() // 禁用HTML转义
.excludeFieldsWithoutExposeAnnotation() // 仅包含带@Expose注解的字段
.create();

// 使用配置后的gson实例...
}
}

常用GsonBuilder配置选项

  1. setPrettyPrinting(): 输出格式化后的JSON
  2. serializeNulls(): 序列化null值
  3. setDateFormat(String): 设置日期格式
  4. disableHtmlEscaping(): 禁用HTML转义
  5. excludeFieldsWithoutExposeAnnotation(): 仅序列化带有@Expose注解的字段
  6. setFieldNamingPolicy(): 设置字段命名策略
  7. registerTypeAdapter(): 注册类型适配器

实际应用案例: REST API交互

以下是一个使用Gson与RESTful API交互的实际案例:

java
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

class Product {
private int id;
private String name;
private double price;
private String description;
private String category;

// Getters和Setters (省略)

@Override
public String toString() {
return "Product{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
", category='" + category + '\'' +
'}';
}
}

public class RestApiExample {
public static void main(String[] args) {
try {
// 创建HTTP连接
URL url = new URL("https://api.example.com/products");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");

// 检查响应状态
if (conn.getResponseCode() != 200) {
throw new RuntimeException("HTTP错误代码: " + conn.getResponseCode());
}

// 读取响应
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
br.close();

// 使用Gson解析JSON数组
Gson gson = new Gson();
Type productListType = new TypeToken<List<Product>>(){}.getType();
List<Product> products = gson.fromJson(response.toString(), productListType);

// 处理结果
System.out.println("获取到 " + products.size() + " 个产品:");
for (Product product : products) {
System.out.println(product);
}

conn.disconnect();

} catch (Exception e) {
e.printStackTrace();
}
}
}
注意

上述代码需要一个实际工作的API端点。在实际应用中,你应该使用你正在使用的真实API地址替换https://api.example.com/products

总结

Gson是一个功能强大且易于使用的Java JSON处理库,适合各种应用场景:

  • 基本用途:对象序列化和反序列化
  • 集合处理:处理List、Set、Map等集合类型
  • 嵌套对象:支持复杂的对象结构
  • 自定义处理:通过TypeAdapter、JsonSerializer和JsonDeserializer实现自定义行为
  • 高级配置:使用GsonBuilder灵活配置

通过学习本文内容,你应该已经掌握了使用Gson处理JSON数据的基本和高级技巧,能够在实际项目中灵活应用。

练习任务

  1. 创建一个表示图书的类Book,包含标题、作者、出版年份和ISBN等字段,使用Gson将其序列化为JSON,然后再反序列化回对象。

  2. 创建一个包含嵌套集合的复杂对象(如School类包含多个Department,每个Department包含多个Teacher),序列化和反序列化它。

  3. 使用Gson为某些字段实现自定义序列化/反序列化逻辑,例如,敏感字段加密/解密。

  4. 尝试使用Gson与一个公开的REST API(如JSONPlaceholder)交互,获取数据并解析。

附加资源

通过深入学习和实践,你将能够在各种Java应用中有效地使用Gson处理JSON数据。