Java GSON自定义反序列化器版本控制支持

时间:2019-01-02 20:05:13

标签: java json gson deserialization versioning

我为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文件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 :(得分:1)

要访问版本字段,请不要使人使用JsonDeserializer,而要使您拥有整个JSON。因此,让我们假设您的JSON是某种响应,可以通过以下Java类来呈现:

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

您的班级人员可能是:

@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是一个有点糟糕的示例类,因为无需使用v1.0或v2.0 JSON中的任何自定义反序列化器就可以轻松对它进行反序列化。从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);
    }
}

答案 1 :(得分:0)

如果要检查值的条件是否为null,请简单输入

if (jsonObj.get("gender") != null) {
    person.setGender(jsonObj.get("gender").getAsString());
}