gpt4 book ai didi

java - 如何将 DefaultMutableTreeNode (Java) 序列化为 JSON?

转载 作者:行者123 更新时间:2023-12-01 19:44:28 24 4
gpt4 key购买 nike

如何将树(使用 DefaultMutableTreeNode 类在 Java 中实现)序列化为 JSON(用于通过 RESTful 方法传输到 iOS 客户端)?

我尝试过:

String jsonString = (new Gson()).toJson(topNode);
// topNode is DefaultMutableTreeNode at the root

它因StackOverflowError而崩溃。

最佳答案

Swing 的 DefaultMutableTreeNode类是一种树状数据结构其中包含相同类型的实例作为 childrenparent。这就是为什么 Gson 的默认序列化器会陷入无限递归因此引发了 StackOverflowError

要解决这个问题,您需要使用更智能的 JsonSerializer 自定义您的 Gson专门用于将 DefaultMutableTreeNode 转换为 JSON。作为奖励,您可能还想提供 JsonDeserializer用于将此类 JSON 转换回 DefaultMutableTreeNode

为此,创建您的 Gson 实例不仅仅是通过 new Gson(),而是通过

Gson gson = new GsonBuilder()
.registerTypeAdapter(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeSerializer())
.registerTypeAdapter(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeDeserializer())
.setPrettyPrinting()
.create();

下面的DefaultMutableTreeNodeSerializer负责用于将 DefaultMutableTreeNode 转换为 JSON。它将其属性 allowsChildrenuserObjectchildren 转换为 JSON。请注意,它不会将 parent 属性转换为 JSON,因为这样做会再次产生无限递归。

public class DefaultMutableTreeNodeSerializer implements JsonSerializer<DefaultMutableTreeNode> {

@Override
public JsonElement serialize(DefaultMutableTreeNode src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("allowsChildren", src.getAllowsChildren());
jsonObject.add("userObject", context.serialize(src.getUserObject()));
if (src.getChildCount() > 0) {
jsonObject.add("children", context.serialize(Collections.list(src.children())));
}
return jsonObject;
}
}

为了进行测试,我们将示例 JTree 的根节点序列化为 JSON,然后再次反序列化它。

tree

JTree tree = new JTree();  // create a sample tree
Object topNode = tree.getModel().getRoot(); // a DefaultMutableTreeNode
String jsonString = gson.toJson(topNode);
System.out.println(jsonString);
DefaultMutableTreeNode topNode2 = gson.fromJson(jsonString, DefaultMutableTreeNode.class);

它生成以下 JSON 输出:

{
"allowsChildren": true,
"userObject": "JTree",
"children": [
{
"allowsChildren": true,
"userObject": "colors",
"children": [
{
"allowsChildren": true,
"userObject": "blue"
},
{
"allowsChildren": true,
"userObject": "violet"
},
{
"allowsChildren": true,
"userObject": "red"
},
{
"allowsChildren": true,
"userObject": "yellow"
}
]
},
{
"allowsChildren": true,
"userObject": "sports",
"children": [
{
"allowsChildren": true,
"userObject": "basketball"
},
{
"allowsChildren": true,
"userObject": "soccer"
},
{
"allowsChildren": true,
"userObject": "football"
},
{
"allowsChildren": true,
"userObject": "hockey"
}
]
},
{
"allowsChildren": true,
"userObject": "food",
"children": [
{
"allowsChildren": true,
"userObject": "hot dogs"
},
{
"allowsChildren": true,
"userObject": "pizza"
},
{
"allowsChildren": true,
"userObject": "ravioli"
},
{
"allowsChildren": true,
"userObject": "bananas"
}
]
}
]
}

下面的DefaultMutableTreeNodeDeserializer负责用于将 JSON 转换回 DefaultMutableTreeNode

它使用与反序列化器相同的想法 How to serialize/deserialize a DefaultMutableTreeNode with Jackson?DefaultMutableTreeNode 不太像 POJO,因此不与Gson配合良好。因此,它使用一个行为良好的 POJO 帮助器类(具有属性allowsChildrenuserObjectchildren)并让 Gson将 JSON 内容反序列化到此类中。然后,POJO 对象(及其 POJO 子对象)被转换为DefaultMutableTreeNode 对象(带有 DefaultMutableTreeNode 子级)。

public class DefaultMutableTreeNodeDeserializer implements JsonDeserializer<DefaultMutableTreeNode> {

@Override
public DefaultMutableTreeNode deserialize(JsonElement json, Type type, JsonDeserializationContext context) {
return context.<POJO>deserialize(json, POJO.class).toDefaultMutableTreeNode();
}

private static class POJO {

private boolean allowsChildren;
private Object userObject;
private List<POJO> children;
// no need for: POJO parent

public DefaultMutableTreeNode toDefaultMutableTreeNode() {
DefaultMutableTreeNode node = new DefaultMutableTreeNode();
node.setAllowsChildren(allowsChildren);
node.setUserObject(userObject);
if (children != null) {
for (POJO child : children) {
node.add(child.toDefaultMutableTreeNode()); // recursion!
// this did also set the parent of the child-node
}
}
return node;
}

// Following setters needed by Gson's deserialization:

public void setAllowsChildren(boolean allowsChildren) {
this.allowsChildren = allowsChildren;
}

public void setUserObject(Object userObject) {
this.userObject = userObject;
}

public void setChildren(List<POJO> children) {
this.children = children;
}
}
}

关于java - 如何将 DefaultMutableTreeNode (Java) 序列化为 JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53997112/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com