GSON序列化简介
Contents
在本文中,我们将研究使用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. 更改序列化实体的字段名称
接下来,让我们看看在序列化实体时如何更改字段的名称。
我们将序列化我们的实体,包含字段intValue和stringValue到一个带有otherIntValue和otherStringValue的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 个常见用例。