Java Jackson多态属性的自定义属性名称到类型映射

Java Jackson多态属性的自定义属性名称到类型映射,java,jackson,Java,Jackson,我正在尝试反序列化一个相当复杂的POJOs JSON,在这里我需要定义一个特定的属性名来进行类型解析,但未能完成这个相当简单的特性 假设一个类如下: class Example { int id; Map<String,Object> extras; } 现在,我想告诉Jackson按实际类型显式反序列化extras对象。所以我需要告诉Jackson如何将“object1”映射到类型A,将“object2”映射到类型B 这可能吗?谢谢 有一个很好的指南来指导如何处理它: 还

我正在尝试反序列化一个相当复杂的POJOs JSON,在这里我需要定义一个特定的属性名来进行类型解析,但未能完成这个相当简单的特性

假设一个类如下:

class Example {
  int id;
  Map<String,Object> extras;
}
现在,我想告诉Jackson按实际类型显式反序列化extras对象。所以我需要告诉Jackson如何将“object1”映射到类型A,将“object2”映射到类型B


这可能吗?谢谢

有一个很好的指南来指导如何处理它:

还有另一个教程:

第二个教程中的第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);
}
Map types=…//受支持类型的映射
JsonToken token=jsonParser.nextToken();
如果(token==JsonToken.FIELD_NAME){/“object1”等。
String name=jsonParser.getCurrentName();
Class type=types.get(name);
Object Object=jsonParser.readValueAs(类型);
}

如果Extras映射仅包含这两个对象(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;
}

这可以使用自定义反序列化器实现;例如,见此。在一个简单的例子中,您需要告诉Jackson应该将字段解组到什么类型;尽管如此,如果序列化数据(JSON)正在动态更改,这可能很容易出错

然后,您可以很容易地对字段的setter进行注释,如下所示:

ObjectA value;

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

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

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

是的,有可能。但您可能需要为映射中的每个对象发送json类型信息。我无法控制收到的json,即使我知道对象类型。您如何辨别对象类型?通过名称,我知道键“object1”属于类型A。谢谢,从第二个教程来看,我似乎需要编写一个处理反序列化的模块。:)不,我应该澄清,这涉及两种以上的类型。对象名称和对象类型之间是否存在1对1的关系?如果是这样,您可以扩展Extras类以包括所有可能的案例。
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();