假设我有一个看起来像的json对象:
{
id: 1,
name: "john doe"
spouse: 2
}
和我希望它将它反序列化为:
class Person{
private Long id;
private String name;
private Person spouse;
//getters/setters
}
在反序列化JSON时,有没有办法告诉jackson将spouse: 2
属性扩展为id=2
的新Person POJO?
由于将JSON反序列化为持久性实体,并且希望能够轻松地保持这些实体之间的关系,我遇到了这个问题。
答案 0 :(得分:3)
除了完整的反序列化器之外,还有一种更简单的方法:使用单个int-arg构造函数定义POJO,如下所示:
class Person {
int id;
public Person(int id) {
this.id = id;
}
}
这实际上是有效的,因为Jackson将尝试找到有限数量的特殊构造函数(采用String,int,long,double或boolean的单arg公共构造函数)。
您也可以选择用@JsonCreator表示这些 - 如果构造函数不是公共的,您必须这样做,以使其可被发现。但对公众来说,这不是必需的。
答案 1 :(得分:2)
杰克逊当然不可能从数字Person
推断出代表配偶的完全填充的2
对象。您可能需要注册一个自定义反序列化器来检查输入是否为整数,如果是,则从配置的任何位置查找配偶。对于包含对自己的引用的类,我没有做过这种事情(例如,Person
包含Person
),所以我只能给你粗略的指导。
我相信这可能仅适用于杰克逊版本1.9
或更高版本。基本上,您可以使用对象映射器注册模块,该模块告诉Jackson使用自定义反序列化器。
SimpleModule module = new SimpleModule("PeopleModule", new Version(1, 1, 0, null);
module.addDeserializer(Person.class, new JacksonPersonDeserializer());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
或者在Person
类本身上,您可以执行以下操作:
class Person {
@JsonDeserialize(using=JacksonPersonDeserializer.class)
Person spouse;
}
这可以在1.9
之前使用,但会污染您的对象。无论哪种方式,您都需要编写自定义反序列化器。