【问题标题】:Jackson deserializing recursive object杰克逊反序列化递归对象
【发布时间】:2014-06-10 10:33:31
【问题描述】:

我有一个递归对象 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;
        }
    }

【问题讨论】:

  • 你找到解决方案了吗?

标签: json serialization recursion jackson deserialization


【解决方案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) 或使用 @JsonInclude(Include.NON_EMPTY) 注释 Node 类。这样您就不需要自定义序列化或反序列化类,但您需要删除Node 属性中的final 修饰符并添加一个空的构造函数和设置器。

【讨论】:

    【解决方案2】:

    经过几次尝试,我想出了以下反序列化程序,但不确定这是否是正确的方法:

    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);
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2019-11-15
      • 1970-01-01
      • 2021-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-02
      • 2013-05-11
      • 2018-03-16
      相关资源
      最近更新 更多