ZK框架中如何序列化DefaultTreeModel为JSON?Gson序列化子节点为空
解决ZK DefaultTreeModel用Gson序列化子节点为null的问题
Gson默认依赖反射访问对象的public字段或JavaBean规范的getter方法,但ZK的TreeNode和DefaultTreeModel的子节点、根节点数据并非通过public字段暴露,而是通过组件自身API方法(如getChildren()、getRoot())获取,因此默认序列化无法识别这些数据,导致子节点显示为null。
解决方案
为TreeNode和DefaultTreeModel自定义Gson序列化器,手动通过API提取数据并完成序列化。
1. 自定义TreeNode序列化器
负责处理TreeNode<TreeDataDTO>的序列化,提取节点业务数据和子节点:
import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; import org.zkoss.zul.TreeNode; import java.lang.reflect.Type; import java.util.List; public class ZkTreeNodeSerializer implements JsonSerializer<TreeNode<TreeDataDTO>> { @Override public JsonElement serialize(TreeNode<TreeDataDTO> node, Type typeOfSrc, JsonSerializationContext context) { JsonObject jsonNode = new JsonObject(); // 序列化节点携带的业务数据TreeDataDTO jsonNode.add("data", context.serialize(node.getData())); // 序列化子节点列表 List<TreeNode<TreeDataDTO>> children = node.getChildren(); if (children != null && !children.isEmpty()) { jsonNode.add("children", context.serialize(children)); } return jsonNode; } }
2. 自定义DefaultTreeModel序列化器
负责提取DefaultTreeModel的根节点并触发序列化:
import com.google.gson.JsonElement; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; import org.zkoss.zul.DefaultTreeModel; import org.zkoss.zul.TreeNode; import java.lang.reflect.Type; public class ZkTreeModelSerializer implements JsonSerializer<DefaultTreeModel<TreeNode<TreeDataDTO>>> { @Override public JsonElement serialize(DefaultTreeModel<TreeNode<TreeDataDTO>> model, Type typeOfSrc, JsonSerializationContext context) { // 序列化根节点,子节点会由TreeNode序列化器递归处理 return context.serialize(model.getRoot()); } }
3. 注册序列化器并执行序列化
创建Gson实例时注册自定义序列化器,再完成序列化操作:
import com.google.gson.Gson; import com.google.gson.GsonBuilder; // 注册自定义序列化器 Gson gson = new GsonBuilder() .registerTypeAdapter(TreeNode.class, new ZkTreeNodeSerializer()) .registerTypeAdapter(DefaultTreeModel.class, new ZkTreeModelSerializer()) .create(); // 执行序列化 String jsonString = gson.toJson(dataTree);
额外说明
- 如果
TreeDataDTO包含特殊类型字段(如日期、自定义枚举),可单独为其添加自定义序列化器,确保数据转换正确。 - 确保使用的ZK版本中
TreeNode.getChildren()和DefaultTreeModel.getRoot()方法能正常返回数据,这是ZK组件的标准API,无需额外处理。
内容的提问来源于stack exchange,提问作者hem6d
相关产品推荐
相关产品推荐

