我有一个递归对象Node.java,我可以使用Jackson序列化,但无法将其反序列化。
Node.java
public class Node {
private final String id;
private final Map<String, Node> embeddedNodes;
public Node(String id, Map<String, Node> embeddedNodes) {
this.id = id;
this.embeddedNodes = embeddedNodes;
}
public String getId() {
return id;
}
public Map<String, Node> getEmbeddedNodes() {
return embeddedNodes;
}
}
杰克逊序列化
public static class NodeSerializer extends JsonSerializer<Node> {
@Override
public void serialize(Node node, JsonGenerator jgen, SerializerProvider provider) throws IOException{
jgen.writeStartObject();
jgen.writeStringField("id", node.getId());
Map<String, Node> embeddedNodesMap = node.getEmbeddedNodes();
if (!embeddedNodesMap.isEmpty()) {
jgen.writeObjectFieldStart("embeddedNodes");
for (Map.Entry<String, Node> entry : embeddedNodesMap.entrySet()) {
jgen.writeObjectField(entry.getKey(), entry.getValue());
}
jgen.writeEndObject();
}
jgen.writeEndObject();
}
}
示例节点实例
Node node0 = new Node("0", Maps.<String, Node>newHashMap());
Map<String, Node> embeddedNodes1 = Maps.newHashMap();
embeddedNodes1.put("zero", node0);
Node node1 = new Node("1", embeddedNodes1);
Node node2 = new Node("2", Maps.<String, Node>newHashMap());
Map<String, Node> embeddedNodes = Maps.newHashMap();
embeddedNodes.put("first", node1);
embeddedNodes.put("second", node2);
Node node3 = new Node("3", embeddedNodes);
String jsonStr = mapper.writeValueAsString(node3);
生成JSON:
{
"id": "3",
"embeddedNodes": {
"second": {
"id": "2"
},
"first": {
"id": "1",
"embeddedNodes": {
"zero": {
"id": "0"
}
}
}
}
}
但是我无法为此编写相应的反序列化器,任何帮助都表示赞赏。
class NodeDeserializer extends JsonDeserializer<Node> {
@Override
public Node deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
//how do we write this??
return null;
}
}
答案 0 :(得分:1)
@ vinodv26在 NodeDeserializer 中,它不是使用ObjectMapper
类来解析(再次)嵌入式Node
的JSON的最有效方法。而不是:
Node embedNode = mapper.readValue(jsonNode.toString(), Node.class);
最好使用:
Node embedNode = jp.getCodec().treeToValue(jsonNode, Node.class);
或者,如果您要查找的内容是在embeddedNodes
属性为空时忽略它,则可以使用mapper.setSerializationInclusion(Include.NON_EMPTY)
或使用{{Node
类注释1}}。这样您就不需要自定义序列化或反序列化类,但您需要删除@JsonInclude(Include.NON_EMPTY)
属性中的final
修饰符并添加空构造函数和setter。
答案 1 :(得分:0)
经过几次尝试后,我想出了以下解串器,但不确定这是否是正确的方法:
private static class NodeDeserializer extends JsonDeserializer<Node> {
@Override
public Node deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
JsonNode node = jp.getCodec().readTree(jp);
String id = node.get("id").asText();
Map<String, Node> embeddedNodes = Maps.newHashMap();
JsonNode embeddedNodesJsonNode = node.get("embeddedNodes");
if (embeddedNodesJsonNode != null) {
Iterator<String> embeddedElementNames = embeddedNodesJsonNode.fieldNames();
while (embeddedElementNames.hasNext()) {
String embedName = embeddedElementNames.next();
JsonNode jsonNode = embeddedNodesJsonNode.get(embedName);
Node embedNode = mapper.readValue(jsonNode.toString(), Node.class);
embeddedNodes.put(embedName, embedNode);
}
}
return new Node(id, embeddedNodes);
}
}