如何用 Jackson 序列化/反序列化 DefaultMutableTreeNode?

我们如何DefaultMutableTreeNode使用 Jackson 将 Swing 序列化/反序列化到 JSON 或从 JSON 序列化/反序列化?

有一个相关的问题 How to serialize DefaultMutableTreeNode (Java) to JSON? . 但它要求 Gson,而不是 Jackson(仅用于序列化,而不用于反序列化)。

对于DefaultMutableTreeNodeJackson 的默认序列化/序列化不起作用,原因有很多:

  • 它包含再次是DefaultMutableTreeNode对象的子项。但它没有规范的 getter 和 setter 方法(如getChildren()and setChildren(...))。

  • 它包含反向引用(通过方法getParent()getRoot()getPath()),这将导致序列化期间的无限递归和 StackOverflow。

  • 它有许多不需要序列化的冗余 getter 方法(如isLeaf()getNextSibling(), , ...),因为它们是从其他属性派生的。getLastChild()


慕姐8265434
浏览 72回答 1
1回答

呼如林

您可以ObjectMapper使用 a 自定义 Jackson'sJsonSerializer并JsonDeserializer专门用于将 a 转换DefaultMutableTreeNode为 JSON,反之亦然。ObjectMapper objectMapper = new ObjectMapper()&nbsp; &nbsp; .registerModule(new SimpleModule()&nbsp; &nbsp; &nbsp; &nbsp; .addSerializer(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeSerializer())&nbsp; &nbsp; &nbsp; &nbsp; .addDeserializer(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeDeserializer()))&nbsp; &nbsp; .enable(SerializationFeature.INDENT_OUTPUT);下面DefaultMutableTreeNodeSerializer负责将 a 转换DefaultMutableTreeNode为 JSON。它将allowsChildren,userObject和children of写入DefaultMutableTreeNodeJSON。它不写它parent,因为那会导致无限递归和 StackOverflowError。相反,父子关系被编码在 JSON 输出的嵌套结构中。public class DefaultMutableTreeNodeSerializer extends JsonSerializer<DefaultMutableTreeNode> {&nbsp; &nbsp; @Override&nbsp; &nbsp; public void serialize(DefaultMutableTreeNode node, JsonGenerator gen, SerializerProvider serializers)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; gen.writeStartObject();&nbsp; &nbsp; &nbsp; &nbsp; gen.writeBooleanField("allowsChildren", node.getAllowsChildren());&nbsp; &nbsp; &nbsp; &nbsp; gen.writeObjectField("userObject", node.getUserObject());&nbsp; &nbsp; &nbsp; &nbsp; if (node.getChildCount() > 0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; gen.writeObjectField("children", Collections.list(node.children()));&nbsp; &nbsp; &nbsp; &nbsp; // Don't write node.getParent(), it would lead to infinite recursion.&nbsp; &nbsp; &nbsp; &nbsp; gen.writeEndObject();&nbsp; &nbsp; }}为了测试,您可以序列化 sample 的根节点JTree,然后再次反序列化。JTree tree = new JTree(); // a sample treeObject root = tree.getModel().getRoot(); // a DefaultMutableTreeNodeString json = objectMapper.writeValueAsString(root);System.out.println(json);DefaultMutableTreeNode root2 = objectMapper.readValue(json, DefaultMutableTreeNode.class);它生成以下 JSON 输出:{&nbsp; "allowsChildren" : true,&nbsp; "userObject" : "JTree",&nbsp; "children" : [ {&nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; "userObject" : "colors",&nbsp; &nbsp; "children" : [ {&nbsp; &nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; &nbsp; "userObject" : "blue"&nbsp; &nbsp; }, {&nbsp; &nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; &nbsp; "userObject" : "violet"&nbsp; &nbsp; }, {&nbsp; &nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; &nbsp; "userObject" : "red"&nbsp; &nbsp; }, {&nbsp; &nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; &nbsp; "userObject" : "yellow"&nbsp; &nbsp; } ]&nbsp; }, {&nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; "userObject" : "sports",&nbsp; &nbsp; "children" : [ {&nbsp; &nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; &nbsp; "userObject" : "basketball"&nbsp; &nbsp; }, {&nbsp; &nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; &nbsp; "userObject" : "soccer"&nbsp; &nbsp; }, {&nbsp; &nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; &nbsp; "userObject" : "football"&nbsp; &nbsp; }, {&nbsp; &nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; &nbsp; "userObject" : "hockey"&nbsp; &nbsp; } ]&nbsp; }, {&nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; "userObject" : "food",&nbsp; &nbsp; "children" : [ {&nbsp; &nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; &nbsp; "userObject" : "hot dogs"&nbsp; &nbsp; }, {&nbsp; &nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; &nbsp; "userObject" : "pizza"&nbsp; &nbsp; }, {&nbsp; &nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; &nbsp; "userObject" : "ravioli"&nbsp; &nbsp; }, {&nbsp; &nbsp; &nbsp; "allowsChildren" : true,&nbsp; &nbsp; &nbsp; "userObject" : "bananas"&nbsp; &nbsp; } ]&nbsp; } ]}下面DefaultMutableTreeNodeDeserializer负责将 JSON 转换回DefaultMutableTreeNode.这DefaultMutableTreeNode非常不像 POJO,因此不能与杰克逊一起很好地工作。因此,我创建了一个表现良好的POJO帮助器类(具有属性 和) allowsChildren,并让 Jackson 将 JSON 内容反序列化到该类中。然后我将对象(及其 子对象)转换为对象(带有子对象)。userObjectchildrenPOJOPOJODefaultMutableTreeNodeDefaultMutableTreeNodepublic class DefaultMutableTreeNodeDeserializer extends JsonDeserializer<DefaultMutableTreeNode> {&nbsp; &nbsp; @Override&nbsp; &nbsp; public DefaultMutableTreeNode deserialize(JsonParser parser, DeserializationContext context)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; return parser.readValueAs(POJO.class).toDefaultMutableTreeNode();&nbsp; &nbsp; }&nbsp; &nbsp; private static class POJO {&nbsp; &nbsp; &nbsp; &nbsp; private boolean allowsChildren;&nbsp; &nbsp; &nbsp; &nbsp; private Object userObject;&nbsp; &nbsp; &nbsp; &nbsp; private List<POJO> children;&nbsp; &nbsp; &nbsp; &nbsp; // no need for: POJO parent&nbsp; &nbsp; &nbsp; &nbsp; public DefaultMutableTreeNode toDefaultMutableTreeNode() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DefaultMutableTreeNode node = new DefaultMutableTreeNode();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node.setAllowsChildren(allowsChildren);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node.setUserObject(userObject);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (children != null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (POJO child : children) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node.add(child.toDefaultMutableTreeNode());&nbsp; // recursion&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // this did also set the parent of the child-node&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return node;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // Following setters needed by Jackson's deserialization:&nbsp; &nbsp; &nbsp; &nbsp; public void setAllowsChildren(boolean allowsChildren) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.allowsChildren = allowsChildren;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public void setUserObject(Object userObject) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.userObject = userObject;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public void setChildren(List<POJO> children) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.children = children;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java