Gson Serialization Cookbook – Gson序列化食谱

最后修改: 2014年 9月 11日

中文/混合/英文(键盘快捷键:t)

In this article we’re going to look at the most common scenarios of serialization using the Gson library.

在本文中,我们将探讨使用Gson库进行序列化的最常见场景。

Let’s start by introducing a simple entity that we’re going to use throughout the following examples:

让我们首先介绍一下一个简单的实体,我们将在下面的例子中一直使用它。

public class SourceClass {
    private int intValue;
    private String stringValue;

    // standard getters and setters
}

1. Serialize an Array of Entities

1.序列化一个实体阵列

First, let’s serialize an array of objects with Gson:

首先,让我们用Gson来序列化一个对象的数组。

@Test
public void givenArrayOfObjects_whenSerializing_thenCorrect() {
    SourceClass[] sourceArray = {new SourceClass(1, "one"), new SourceClass(2, "two")};
    String jsonString = new Gson().toJson(sourceArray);

    String expectedResult = 
      "[{"intValue":1,"stringValue":"one"},{"intValue":2,"stringValue":"two"}]";
    assertEquals(expectedResult, jsonString);
}

2. Serialize a Collection of Entities

2.序列化一个实体的集合

Next, let’s do the same for a Collection of objects:

接下来,让我们对一个对象的集合做同样的处理。

@Test
public void givenCollection_whenSerializing_thenCorrect() {
    Collection<SourceClass> sourceCollection = 
      Lists.newArrayList(new SourceClass(1, "one"), new SourceClass(2, "two"));
    String jsonCollection = new Gson().toJson(sourceCollection);

    String expectedResult = 
      "[{"intValue":1,"stringValue":"one"},{"intValue":2,"stringValue":"two"}]";
    assertEquals(expectedResult, jsonCollection);
}

3. Change the Field Names of an Entity on Serialization

3.在序列化时改变实体的字段名

Next, let’s see how we can change the name of the field when we’re serializing an entity.

接下来,让我们看看在序列化实体时,我们如何改变字段的名称

We’re going to serialize our entity, containing the fields intValue and stringValue to a json with otherIntValue and otherStringValue:

我们将序列化我们的实体,包含字段intValuestringValue到一个带有otherIntValueotherStringValue的json。

@Test
public void givenUsingCustomSerializer_whenChangingNameOfFieldOnSerializing_thenCorrect() {
    SourceClass sourceObject = new SourceClass(7, "seven");
    GsonBuilder gsonBuildr = new GsonBuilder();
    gsonBuildr.registerTypeAdapter(SourceClass.class, new DifferentNameSerializer());
    String jsonString = gsonBuildr.create().toJson(sourceObject);

    String expectedResult = "{"otherIntValue":7,"otherStringValue":"seven"}";
    assertEquals(expectedResult, jsonString);
}

Note that we’re using a custom serializer here to change the name of our fields:

注意,我们在这里使用了一个自定义的序列化器来改变我们的字段的名称。

public class DifferentNameSerializer implements JsonSerializer<SourceClass> {
    @Override
    public JsonElement serialize
      (SourceClass src, Type typeOfSrc, JsonSerializationContext context) {
        String otherIntValueName = "otherIntValue";
        String otherStringValueName = "otherStringValue";

        JsonObject jObject = new JsonObject();
        jObject.addProperty(otherIntValueName, src.getIntValue());
        jObject.addProperty(otherStringValueName, src.getStringValue());

        return jObject;
    }
}

4. Ignore a Field When Serializing an Entity

4.序列化实体时忽略一个字段

Let’s now ignore a field completely when performing the serialization:

现在让我们在执行序列化的时候完全忽略一个字段

@Test
public void givenIgnoringAField_whenSerializingWithCustomSerializer_thenFieldIgnored() {
    SourceClass sourceObject = new SourceClass(7, "seven");
    GsonBuilder gsonBuildr = new GsonBuilder();
    gsonBuildr.registerTypeAdapter(SourceClass.class, new IgnoringFieldsSerializer());
    String jsonString = gsonBuildr.create().toJson(sourceObject);

    String expectedResult = "{"intValue":7}";
    assertEquals(expectedResult, jsonString);
}

Similar to the previous example, we’re using a custom serializer here as well:

与之前的例子类似,我们在这里也使用了一个自定义的序列化器。

public class IgnoringFieldsSerializer implements JsonSerializer<SourceClass> {
    @Override
    public JsonElement serialize
      (SourceClass src, Type typeOfSrc, JsonSerializationContext context) {
        String intValue = "intValue";
        JsonObject jObject = new JsonObject();
        jObject.addProperty(intValue, src.getIntValue());

        return jObject;
    }
}

Also note that we most likely need to do this in cases where we cannot change the source code of the entity, or if the field should only be ignored very specific cases. Otherwise we can ignore the field easier with a direct annotation on the entity class.

还要注意的是,我们很可能需要在不能改变实体的源代码的情况下这样做,或者在该字段只应在非常特殊的情况下被忽略。否则,我们可以通过在实体类上直接注解来更容易地忽略该字段。

5. Serialize a Field Only If It Passes a Custom Condition

5.只有当一个字段通过一个自定义条件时才会序列化它

Finally, let’s analyze a more advanced usecase – we want to only serialize a field if it passes a specific, custom condition.

最后,让我们来分析一个更高级的用例–我们只想在一个字段通过一个特定的、自定义的条件时将其序列化。

For example, let’s only serialize the int value if it’s positive and simply skip it if it’s negative:

例如,让我们只在int值为正数时将其序列化,如果为负数则直接跳过。

@Test
public void givenUsingCustomDeserializer_whenFieldNotMatchesCriteria_thenIgnored() {
    SourceClass sourceObject = new SourceClass(-1, "minus 1");
    GsonBuilder gsonBuildr = new GsonBuilder();
    gsonBuildr.registerTypeAdapter(SourceClass.class, 
      new IgnoringFieldsNotMatchingCriteriaSerializer());
    Gson gson = gsonBuildr.create();
    Type sourceObjectType = new TypeToken<SourceClass>() {}.getType();
    String jsonString = gson.toJson(sourceObject, sourceObjectType);
    
    String expectedResult = "{"stringValue":"minus 1"}";
    assertEquals(expectedResult, jsonString);
}

Of course we’re using a custom serializer here as well:

当然,我们在这里也使用了自定义序列化器

public class IgnoringFieldsNotMatchingCriteriaSerializer 
  implements JsonSerializer<SourceClass> {
    @Override
    public JsonElement serialize
      (SourceClass src, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject jObject = new JsonObject();

        // Criteria: intValue >= 0
        if (src.getIntValue() >= 0) {
            String intValue = "intValue";
            jObject.addProperty(intValue, src.getIntValue());
        }

        String stringValue = "stringValue";
        jObject.addProperty(stringValue, src.getStringValue());

        return jObject;
    }
}

And that’s it – 5 common usecases of serialization using Gson.

就是这样–使用Gson进行序列化的5个常见用例