Gson как распарсить во внутреннем объекте nullable-поле?
Я знаю что если указать serializeNulls() тогда объект раскладывается с null-полями.
У меня возникла сложность с вложенным классом, который должен парсится с null-полями, но это не должно относится к внешнему классу, который парсится обязательно без null-полей (хотя они могут в нем присутствовать).
null-поля во внешнем классе нельзя использовать из-за ограничений backend. Поэтому нельзя использовать serializeNulls() на главном Gson
Пример для наглядности:
основной пример объекта
{
"name": "Anna",
"age": 40,
"pet" : {
"name" : "snowball",
"type" : 2
}
}
{
"name" : "Bob"
"age" : 30,
"pet" : {
"name" : "smoky",
"type" : null //Корректный вариант. Но это поле не могу распарсить
}
}
{
"name" : "Carol",
"age" : null, //ошибка. Во внешнем объекте не должно быть null
"pet" : {
"name" : "twiky",
"type" : null //как распарсить это, не затрагивая внешний объект
}
}
когда я указываю внутренний парсер через registerTypeAdapter - он возвращает корретный json (пример2 {"name":"smoky","type":null}), но после прохода через внешний Gson - null-значение стирается (пример2 {"name":"Bob","age":30,"pet":{"name":"smoky"}})
Пример с кодом:
public static void main(String[] args) {
Pet pet1 = new Pet("snowball", 2);
Person anna = new Person("Anna", 40, pet1);
Pet pet2 = new Pet(null, 1);
Person bob = new Person("Bob", 30, pet2);
Gson gson = new GsonBuilder()
.registerTypeAdapter(Pet.class, new PetParser())
.create();
System.out.println(gson.toJson(anna) + "\n");//{"name":"Anna","age":40,"pet":{"name":"snowball","type":2}}
System.out.println(gson.toJson(bob) + "\n");//{"name":"Bob","age":30,"pet":{"type":1}} <- null-поле исчезло
}
public static class PetParser implements JsonSerializer<Pet> {
@Override
public JsonElement serialize(Pet pet, Type type, JsonSerializationContext jsonSerializationContext) {
Gson childGson = new GsonBuilder().serializeNulls().create();
System.out.printf("pet:" + childGson.toJsonTree(pet) + "\n");
return childGson.toJsonTree(pet);
//anna pet:{"name":"snowball","type":2}
//bob pet:{"name":null,"type":1} <- null-поле есть
}
}
Ответы (1 шт):
Наверное, никак. Такой случай, как у вас, разработчики Gson не предусмотрели.
Загляните в исходники метода
public void toJson(Object src, Type typeOfSrc, JsonWriter writer)
там setSerializeNulls выставляется для JsonWriter, все элементы туда пишутся одинаково, кастомный сериализатор на этом ничего не меняет.
Верным решением будет договориться с бэкендом, это ненормально тут принимать null, а тут нет.
ДОПОЛНЕНО
Как вот тут пишут
https://github.com/google/gson/blob/master/UserGuide.md#null-object-support
PetParser просто добавляет JsonNull элемент при сериализации, но потом в toJson() уровнем выше это игнорируется и все null опускаются.
Т.е. при текущей реализации этой фичи в Gson -- никак.