Gson Serialization Cookbook

Gson Serialization Cookbook

В этой статье мы рассмотрим наиболее распространенные сценарии сериализации с использованиемthe Gson library.

Начнем с представленияa simple entity, которое мы будем использовать в следующих примерах:

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 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 name of the field при сериализации объекта.

Мы собираемся сериализовать нашу сущность, содержащую поляintValue иstringValue, в json сotherIntValue иotherStringValue:

@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 {
    @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 completely при сериализации:

@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 {
    @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() {}.getType();
    String jsonString = gson.toJson(sourceObject, sourceObjectType);

    String expectedResult = "{"stringValue":"minus 1"}";
    assertEquals(expectedResult, jsonString);
}

Конечно, здесь мы также используемa custom serializer:

public class IgnoringFieldsNotMatchingCriteriaSerializer
  implements JsonSerializer {
    @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;
    }
}

Вот и все - 5 распространенных вариантов использованияserialization using Gson.