栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

利用反射构建一棵菜单生成树

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

利用反射构建一棵菜单生成树

利用java的动态调用类和类属性机制, 编写一个工具类来自动为我们创建一个菜单树, 从而使得我们不用每次遇到树结构都要重复的写一些逻辑, 十分不友好. 

public class TreeBuilder {
    private static final String SET_METHOD_PREFIX = "set";
    private static final String GET_METHOD_PREFIX = "get";

    private static final String DEFAULT_ID_NAME = "id";
    private static final String DEFAULT_PARENT_ID_NAME = "parentId";
    private static final String DEFAULT_CHILDREN_NAME = "children";

    
    public static List builder(String rootId, List dataList) throws Exception {
        List tree = new ArrayList<>();
        for (Object data : dataList) {
            String parentId = data.getClass().getMethod(generateGetMethodName(DEFAULT_PARENT_ID_NAME)).invoke(data).toString();

            if (rootId.equals(parentId)) {
                // 是根节点的话, 递归查找以该节点id作为parentId的孩子
                List children = builder(data.getClass().getMethod(generateGetMethodName(DEFAULT_ID_NAME)).invoke(data).toString(), dataList);
                // 设置孩子
                data.getClass().getMethod(generateSetMethodName(DEFAULT_CHILDREN_NAME), List.class).invoke(data, children);
                // 保存当前节点
                tree.add(data);
            }
        }

        return tree;
    }

    
    public static List builder(String rootId, List dataList,String IDFiledName, String parentIdFiledName, String childrenFiledName) throws Exception {
        TreeBuilder treeBuilder = new TreeBuilder<>();
        return treeBuilder.getTree(rootId, dataList, IDFiledName, parentIdFiledName, childrenFiledName);
    }

    
    public List getTree(String rootId, List dataList) throws Exception {
        return builder(rootId, dataList);
    }

    
    public List getTree(String rootId, List dataList, String IDFiledName, String parentIdFiledName, String childrenFiledName) throws Exception {
        List tree = new ArrayList<>();
        for (T data : dataList) {
            String parentId = data.getClass().getMethod(generateGetMethodName(parentIdFiledName)).invoke(data).toString();

            if (rootId.equals(parentId)) {
                // 是根节点的话, 查找以该节点id作为parentId的孩子
                List children = getTree(data.getClass().getMethod(generateGetMethodName(IDFiledName)).invoke(data).toString(), dataList, IDFiledName, parentIdFiledName, childrenFiledName);
                // 设置孩子
                data.getClass().getMethod(generateSetMethodName(childrenFiledName), List.class).invoke(data, children);
                // 保存当前节点
                tree.add(data);
            }
        }

        return tree;
    }

    private static String generateGetMethodName(String filedName){
        return GET_METHOD_PREFIX +filedName.substring(0, 1).toUpperCase() + filedName.substring(1);
    }

    private static String generateSetMethodName(String filedName){
        return SET_METHOD_PREFIX +filedName.substring(0, 1).toUpperCase() + filedName.substring(1);
    }

}

测试: 

class Test{
    public static void main(String[] args) throws Exception {
        // 创建一个实体类
        @Data
        @AllArgsConstructor
        class Node {
            private String id;
            private String data;
            private String parentId;
            private List children;

            public Node(String id, String data, String parentId) {
                this.id = id;
                this.data = data;
                this.parentId = parentId;
            }
        }
        // 模拟一份数据库Node表
        List nodeList = new ArrayList<>();
        nodeList.add(new Node("1", "用户管理", "0"));
        nodeList.add(new Node("2", "角色管理", "0"));
        nodeList.add(new Node("3", "菜单管理", "0"));
        nodeList.add(new Node("4", "工单管理", "0"));
        nodeList.add(new Node("5", "登录管理", "0"));
        nodeList.add(new Node("6", "日志管理", "0"));

        nodeList.add(new Node("7", "用户创建", "1"));
        nodeList.add(new Node("8", "用户角色配置", "1"));
        nodeList.add(new Node("9", "用户禁用", "1"));

        nodeList.add(new Node("10", "角色创建", "2"));
        nodeList.add(new Node("11", "角色删除", "2"));
        nodeList.add(new Node("12", "角色禁用", "2"));

        nodeList.add(new Node("13", "菜单删除", "3"));
        nodeList.add(new Node("14", "菜单编辑", "3"));
        nodeList.add(new Node("15", "菜单禁用", "3"));

        nodeList.add(new Node("16", "创建工单", "4"));
        nodeList.add(new Node("17", "修改工单", "4"));

        nodeList.add(new Node("18", "登录配置", "5"));
        nodeList.add(new Node("19", "登录校验", "5"));

        nodeList.add(new Node("20", "系统日志", "6"));
        nodeList.add(new Node("21", "登录日志", "6"));

        nodeList.add(new Node("22", "普通创建", "7"));
        nodeList.add(new Node("23", "特殊创建", "7"));

        nodeList.add(new Node("24", "配置A", "8"));
        nodeList.add(new Node("25", "配置B", "8"));

        nodeList.add(new Node("26", "常规日志", "20"));
        nodeList.add(new Node("27", "异常日志", "20"));

        // ==== 静态方式调用 ====
        List tree = TreeBuilder.builder("0", nodeList);
        // 声明字段名称, 如果自己的实体类与默认的字段名称不一样, 从参数中声明一下
        List tree0 = TreeBuilder.builder("0", nodeList, "id", "parentId", "children");

        // ==== 创建对象方式调用 ====
        TreeBuilder builder = new TreeBuilder<>();
        List tree1 = builder.getTree("0", nodeList);
        // 声明字段名称, 如果自己的实体类与默认的字段名称不一样, 从参数中声明一下
        List tree2 = builder.getTree("0", nodeList, "id", "parentId", "children");


        return;
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1028067.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号