Поддержка версий Java GSON Custom Deserializer - PullRequest
0 голосов
/ 02 января 2019

Я создал собственный десериализатор для своего класса Person.Это только для демонстрации.Мой настоящий класс более сложный.

Файл json содержит версию формата, а после этого массив персон.

В версии 1.0 у меня есть имя и возраст для каждого человека.
В версии 2.0 у меня есть имя , возраст и дополнительно пол .

Моя проблема здесь в том, что у меня нет доступа к версии в пользовательском десериализаторе, или, по крайней мере, я не выяснил, как ее получить.

Есть ли другой способ сделать это без jsonObj.get("gender").has();
или if (jsonObj.get("gender") != null)?

GSON Версия: 2.8.5

Десериализатор:

private class PersonDeserializer implements JsonDeserializer<PersonDatapoint>
{
    @Override
    public PersonDatapoint deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
    {
        JsonObject jsonObj = json.getAsJsonObject();

        // version 1.0
        Person person = new Person(jsonObj.get("name").getAsString());
        person.setAge(jsonObj.get("age").getAsInt());

        // version 2.0
        // how to determine version field in json File?
        // person.setGender(jsonObj.get("gender").getAsString());

        return person;
    }
}

JSON-файлv1.0:

{
    "version": "1.0",

    "persons": [
    {
      "name": "Alex",
      "age": 30
    },
    {
      "name": "John",
      "age": 31
    },
    {
      "name": "Elise",
      "age": 32
    }]  
}

JSON File v2.0:

{
  "version": "2.0",

  "persons": [
  {
    "name": "Alex",
    "age": 30,
    "gender": "male"
  },
  {
    "name": "John",
    "age": 31,
    "gender": "male" 
  },
  {
    "name": "Elise",
    "age": 32,
    "gender": "female"
  }]   
}

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Чтобы получить доступ к полю версии, сделайте JsonDeserializer не для человека, а для всего JSON, который у вас есть.Итак, давайте предположим, что ваш JSON является своего рода ответом, который может быть представлен с помощью класса Java, например:

@Getter @Setter
public class Response {
    private Double version;
    private Person[] persons; // versioned stuff
}

Ваш класс Person может выглядеть следующим образом:

@Getter @Setter
public class Person {
    @Since(1.0) // these annotations are put just for demonstrative purpose but are 
                // actually also functional, see deserializer
    private String name;
    @Since(1.0)
    private Integer age;
    @Since(2.0)
    private String gender;
}

Примечание : Этот Person является немного плохим примером класса, поскольку его можно легко десериализовать без какого-либо пользовательского десериализатора из JSON версии 1.0 или 2.0.Десериализация из v1.0 просто оставит gender нулевым.В любом случае ваш пользовательский десериализатор, использующий полевую версию JSON, может выглядеть так:

public class ResponseDeserializer implements JsonDeserializer<Response> {
    @Override
    public Response deserialize(JsonElement json, Type typeOfT,
                                    JsonDeserializationContext context)
            throws JsonParseException {
        // This is how to get the version
        Double version = json.getAsJsonObject().get("version").getAsDouble();
        // and below is jsut an example what you could do with version
        Gson gson = new GsonBuilder()
                .setVersion(version) // this is where @Since might be handy
                .setPrettyPrinting()
                .create();
        return gson.fromJson(json, Response.class);
    }
}
0 голосов
/ 03 января 2019

Проще говоря, если условие для проверки значения null или нет

if (jsonObj.get("gender") != null) {
    person.setGender(jsonObj.get("gender").getAsString());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...