【发布时间】:2014-08-22 11:40:17
【问题描述】:
我正在使用 fasterXML 的 Jackson (v2.3.3) 库来反序列化和序列化自定义类。类定义如下:
public class Person {
private String name;
private Map<String, Person> children;
// lots of other fields of different types with no issues
}
映射children 的键是name 字段。我以 JSON 格式接收数据,每个 person 对象的结构如下(我省略了其他字段):
{"name":"Bob", "children":[{"name":"Jimmmy"},{"name":"Judy"}]}
(许多字段如children是可选的,为null时不序列化)
到目前为止,我一直将孩子存储在 List<Person> 中,没有任何问题,但是许多新用例需要访问名称集或使用其名称作为键的特定人员。这就是为什么我决定使用地图来存储它们。
经过一番研究,我认为最好的方法是使用注解@JsonDeserialize 和@JsonSerialize 分别带有JsonDeserializer 和JsonSerializer 作为字段children 的参数:
public class Person {
private String id;
@JsonSerialize(using=MySerializer.class)
@JsonDeserialize(using=MyDeserializer.class)
private Map<String, Person> friends;
// lots of other fields
}
我的问题是:这样的 JsonSerializer/JsonDeserializer 是否存在,如果不存在,我该如何定义?
编辑:我已经开始实现自定义反序列化器,但我得到了这个异常:
com.fasterxml.jackson.databind.JsonMappingException: Class has no default (no arg) constructor
这很奇怪,因为我定义了一个默认构造函数。这是我的自定义反序列化器:
public class MyDeserializer extends JsonDeserializer<Map<String, Person>> {
public MyDeserializer() {
}
@Override
public Map<String, Person> deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode personsNodeArray = jp.getCodec().readTree(jp);
Map<String, Person> newChildren = null;
if (personsNodeArray.isArray() && personsNodeArray.size() > 0) {
newChildren = new HashMap<String, Person>();
for (JsonNode personNode : personsNodeArray) {
String id = personNode.get("name").asText();
// jsonMapper is a default ObjectMapper
newChildren.put(id, jsonMapper.readValue(personNode.toString(), Person.class));
}
}
return newChildren;
}
}
【问题讨论】:
标签: serialization map jackson deserialization arrays