Java JSON处理库之Gson的用法详解

寻技术 JS脚本 / JAVA编程 2023年07月11日 120

引言

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成。在Java项目中,JSON被广泛应用于各种场景,例如Web应用程序中的数据传输、配置文件、日志记录等。随着Java开发人员对JSON处理需求的增长,诸多JSON处理库应运而生,旨在简化和优化JSON数据的操作。

在Java领域,处理JSON数据的常见库有Jackson、Gson等。这些库各有优缺点,具体的选择取决于项目的需求和开发者的喜好。本文将重点介绍Google开发的Gson库,包括其基本功能、高级特性以及如何在实际项目中使用Gson来处理JSON数据。

Gson简介

Gson是Google开发的一款Java JSON处理库,旨在简化Java开发人员操作JSON数据的过程。Gson库的核心功能是将Java对象转换为JSON表示(序列化)以及将JSON字符串转换为等效的Java对象(反序列化)。它的设计注重简洁易用,API直观且易于学习。

Gson在性能方面表现优秀,虽然可能不是最快的JSON库,但它的性能足够满足大多数应用场景的需求。此外,Gson拥有丰富的特性和选项,可以满足不同项目的需求和定制化需求。

官方网站:github.com/google/gson

Gson的基本功能

Gson库提供了一些简单易用的功能来处理JSON数据。以下是Gson的两个核心功能:

1. 将Java对象转换为JSON字符串(序列化)

Gson可以将Java对象转换为JSON格式的字符串。这个过程通常被称为序列化。Gson通过分析对象的属性和值来生成相应的JSON表示。例如:

Person person = new Person("John Doe", 30);
Gson gson = new Gson();
String json = gson.toJson(person);
System.out.println(json);

输出结果:

{
  "name": "John Doe",
  "age": 30
}

2. 将JSON字符串转换为Java对象(反序列化)

Gson还可以执行反向操作,即将JSON字符串转换为对应的Java对象。这个过程通常被称为反序列化。例如:

String json = "{\"name\":\"John Doe\",\"age\":30}";
Gson gson = new Gson();
Person person = gson.fromJson(json, Person.class);
System.out.println(person);

输出结果:

Person{name='John Doe', age=30}

使用Gson的基本步骤

要在项目中使用Gson库,可以遵循以下基本步骤:

1. 添加依赖

首先,需要将Gson库添加到项目的依赖中。根据你的项目构建工具(Maven或Gradle),你可以选择相应的方法添加依赖。

1.1. Maven

将以下依赖添加到项目的pom.xml文件中:

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

1.2. Gradle

将以下依赖添加到项目的build.gradle文件中:

implementation 'com.google.code.gson:gson:2.8.9'

2. 创建Java对象模型

在项目中创建一个或多个Java类,用于表示JSON数据。例如,如果你要处理一个包含人员信息的JSON对象,你可以创建一个名为Person的类:

public class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 省略getter和setter方法
}

3. 使用Gson进行序列化和反序列化

创建Gson实例并使用其提供的方法将Java对象转换为JSON字符串(序列化)以及将JSON字符串转换为Java对象(反序列化)。

3.1. 序列化

Person person = new Person("John Doe", 30);
Gson gson = new Gson();
String json = gson.toJson(person);
System.out.println(json);

3.2. 反序列化

String json = "{\"name\":\"John Doe\",\"age\":30}";
Gson gson = new Gson();
Person person = gson.fromJson(json, Person.class);
System.out.println(person);

GsonBuilder详解

excludeFieldsWithoutExposeAnnotation() 方法:

该方法用于设置 Gson 在序列化或反序列化时,只包含带有 @Expose 注解的字段。默认情况下,Gson 包含所有字段,无论是否带有 @Expose 注解。

Gson gson = new GsonBuilder()
    .excludeFieldsWithoutExposeAnnotation()
    .create();

excludeFieldsWithModifiers(Modifier... modifiers) 方法:

该方法用于设置 Gson 在序列化或反序列化时,不包含指定修饰符的字段。参数为 Java 修饰符的可变参数,表示不包含这些修饰符的字段不会被序列化或反序列化。

Gson gson = new GsonBuilder()
    .excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT)
    .create();

serializeNulls() 方法:

该方法用于设置 Gson 在序列化时,将 null 值作为字段的值进行序列化。默认情况下,Gson 不会将 null 值作为字段的值进行序列化。

Gson gson = new GsonBuilder()
    .serializeNulls()
    .create();

disableHtmlEscaping() 方法:

该方法用于设置 Gson 在序列化时,不对 HTML 特殊字符进行转义。默认情况下,Gson 会将 HTML 特殊字符(如 <, > 等)进行转义。

Gson gson = new GsonBuilder()
    .disableHtmlEscaping()
    .create();

setPrettyPrinting() 方法:

该方法用于设置 Gson 在序列化时,输出格式化的 JSON 字符串。默认情况下,Gson 输出的 JSON 字符串是压缩的。

Gson gson = new GsonBuilder()
    .setPrettyPrinting()
    .create();

setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) 方法:

该方法用于设置 Gson 在序列化或反序列化时,将 Java 字段名转换为 JSON 字段名的策略。参数为一个 FieldNamingStrategy 对象,表示转换策略。

Gson gson = new GsonBuilder()
    .setFieldNamingStrategy(new FieldNamingStrategy() {
        @Override
        public String translateName(Field field) {
            return field.getName().toUpperCase();
        }
    })
    .create();

setDateFormat(String pattern) 方法:

该方法用于设置 Gson 在序列化或反序列化时,使用的日期格式。参数为一个日期格式字符串。

Gson gson = new GsonBuilder()
    .setDateFormat("yyyy-MM-dd")
    .create();

registerTypeAdapter(Type type, Object typeAdapter) 方法:

该方法用于注册一个自定义的 TypeAdapter 对象,用于在序列化或反序列化时,转换指定类型的对象。参数为需要转换的 Java 类型和对应的 TypeAdapter 对象。

Gson gson = new GsonBuilder()

registerTypeAdapterFactory(TypeAdapterFactory factory) 方法:

该方法用于注册一个自定义的 TypeAdapterFactory 对象,用于在序列化或反序列化时,转换多个类型的对象。参数为需要转换的 Java 类型工厂和对应的 TypeAdapterFactory 对象。

Gson gson = new GsonBuilder()
    .registerTypeAdapterFactory(new MyTypeAdapterFactory())
    .create();

registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) 方法:

该方法用于注册一个自定义的 TypeAdapter 对象,用于在序列化或反序列化时,转换指定基类的所有子类对象。参数为需要转换的基类类型和对应的 TypeAdapter 对象。

Gson gson = new GsonBuilder()
    .registerTypeHierarchyAdapter(Number.class, new MyNumberTypeAdapter())
    .create();

setVersion(double version) 方法:

该方法用于设置 Gson 在序列化或反序列化时,使用的版本号。默认情况下,Gson 不使用版本号。

Gson gson = new GsonBuilder()
    .setVersion(1.0)
    .create();

enableComplexMapKeySerialization() 方法:

该方法用于设置 Gson 在序列化时,支持序列化复杂的 Map 类型的键。默认情况下,Gson 不支持序列化复杂的 Map 类型的键。

Gson gson = new GsonBuilder()
    .enableComplexMapKeySerialization()
    .create();

disableInnerClassSerialization() 方法:

该方法用于设置 Gson 在序列化时,不序列化内部类。默认情况下,Gson 会序列化内部类。

Gson gson = new GsonBuilder()
    .disableInnerClassSerialization()
    .create();

enableLongSerialization() 方法:

该方法用于设置 Gson 在序列化时,将 long 类型的值强制转换为字符串进行序列化。默认情况下,Gson 不会将 long 类型的值转换为字符串。

Gson gson = new GsonBuilder()
    .enableLongSerialization()
    .create();

setFieldNamingPolicy(FieldNamingPolicy fieldNamingPolicy) 方法:

该方法用于设置 Gson 在序列化或反序列化时,将 Java 字段名转换为 JSON 字段名的策略。参数为一个 FieldNamingPolicy 枚举值,表示转换策略。

Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
    .create();

以上是 GsonBuilder 常用的方法,通过链式调用这些方法,可以灵活地配置 Gson 实例的行为。最后,调用 create() 方法可以创建一个 Gson 实例。

高级特性

除了基本功能之外,Gson库还提供了许多高级特性,以便在处理JSON数据时具有更大的灵活性。以下是Gson库的一些高级特性:

1. 自定义序列化和反序列化

Gson库提供了一些方法来允许开发人员自定义Java对象的序列化和反序列化方式。例如,可以使用JsonSerializerJsonDeserializer接口实现自定义序列化和反序列化。

1.1. 实现自定义序列化

public class PersonSerializer implements JsonSerializer<Person> {
    @Override
    public JsonElement serialize(Person person, Type type, JsonSerializationContext context) {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("name", person.getName());
        jsonObject.addProperty("age", person.getAge());
        return jsonObject;
    }
}

1.2. 实现自定义反序列化

public class PersonDeserializer implements JsonDeserializer<Person> {
    @Override
    public Person deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
        JsonObject jsonObject = json.getAsJsonObject();
        String name = jsonObject.get("name").getAsString();
        int age = jsonObject.get("age").getAsInt();
        return new Person(name, age);
    }
}

1.3. 注册自定义序列化和反序列化

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Person.class, new PersonSerializer());
gsonBuilder.registerTypeAdapter(Person.class, new PersonDeserializer());
Gson gson = gsonBuilder.create();

2. 类型适配器

Gson库提供了TypeAdapter类,允许开发人员完全控制序列化和反序列化的过程。

public class PersonTypeAdapter extends TypeAdapter<Person> {
    @Override
    public void write(JsonWriter out, Person person) throws IOException {
        out.beginObject();
        out.name("name").value(person.getName());
        out.name("age").value(person.getAge());
        out.endObject();
    }
    @Override
    public Person read(JsonReader in) throws IOException {
        in.beginObject();
        String name = "";
        int age = 0;
        while (in.hasNext()) {
            switch (in.nextName()) {
                case "name":
                    name = in.nextString();
                    break;
                case "age":
                    age = in.nextInt();
                    break;
                default:
                    in.skipValue();
            }
        }
        in.endObject();
        return new Person(name, age);
    }
}

3. JsonElement、JsonObject、JsonArray

Gson库提供了一些类来动态解析JSON数据。例如,可以使用JsonElementJsonObjectJsonArray类来访问JSON对象、JSON数组和JSON元素。

JsonElement element = JsonParser.parseString(json);
if (element.isJsonObject()) {
    JsonObject jsonObject = element.getAsJsonObject();
    // 访问JSON对象
} else if (element.isJsonArray()) {
    JsonArray jsonArray = element.getAsJsonArray();
    // 访问JSON数组
} else if (element.isJsonPrimitive()) {
    JsonPrimitive jsonPrimitive = element.getAsJsonPrimitive();
    // 访问JSON元素
}

4. 注解

Gson库提供了一些注解,可以在Java对象的属性上指定自定义名称、排除某些属性、指定版本等。

4.1. @SerializedName

使用@SerializedName注解来指定Java对象属性对应的JSON属性名。

public class Person {
    @SerializedName("full_name")
    private String name;
    private int age;
    //...
}

4.2. @Expose

使用@Expose注解来指定序列化和反序列化哪些属性。

public class Person {
    @Expose
    private String name;
    @Expose(serialize = false)
    private int age;
    //...
}

4.3. @Since 和 @Until

使用@Since@Until注解来指定某些属性在某个版本或版本之后才能够被序列化或反序列化。

public class Person {
    @Since(1.0)
    private String name;
    @Until(2.0)
    private int age;
    //...
}

5. 支持泛型

Gson库支持处理泛型类型。例如,如果要将JSON数组转换为泛型列表,可以使用TypeToken类。

Type listType = new TypeToken<List<Person>>() {}.getType();
List<Person> personList = gson.fromJson(json, listType);

6. 对象引用处理

Gson库可以正确地处理循环引用和对象引用。

public class Person {
    private String name;
    private int age;
    private List<Person> friends;
    //...
}

如果某个人对象的朋友列表包含其他人对象,那么Gson可以正确地处理它们之间的引用。

通过这些高级特性,Gson库提供了更多的选项和灵活性,可以满足不同项目的需求和定制化需求。

总结

Gson是一个方便易用的Java JSON处理库,提供了一些简单易用的API来处理JSON数据。它具有许多有用的特性,如自定义序列化和反序列化、类型适配器、动态解析JSON数据、注解支持、泛型支持等。使用Gson可以方便地将Java对象转换为JSON格式的字符串,以及将JSON字符串转换为等效的Java对象。

在使用Gson时,需要注意以下一些优势和局限性:

优势

  • 易于使用
  • 性能相对较好
  • 支持注解和泛型

局限性

  • 无法处理复杂的嵌套关系
  • 对于大型JSON文件,可能会占用较多内存

在使用Gson时,一些最佳实践如下:

  • 尽量使用JavaBean对象来表示JSON数据
  • 避免使用循环引用
  • 使用@Expose注解来控制属性的序列化和反序列化
  • 使用TypeToken处理泛型类型
  • 避免将Gson对象作为全局对象,以避免线程安全问题

最后,要注意保持Gson库的版本更新,以获取最新的功能和性能优化。

原文地址:https://juejin.cn/post/7231200657902010405
关闭

用微信“扫一扫”