1. 什么是Gson?
Gson是由Google开发的一个Java库,它可以将Java对象转换为JSON形式的数据,从而方便地进行网络传输和存储。它提供了非常简单易用的API,使得Java开发人员可以在应用程序中轻松地解析JSON。
2. Gson的基本用法
使用Gson非常简单,只需要将Java对象传递给Gson的toJson()方法即可将其转换为JSON字符串,或者使用fromJson()方法将JSON字符串转换为Java对象。下面是一个示例代码:
import com.google.gson.Gson;
public class GsonTest {
public static void main(String[] args) {
Gson gson = new Gson();
//将Java对象转换为JSON字符串
Person person = new Person("Alice", 18);
String json = gson.toJson(person);
System.out.println(json);
//将JSON字符串转换为Java对象
json = "{\"name\":\"Bob\",\"age\":20}";
Person person2 = gson.fromJson(json, Person.class);
System.out.println(person2);
}
}
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
以上代码将输出以下结果:
{"name":"Alice","age":18}
Person{name='Bob', age=20}
3. Gson默认的命名策略
在Java中,成员变量的命名通常使用camelCase(驼峰式)风格,例如:firstName、lastName等。而在JSON中,通常使用snake_case(下划线式)风格,例如:first_name、last_name等。当使用Gson将Java对象转换为JSON字符串时,Gson默认会使用Java的命名规则,即转换为camelCase风格。例如,上面示例中Person对象的name属性被转换为"name",而不是"first_name"。当使用fromJson()方法将JSON字符串转换为Java对象时,Gson同样也会遵循Java的命名规则。
4. 使用@SerializedName注解
如果我们希望在Java和JSON之间使用不同的命名规则,例如在Java中使用camelCase风格而在JSON中使用snake_case风格,那么就需要使用@SerializedName注解。这个注解可以放在Java对象的属性上,指定该属性在JSON中的名称。例如,我们可以将Person对象的name属性改名为"first_name":
class Person {
@SerializedName("first_name")
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
这样,当我们将Person对象转换为JSON字符串时,"name"属性将被转换为"first_name":
{"first_name":"Alice","age":18}
当使用fromJson()方法将JSON字符串转换为Java对象时,Gson会自动将"first_name"转换为"name"属性。
4.1 @SerializedName的嵌套使用
在Java对象中,有时候会包含其他对象的引用,这时候就可以使用@SerializedName的嵌套使用。例如,考虑下面的类:
class Student {
@SerializedName("first_name")
String firstName;
@SerializedName("last_name")
String lastName;
@SerializedName("score_map")
Map<String, Integer> scores;
}
在这个类中,我们使用了@SerializedName注解将firstName属性和lastName属性分别指定为"first_name"和"last_name"。此外,我们还在scores属性上使用了@SerializedName注解,指定该属性在JSON中被表示为"score_map"。这个属性的值是一个Map对象,它将字符串表示的科目映射为整数表示的分数。
当我们将该对象转换为JSON字符串时,输出的JSON字符串将像这样:
{"first_name":"Alice","last_name":"Green","score_map":{"math":98,"english":87,"history":92}}
当使用fromJson()方法将JSON字符串转换为Java对象时,Gson将自动解析嵌套的结构。
4.2 @SerializedName与泛型
在Java中,泛型的类型信息在编译时被擦除,因此在转换为JSON字符串时无法得知其实际类型。为了解决这个问题,可以使用TypeToken类来表示泛型类型。例如,我们可以将Person的List集合转换为JSON字符串,代码如下:
List<Person> persons = new ArrayList();
persons.add(new Person("Alice", 18));
persons.add(new Person("Bob", 20));
String json = gson.toJson(persons);
System.out.println(json);
但是,如果我们直接使用fromJson()方法将JSON字符串转换为List<Person>对象,会发生类型擦除的问题,转换结果仅是一个List对象而已。为了解决这个问题,可以先将JSON字符串转换为一个JsonElement对象,然后再使用TypeToken来获取List<Person>的类型信息。代码如下:
json = "[{\"name\":\"Alice\",\"age\":18},{\"name\":\"Bob\",\"age\":20}]";
JsonElement jsonElement = gson.fromJson(json, JsonElement.class);
Type type = new TypeToken<List<Person>>(){}.getType();
List<Person> persons2 = gson.fromJson(jsonElement, type);
System.out.println(persons2);
以上代码将输出以下结果:
[Person{name='Alice', age=18}, Person{name='Bob', age=20}]
5. 总结
使用Gson可以将Java对象转换为JSON字符串,或者将JSON字符串转换为Java对象,它提供了非常简单易用的API。当默认的命名规则无法满足需求时,可以使用@SerializedName注解来指定Java属性和JSON属性之间的映射关系。在Java对象中包含其他对象的引用时,可以使用嵌套的@SerializedName注解。对于泛型类型,需要使用TypeToken来获取类型信息。