【问题标题】:Jackson Custom Property-Name to Type Mapping for Polymorphic PropertiesJackson 自定义属性名称到多态属性的类型映射
【发布时间】:2012-10-17 10:04:26
【问题描述】:

我正在尝试反序列化一个相当复杂的 POJO JSON,我需要在其中定义一个特定的属性名称来进行类型解析,但未能找到这个相当简单的功能。

假设一个类:

class Example {
  int id;
  Map<String,Object> extras;
}

Jackson 正在将 POJO 正确序列化为 JSON,其中映射被序列化为键值映射,就像预期的那样:

{...
id:5,
extras:{object1:{...}, object2:{...}}
...}

现在我想告诉杰克逊通过它们的实际类型显式反序列化额外对象。所以我需要告诉杰克逊以某种方式将“object1”映射到类型 A,将“object2”映射到类型 B。

这可能吗?谢谢。

【问题讨论】:

  • 是的,这是可能的。但是您可能需要为地图中的每个对象发送 json 类型信息。
  • 我无法控制收到的 json,即使我知道对象类型。
  • 您是如何辨别对象类型的?
  • 按名称,我知道键“object1”属于类型A。

标签: java jackson


【解决方案1】:

有很好的指导如何处理它:http://www.cowtowncoder.com/blog/archives/2010/03/entry_372.html

还有一个教程:
http://programmerbruce.blogspot.de/2011/05/deserialize-json-with-jackson-into.html

可以修改第二个教程中的第 6 个示例,反序列化器将具有类似于以下内容的循环:

Map<String, Class> types = ...// map of supported types
JsonToken token = jsonParser.nextToken();
if(token == JsonToken.FIELD_NAME){ // "object1" etc.
    String name = jsonParser.getCurrentName();
    Class type = types.get(name);
    Object object = jsonParser.readValueAs(type);
}

【讨论】:

  • 谢谢,从第二个教程看来我需要编写一个处理反序列化的模块。
【解决方案2】:

最简单的方法是启用所谓的“默认类型”——它大致相当于添加@JsonTypeInfo 注释(支持多态类型处理)——这会在值中添加类型信息。所以:

ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();

【讨论】:

    【解决方案3】:

    如果 Extras 地图仅包含这 2 个对象(object1 和 object2),您可以执行以下操作

    class TypeA {
        // TypeA body
    }
    
    class TypeB {
        // TypeB body
    }
    
    class Extras {
        private TypeA object1;
        private TypeB object2;
        // Getters and setters
    }
    
    class Example {
        int id;
        Extras extras;
    }
    

    【讨论】:

    • :) 不,我应该澄清一下,涉及的类型不止两种。
    • 对象名称和对象类型之间是否存在一对一的关系?如果是这样,您可以扩展 Extras 类以包含所有可能的情况。
    【解决方案4】:

    这可以使用自定义反序列化器;例如,请参阅此link。简而言之,您需要告诉 Jackson 应该将字段解组为哪种类型;不过,如果您的序列化数据 (JSON) 是动态变化的,这可能很容易出错。

    然后您可以像这样轻松地注释字段的设置器:

    ObjectA value;
    
    @JsonDeserialize(using=ObjectADeserializer.class)
    public void setValue(ObjectA objectAValue) {
       this.value = objectAValue;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-06-09
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 2015-06-03
      • 2012-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多