Kotlin嵌套JSON节点增删改问题:GraphView树状图生成器异常排查
解决嵌套JSON节点增删改与GSON栈溢出问题
一、修复GSON栈溢出异常
栈溢出的核心原因是节点类存在循环引用(比如Node类中持有父节点parent的引用),GSON序列化时会无限递归遍历父节点、祖父节点,最终触发栈溢出。解决方法如下:
1. 排除循环引用字段
在节点类中给循环引用的字段添加@JsonIgnore注解,直接跳过序列化/反序列化:
data class Node( var id: String, var content: String, @JsonIgnore // 忽略父节点引用,避免循环递归 var parent: Node? = null, var children: MutableList<Node> = mutableListOf() )
2. 自定义序列化策略
如果需要保留父节点的内存引用但不想序列化,可通过GsonBuilder配置排除策略:
val gson = GsonBuilder() .addSerializationExclusionStrategy(object : ExclusionStrategy { override fun shouldSkipField(f: FieldAttributes): Boolean { return f.name == "parent" // 仅排除parent字段 } override fun shouldSkipClass(clazz: Class<*>?): Boolean = false }) .create()
二、实现嵌套JSON节点的增删改
放弃String.replace()这种脆弱的文本替换方式,直接基于对象结构操作:
1. 定义可修改的节点数据类
用带MutableList的节点类映射JSON,直接操作对象完成增删改:
data class Node( var id: String, var content: String, @JsonIgnore var parent: Node? = null, var children: MutableList<Node> = mutableListOf() )
2. 核心操作实现
修改节点:通过遍历找到目标节点后直接修改属性
fun updateNodeContent(root: Node, targetId: String, newContent: String) { val targetNode = findNodeById(root, targetId) targetNode?.content = newContent } // 递归遍历查找节点 private fun findNodeById(root: Node, targetId: String): Node? { if (root.id == targetId) return root for (child in root.children) { val found = findNodeById(child, targetId) if (found != null) return found } return null }新增节点:找到父节点后直接添加到子节点列表
fun addChildNode(parentNode: Node, newNode: Node) { newNode.parent = parentNode parentNode.children.add(newNode) }删除节点:找到父节点后从子列表移除目标节点
fun deleteNode(root: Node, targetId: String) { val targetNode = findNodeById(root, targetId) targetNode?.parent?.children?.remove(targetNode) }
3. 与AWS数据库交互
序列化/反序列化时用上述配置好的Gson实例,确保JSON结构与节点类完全匹配:
// 将节点树转为JSON存储到AWS val json = gson.toJson(rootNode) // 从AWS加载JSON转为节点树 val rootNode = gson.fromJson(jsonString, Node::class.java)
内容的提问来源于stack exchange,提问作者asanme
相关产品推荐
相关产品推荐

