将数据转换成树型层级的Json格式的String
有时候我们项目里面需要将树型关系的数据转换成Json格式的String字符串
假设数据库中的数据如下

需要转换后输出的字符串的结果如下(对应的层级的关系)
[
{name:'爷爷',id:'1',content:'老人辈',parentId:'0',expanded: true,children:[
{name:'爸爸',id:'2',content:'长辈',parentId:'1',expanded: true,children:[
{name:'儿子',id:'4',content:'晚辈',parentId:'2',leaf:true},{name:'女儿',id:'5',content:'晚辈',parentId:'2',leaf:true}
]},{name:'叔叔',id:'3',content:'长辈',parentId:'1',leaf:true}
]
}
]
相应的代码资料网上可以找到
1、树节点类
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* 树节点类(用于模拟树型结构关系中的节点)
*/
public class TreeNode {
public static final String TREENODE_ATTRIBUTE_NAME_NAME = "name"; // 字段属性name
public static final String TREENODE_ATTRIBUTE_NAME_ID = "id"; // 字段属性id
private Map<String,Object> attributes = new HashMap<String, Object>(); // 字段属性的Map private TreeNode parent = null; //当前节点的父节点
private List<TreeNode> child = new ArrayList<TreeNode>(); //当前节点的子节点
private boolean isCheck = false; //当前节点是否被勾选标志 /*
无参构造函数
*/
public TreeNode(){
super();
} /**
* 获取/设置 节点的属性name
* @return
*/
public String getName() {
return (String) attributes.get(TREENODE_ATTRIBUTE_NAME_NAME);
}
public void setName(String name) {
attributes.put(TREENODE_ATTRIBUTE_NAME_NAME,name);
} /**
* 获取/设置 节点的属性id
* @return
*/
public String getId() {
return (String) attributes.get(TREENODE_ATTRIBUTE_NAME_ID);
}
public void setId(String id) {
attributes.put(TREENODE_ATTRIBUTE_NAME_ID,id);
} /**
* 获取/设置 节点需要在树形结构中显示的信息
* @return
*/
public Map<String, Object> getAttributes() {
return attributes;
}
public void setAttributes(Map<String, Object> attributes) {
this.attributes = attributes;
} /**
* 获取/设置 节点是否被勾选信息
* @return
*/
public boolean isCheck() {
return isCheck;
}
public void setCheck(boolean check) {
isCheck = check;
} /**
* 获取/设置 节点父节点信息
* @return
*/
public TreeNode getParent() {
return parent;
}
public void setParent(TreeNode parent) {
this.parent = parent;
} /**
* 是否存在/获取/设置/添加 节点子节点信息
* @return
*/
public boolean hasChildren(){
return child.size()>0;
}
public List<TreeNode> getChild() {
return child;
}
public void setChild(List<TreeNode> child) {
this.child = child;
}
public void addChild(TreeNode treeNode){
treeNode.setParent(this);
child.add(treeNode);
}
}
2、树型节点的属性Map类
import java.util.HashMap;
import java.util.Map; /**
* 树型节点的属性Map(用于操作节点的各个属性,如name,id)
*/
public class TreeAttributesMap {
private Map<String,Object> attributes = new HashMap<>(); //存放属性的Map /**
* 有参构造函数
* @param id
* @param name
*/
public TreeAttributesMap(Object id,Object name){
attributes.put(TreeNode.TREENODE_ATTRIBUTE_NAME_ID,id);
attributes.put(TreeNode.TREENODE_ATTRIBUTE_NAME_NAME,name);
} /**
* 获取属性的Map
* @return
*/
public Map<String, Object> getAttributes() {
return attributes;
} /**
* 往属性的Map中添加属性
* @param name
* @param value
*/
public void putAttributes(String name,Object value){
attributes.put(name,value);
}
}
3、定义一些树型结构相关的接口(方便以后拓展)
/**
* 定义一般普通的树节点的接口
*/
public interface ISimpleTreeNode { /**
* 每个树节点都具备自身的一些属性
* @return
*/
public TreeAttributesMap getTreeAttributesMap();
}
/**
* 定义层级树节点的接口
*/
public interface ILevelTreeNode extends ISimpleTreeNode{ public int getParentId();
public int getId();
}
public interface ITreeParser<T> {
/**
* 解析数据
* @param data
* @return
*/
List<T> parser(Object data);
}
4、树类
/**
* 树类 (根据自身需求对数据进行解析和转换)
*/
public class Tree {
private ITreeParser<TreeNode> treeParser;
private int treeType; //转换标志(可以拓展)
private Object data; //数据源 /**
* 有参构造函数
* @param data
* @param treeType
*/
public Tree(Object data,int treeType){
this.data = data;
this.treeType = treeType;
} /**
* 数据转换 data ---> json格式
* @return json格式的String
*/
public String toJsonTree(){
String json = "";
if (treeType == 1){
treeParser = new LevelTreeParser();
json = toLevelTree();
}else if (treeType == 2){
//XXX树型结构
}else if (treeType == 3){
//XXX树型结构
}else{
//other树型结构
}
return json;
} private String toLevelTree(){
String jsonString = "";
List<TreeNode> nodes = treeParser.parser(data);
StringBuffer sb = new StringBuffer();
sb.append("[");
parserLevelNodeToJson(sb,nodes);
sb.append("]");
jsonString = sb.toString();
return jsonString;
} private void parserLevelNodeToJson(StringBuffer sb,List<TreeNode> nodes){
Iterator<TreeNode> it = nodes.iterator();
while(it.hasNext()){
TreeNode node = it.next();
boolean isLeaf = node.hasChildren();
sb.append("{");
Map<String,Object> attributes = node.getAttributes();
for(String key:attributes.keySet()){
Object obj = attributes.get(key);
if (obj != null)
sb.append(key + ":'" + obj.toString() + "',");
}
if (isLeaf){
sb.append("expanded: true,children: [");
parserLevelNodeToJson(sb,node.getChild());
if (it.hasNext()){
sb.append("]},");
}else{
sb.append("]}");
}
}else{
if (it.hasNext()){
sb.append("leaf:true},");
}else{
sb.append("leaf:true}");
}
}
}
}
}
5、层级树状结构解析实现类
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class LevelTreeParser implements ITreeParser<TreeNode>{ private Map<Object,TreeNode> treeNodeMap = new HashMap<Object, TreeNode>();
TreeNode root = new TreeNode(); public List<TreeNode> parser(Object data){
//将数据data强转为List<ILevelTreeNode>格式
List<ILevelTreeNode> list = (List<ILevelTreeNode>) data;
//List<TreeNode> nodes = new ArrayList<TreeNode>(); //list不为空且大小不为0
if (list != null && list.size()>0){ //加强for循环list
for (ILevelTreeNode levelTreeNode:list){
TreeNode item = new TreeNode();
//获取每个树节点的属性
item.setAttributes(levelTreeNode.getTreeAttributesMap().getAttributes());
//封装每个树节点
treeNodeMap.put(levelTreeNode.getId(),item);
}
//再次遍历所有的树节点
for (ILevelTreeNode levelTreeNode:list){
TreeNode parent = treeNodeMap.get(levelTreeNode.getParentId());
TreeNode treeNode = treeNodeMap.get(levelTreeNode.getId());
if (parent == null){
root.addChild(treeNode);
}else{
parent.addChild(treeNode);
}
}
}
return root.getChild();
}
}
6、解析格式选择类
/**
* 解析格式选择类 (用于接受数据源并选择解析格式)
*/
public class BaseParser {
public static String parserListToLevelTree(List list){
Tree tree = new Tree(list,1);
return tree.toJsonTree();
}
}
7、数据库的Model类treeLevel
要实现接口ILevelTreeNode并实现getTreeAttributesMap的方法,把数据库字段对应的类中的属性都封装起来
public class treeLevel implements ILevelTreeNode {
private int id;
private int parentId;
private String name;
private String content;
@Override
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public int getParentId() {
return parentId;
}
public void setParentId(int parentId) {
this.parentId = parentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public TreeAttributesMap getTreeAttributesMap() {
TreeAttributesMap treeMap = new TreeAttributesMap(this.id,this.name);
treeMap.putAttributes("content",this.content);
treeMap.putAttributes("parentId",this.parentId);
return treeMap;
}
}
8、Dao层(查询数据库表中所有的记录)
@Mapper
public interface MyDao { @Select("SELECT * FROM treelevel")
4 List<treeLevel> getTreeLevelList();
5 }
9、Server层就省略了,最后只要在Controller层提供Server层调用Dao层访问数据库,将返回的结果List传入静态方法BaseParser.parserListToLevelTree()中即可。
最后,总结一下
a.先为自己的树型节点定义好接口,比如每个节点有获取自己的id、父节点id、属性集合等方法。
b.根据数据库字段创建好对应的类的Model,这里Model类需要实现之前定义好节点的接口,便于后面代码的接入。
c.创建好Parser转换类,将传入List形式的数据转换成自己想要的节点链表形式的数据(对每个节点封装好父节点、子节点们和自身属性集合等)。
d.创建好Tree数据选择解析类,将转换好的节点数据集合解析成自己想要的Json格式的String字符串。
将数据转换成树型层级的Json格式的String的更多相关文章
- 从一个复杂的json格式的String内获取某key的值
如题,如何简单的从一个复杂的String格式内获取某个key的值. 例如:从下面String下取到status的值. {"response":{"info":{ ...
- Python把json格式的string对象转变成dict对象操作、Python3不能使用urllib2、urllib.parse.urlencode(params).encode(encoding='UTF8')
son格式的string对象转变成dict对象操作 content=eval(content)#json字典转化 Python3不能使用urllib2 直接使用urllib.request替换urll ...
- Json格式转换
验证Json格式可以进入 http://json.cn/ json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构1.对象:对象 ...
- json格式转换成Map的应用
jsp 1.引用json.js(将json格式转换成字符串) 2. var name = document.getElementById("name").value; var re ...
- 转!!JavaBean,List,Map转成json格式
public class User { private String username; private String password; public String getUsername() { ...
- JavaBean,List,Map转成json格式
public class User { private String username; private String password; public String getUsername() { ...
- Ajax中的JSON格式与php传输过程的浅析
在Ajax中的JSON格式与php传输过程中有哪些要注意的小地方呢? 先来看一下简单通用的JSON与php传输数据的代码 HTML文件: <input type="button&quo ...
- JSON(五)——同步请求中使用JSON格式字符串进行交互(不太常见的用法)
在同步请求中使用JSON格式进行数据交互的场景并不多,同步请求是浏览器直接与服务器进行数据交互的大多是用jsp的标签jstl和el表达式对请求中的数据进行数据的渲染.我也是在一次开发中要从其它服务器提 ...
- xml和JSON格式相互转换的Java实现
依赖的包: json-lib-2.4-jdk15.jar ezmorph-1.0.6.jar xom-1.2.1.jar commons-lang-2.1.jar commons-io-1.3.2.j ...
随机推荐
- 摩羯座Capricornus
Capricornus 摩羯座的人通常会如何拒绝别人. 摩羯座的人做事脚踏实地,比较固执,忍耐力也是出奇的强大,同时也非常勤奋.他们心中总是背负着很多的责任感,但往往又很没有安全感,不会完全地相信别 ...
- js里面对数据处理的方法
1,charAt()方法可返回指定位置的字符 JavaScript String 对象 例:stringObject.charAt(index) index:表示字符串中某个位置的数字,即字符在字 ...
- composer 自动加载(php-amqplib)
最近要使用RabbitMQ 做消息队列,也是刚接触到.因为用的的TP框架,comoser又下载不下来,所以只能手动下载拓展包,做手动加载,在php-amqplib是我手动下载下来的拓展包,创建一个co ...
- redis安装,windows,linux版本并部署服务
一.使用场景 项目中采用数据库访问量过大或访问过于频繁,将会对数据库带来很大的压力.redis数据库是以非关系数据库的出现,后来redis的迭代版本支持了缓存数据.登录session状 ...
- 接口压力测试--Jmeter
1.Jmeter简介 JMeter就是一个测试工具,相比于LoadRunner等测试工具,此工具免费,且比较好用,但是前提当然是安装Java环境: JMeter可以做 (1)压力测试及性能测试: (2 ...
- PDF 补丁丁 0.6.1.3498 版重大更新:为文本PDF文档自动生成书签!
新的 PDF 补丁丁开放了内部测试了很久的好用功能——自动书签. 这个功能可以在一分钟内快速生成文本型 PDF 文档的书签(说明:本功能分析文档中的文本,生成标题,故对扫描版的 PDF 文档无效). ...
- 关于SQLSERVER数据库连接池
页内导航 1.如何开启连接池? 2. 那连接池是和有什么有关呢? 3.如何使用相同的连接池访问不同的数据库? ‘关于数据库连接池大家都听说过或者用过,但真正的了解有多少呢? 数据连接池如何启用?有哪些 ...
- null 和System.DBNull.Value
row[column]的值为DBNull.Value的话,说明它是从数据库中取到值了,对应了数据库中的空值:但如果row[column]的值为null的话,说明没有从数据库中取到值. DBNull.V ...
- python-之-深浅拷贝一
深浅拷贝 一.数据为不可变类型 (str.int.bool) import copy v1 = "abc" v2 = copy.copy(v1) v3 = copy.deepcop ...
- HashMap 的put方法
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] ta ...