【问题标题】:Java GSON Custom Deserializer versioning supportJava GSON 自定义反序列化器版本控制支持
【发布时间】:2019-01-02 20:05:13
【问题描述】:

我为我的 Person 类创建了一个自定义反序列化器。这仅用于演示目的。我的实际课程更复杂。

json 文件包含格式的版本,然后是人员数组。

在 1.0 版中,我为每个人设置了一个姓名年龄
在 2.0 版中,我有 nameage 以及 gender

我的问题是我无法访问自定义反序列化器中的版本,或者至少还不知道如何获取它。

如果没有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"
  }]   
}

【问题讨论】:

    标签: java json gson deserialization versioning


    【解决方案1】:

    要访问版本字段,不要为人员创建 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 是一个有点糟糕的示例类,因为它可以很容易地被反序列化,而无需任何来自 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);
        }
    }
    

    【讨论】:

      【解决方案2】:

      简单的 if 条件来检查值是否为null

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

      【讨论】:

      • 这正是 'jsonObj.get("gender").has()' 所做的,但如果 "gender" 存在,它会返回一个布尔值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-01
      • 1970-01-01
      • 2017-05-16
      • 1970-01-01
      • 1970-01-01
      • 2011-04-25
      相关资源
      最近更新 更多