Contents

GSON序列化简介

在本文中,我们将研究使用Gson 库 进行序列化的最常见场景。 让我们首先介绍一个简单的实体,我们将在以下示例中使用它:

public class SourceClass {
    private int intValue;
    private String stringValue;
    // standard getters and setters
}

1. 序列化实体数组

首先,让我们用 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. 序列化实体集合

接下来,让我们对对象集合做同样的事情:

@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. 更改序列化实体的字段名称

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

我们将序列化我们的实体,包含字段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);
}

请注意,我们在这里使用自定义序列化程序来更改字段的名称:

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. 序列化实体时忽略字段

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

@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);
}

与前面的示例类似,我们在这里也使用了自定义序列化程序:

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;
    }
}

另请注意,我们很可能需要在无法更改实体的源代码的情况下执行此操作,或者仅应忽略非常特定的字段。否则,我们可以通过在实体类上直接注释来更轻松地忽略该字段。

5. 仅当字段通过自定义条件时才对字段进行序列化

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

例如,我们只序列化 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);
}

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

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;
    }
}

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