【问题标题】:How to handle backward compatibility (field name change) in Jackson?如何处理杰克逊的向后兼容性(字段名称更改)?
【发布时间】:2021-08-11 15:13:25
【问题描述】:

假设我使用库中的架构(不属于我)

class OldClass {
   int id;
   string name;
}

序列化的 JSON "SerJsonStr" 想要

{"id": 12, "name": "Bob"}

现在我可以使用“OldClass”模式和上面的示例 json 将 json 反序列化为 scala 对象

OldClass obj = new ObjectMapper().readValue[OldClass](SerJsonStr)

但是,假设库将架构(通过更改字段名称)更新为

class OldClass {
   int id;
   string **fullName**;
}

现在,为了向后兼容,反序列化会将 fullName 设置为 null。请注意,“OldClass”是不属于我的第三方库的一部分

有没有办法明确指定 Map["name" -> "full name"] 然后

  customizedFieldNameChange["name"] = "fullName"
  OldClass obj = new ObjectMapper().readValue[OldClass]({"id": 12, "name": "Bob"}, customizedFieldNameChange)

会将 fullName 设置为“Bob”(即,它将在“obj”上为 json 字符串中的“name”字段调用 setFullName())?

【问题讨论】:

    标签: json scala serialization jackson backwards-compatibility


    【解决方案1】:

    您必须使用JsonDeserializer 从 json 中动态读取值。

    下面是一个Java示例,

    public class CustomDeserializer extends JsonDeserializer<OldClass> {
        @Override
        public OldClass deserialize(JsonParser jsonParser, DeserializationContext context)
                throws IOException, JsonProcessingException {
            JsonNode node = jsonParser.getCodec().readTree(jsonParser);
            int id = (Integer) ((IntNode) node.get("id")).numberValue();
            String fullName = node.get("name").asText();
            return new OldClass(id, fullName);
        }
    }
    

    最后,反序列化

    ObjectMapper mapper = new ObjectMapper();
    SimpleModule module = new SimpleModule();
    module.addDeserializer(OldClass.class, new CustomDeserializer());
    mapper.registerModule(module);
    OldClass values = mapper.readValue(json, OldClass.class);
    

    详细解释请查看tutorial

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-14
      • 2015-08-23
      • 1970-01-01
      • 2022-12-08
      • 2012-04-22
      • 2020-02-12
      • 1970-01-01
      • 2012-09-13
      相关资源
      最近更新 更多