Javaでさまざまな役割の動的メニューを設計する方法

メニューはデータベースで構成され、index.htmlが初めて開かれ、バックグラウンドによって返されるhtmlメニューがajaxリクエストを介して取得されます。

メニューの表示はロールによって制御され、データベース情報が読み取られ、ロールとMenuListのマッピング関係が返されます。後で、現在のユーザーログインのロールに従ってメニューを制御できます。

関与するテクノロジー:

adminlteレンダリング+春-セキュリティリクエストフィルタリング+ springmvcリクエスト+ mybatis

効果画像:

drop table menu;
create table menu(
menu_id number(10),
menu_name varchar2(256),
paerent_id number(10),
is_leaf char,
target_url varchar2(256)
);

drop table role_menu;
create table role_menu(
menu_id number(10),
role_id number(10));
create table ROLE
(
  ID        NUMBER(10),
  ROLE_NAME VARCHAR2(32)
);
delete from menu 1=2;
insert into menu(menu_id,menu_name,paerent_id,is_leaf,target_url)
values(1000,'菜单1',0,0,'#');
insert into menu(menu_id,menu_name,paerent_id,is_leaf,target_url)
values(1001,'子菜单1',1000,1,'/test.html');
insert into menu(menu_id,menu_name,paerent_id,is_leaf,target_url)
values(1002,'子菜单2',1000,1,'#');
insert into menu(menu_id,menu_name,paerent_id,is_leaf,target_url)
values(1003,'菜单1-3',1000,1,'#');
insert into menu(menu_id,menu_name,paerent_id,is_leaf,target_url)
values(1100,'菜单2',0,0,'#');
insert into menu(menu_id,menu_name,paerent_id,is_leaf,target_url)
values(1101,'菜单2-1',1100,1,'#');
delete from role_menu 1=2;
insert into role_menu(menu_id,role_id)
values(1000,0);
insert into role_menu(menu_id,role_id)
values(1001,0);
insert into role_menu(menu_id,role_id)
values(1002,0);
insert into role_menu(menu_id,role_id)
values(1003,0);
insert into role_menu(menu_id,role_id)
values(1100,0);
insert into role_menu(menu_id,role_id)
values(1101,0);
delete from role 1=2;
insert into role(id,role_name)
values(0,'admin');
insert into role(id,role_name)
values(10001,'ROLE_USER');

メニューツリーの永続性(データベース)

RoleMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.demo.dao.IRoleDao">
    <resultMap id="user_role_permission_map" type="com.demo.domain.Role">
        <id column="id" property="id"/>
        <result column="role_name" property="roleName"/>
        <result column="roleDesc" property="roleDesc"/>
    </resultMap>


    <select id="findRolesByUserId" resultMap="user_role_permission_map" parameterType="java.lang.String">
        select * from role where id in (select role_id from users_role where user_id = #{uid})
    </select>
    <!-- 一对多 -->
    <select id="selectRoleMenu" resultMap="roleMenuMap" parameterType="int">
       select * from role a,role_menu b,menu c where a.id = b.role_id and b.menu_id = c.menu_id order by c.menu_id
    </select>
    <resultMap type="com.demo.domain.po.RoleMenu" id="roleMenuMap">
             <id property="id" column="id"/>
      <!--       <association property="menuId" column="menu_id" javaType="com.demo.domain.Menu">
                 <id property="menuId" column="menu_id"/>
                 <result property="name" column="t_name"/>
             </association>-->
             <!-- ofType指定students集合中的对象类型 -->
             <collection property="menuList" ofType="com.demo.domain.Menu">
                 <id property="menuId" column="menu_id"/>
                 <result property="menuId" column="menu_id"/>
                 <result property="menuName" column="menu_name"/>
                 <result property="paerentId" column="paerent_id"/>
                 <result property="isLeaf" column="is_leaf"/>
                 <result property="targetUrl" column="target_url"/>
             </collection>
         </resultMap>

</mapper>

po

public class RoleMenu {
    private Integer id;
    private List<Menu> menuList;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public List<Menu> getMenuList() {
        return menuList;
    }

    public void setMenuList(List<Menu> menuList) {
        this.menuList = menuList;
    }
}

メニュー

package com.demo.domain;

public class Menu {
    private Long menuId;
    private String menuName;
    private Long paerentId;
    private Integer isLeaf;
    private String targetUrl;

    public String getTargetUrl() {
        return targetUrl;
    }

    public void setTargetUrl(String targetUrl) {
        this.targetUrl = targetUrl;
    }

    public Long getMenuId() {
        return menuId;
    }

    public void setMenuId(Long menuId) {
        this.menuId = menuId;
    }

    public String getMenuName() {
        return menuName;
    }

    public void setMenuName(String menuName) {
        this.menuName = menuName;
    }

    public Long getPaerentId() {
        return paerentId;
    }

    public void setPaerentId(Long paerentId) {
        this.paerentId = paerentId;
    }

    public Integer getIsLeaf() {
        return isLeaf;
    }

    public void setIsLeaf(Integer isLeaf) {
        this.isLeaf = isLeaf;
    }

}

スパニングツリー:GenTree.java

package com.demo.common;

import com.demo.domain.Menu;
import com.demo.domain.po.RoleMenu;

import java.util.List;

public class GenTree {
    public String generateTreeHtml(List<RoleMenu> roleMenus) {
        List<Menu> menus = null;
        StringBuilder sb = new StringBuilder();
        for (RoleMenu roleMenu : roleMenus) {
            if (0 == roleMenu.getId()) {
                menus = roleMenu.getMenuList();
            }
        }

        return  tree(menus);
    }

    public String tree(List<Menu> menus) {
        StringBuilder sb = new StringBuilder();
        int leafFlag = 0;
        int cnt = 0;
        for (Menu menu : menus) {
            if (menu.getIsLeaf() == 0) {
                if (cnt == 0) {
                    sb.append("<li class=\"nav-item has-treeview\"> \n");
                } else {
                    sb.append("</ul></li>");
                    sb.append("<li class=\"nav-item has-treeview\"> \n");
                }
                sb.append("<a href=\"#\" class=\"nav-link\"> <i class=\"nav-icon fas fa-tachometer-alt\"></i> <p>");
                sb.append(menu.getMenuName());
                sb.append("<i class=\"right fas fa-angle-left\"></i></p></a> ");
                leafFlag = 0;
            } else {
                if (leafFlag == 0) {
                    sb.append("<ul class=\"nav nav-treeview\">");
                }
                sb.append("<li class=\"nav-item\"> <a href=\""+menu.getTargetUrl()+"\" target=\"menuFrame\" class=\"nav-link\"> <i class=\"far fa-circle nav-icon\"></i> <p>");
                sb.append(menu.getMenuName());
                sb.append("</p> </a></li>\n");
                if (cnt == menus.size() - 1) {
                    sb.append("</ul></li>");
                }
                leafFlag = 1;
            }
            cnt++;
        }
        System.out.println(sb.toString());
        return sb.toString();
    }

}

サービス

    public String queryAllRoleMenu() {
        List<RoleMenu> roleMenus = roleDao.selectRoleMenu();
        return  new GenTree().generateTreeHtml(roleMenus);
    }

コントローラ

@RequestMapping(value = "/getTree", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String refleshTree() {
        return myService.queryAllRoleMenu();
    }

html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>AdminLTE 3 | Legacy User Menu</title>
    <!-- Tell the browser to be responsive to screen width -->
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Font Awesome -->
    <link rel="stylesheet" href="plugins/fontawesome-free/css/all.min.css">
    <!-- Ionicons -->
    <link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
    <!-- overlayScrollbars -->
    <link rel="stylesheet" href="dist/css/adminlte.min.css">
    <!-- Google Font: Source Sans Pro -->
   <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
</head>
<body class="hold-transition sidebar-mini">
<!-- Site wrapper -->
<div class="wrapper">
    <!-- Navbar -->
    <nav class="main-header navbar navbar-expand navbar-white navbar-light">
        <!-- Left navbar links -->
        <ul class="navbar-nav">
            <li class="nav-item">
                <a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a>
            </li>
            <li class="nav-item d-none d-sm-inline-block">
                <a href="/test.html" class="nav-link">Home</a>
            </li>
            <li class="nav-item d-none d-sm-inline-block">
                <a href="#" class="nav-link">菜单1121</a>
            </li>
        </ul>

        <!-- SEARCH FORM -->
        <form class="form-inline ml-3">
            <div class="input-group input-group-sm">
                <input class="form-control form-control-navbar" type="search" placeholder="Search" aria-label="Search">
                <div class="input-group-append">
                    <button class="btn btn-navbar" type="submit">
                        <i class="fas fa-search"></i>
                    </button>
                </div>
            </div>
        </form>

        <!-- Right navbar links -->
        <ul class="navbar-nav ml-auto">
            <!-- Messages Dropdown Menu -->
            <li class="nav-item dropdown user-menu">
                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">
                    <img src="dist/img/user2-160x160.jpg" class="user-image img-circle elevation-2" alt="User Image">
                    <span class="d-none d-md-inline">张三</span>
                </a>
                <ul class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
                    <!-- User image -->
                    <li class="user-header bg-primary">
                        <img src="dist/img/user2-160x160.jpg" class="img-circle elevation-2" alt="User Image">

                        <p>
                            张三 - 工程师
                            <small>Member since Nov. 2012</small>
                        </p>
                    </li>
                    <!-- Menu Body -->
                    <li class="user-body">
                        <div class="row">
                            <div class="col-4 text-center">
                                <a href="#">Followers</a>
                            </div>
                            <div class="col-4 text-center">
                                <a href="#">Sales</a>
                            </div>
                            <div class="col-4 text-center">
                                <a href="#">Friends</a>
                            </div>
                        </div>
                        <!-- /.row -->
                    </li>
                    <!-- Menu Footer-->
                    <li class="user-footer">
                        <a href="#" class="btn btn-default btn-flat">Profile</a>
                        <a href="/logout" class="btn btn-default btn-flat float-right">退出</a>
                    </li>
                </ul>
            </li>
            <li class="nav-item">
                <a class="nav-link" data-widget="control-sidebar" data-slide="true" href="#" role="button">
                    <i class="fas fa-th-large"></i>
                </a>
            </li>
        </ul>
    </nav>
    <!-- /.navbar -->

    <!-- Main Sidebar Container -->
    <aside class="main-sidebar sidebar-dark-primary elevation-4">
        <!-- Brand Logo -->
        <a href="/fail.html" target="menuFrame" class="brand-link">
            <img src="dist/img/AdminLTELogo.png"
                 alt="AdminLTE Logo"
                 class="brand-image img-circle elevation-3"
                 style="opacity: .8">
            <span class="brand-text font-weight-light">后台管理系统</span>
        </a>

        <!-- Sidebar -->
        <div class="sidebar">
            <!-- Sidebar Menu -->
            <nav class="mt-2">
                <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu"
                    data-accordion="false"  id="myHtml" name="myHtml">
                    <!-- Add icons to the links using the .nav-icon class
                         with font-awesome or any other icon font library -->
                </ul>
            </nav>
            <!-- /.sidebar-menu -->
        </div>
        <!-- /.sidebar -->
    </aside>

    <!-- Content Wrapper. Contains page content -->
    <div class="content-wrapper">
        <!-- Content Header (Page header) -->
        <section class="content-header">
            <div class="container-fluid">
                <div class="row mb-2">
                    <div class="col-sm-6">
                        <h1>Legacy User Menu</h1>
                    </div>
                    <div class="col-sm-6">
                        <ol class="breadcrumb float-sm-right">
                            <li class="breadcrumb-item"><a href="#">Home</a></li>
                            <li class="breadcrumb-item active">Legacy User Menu</li>
                        </ol>
                    </div>
                </div>
            </div><!-- /.container-fluid -->
        </section>

        <!-- Main content -->
        <section class="content">

            <!-- Default box -->
           <!-- <div class="card">
                <div class="card-header">
                    <h3 class="card-title">Title</h3>

                    <div class="card-tools">
                        <button type="button" class="btn btn-tool" data-card-widget="collapse" data-toggle="tooltip"
                                title="Collapse">
                            <i class="fas fa-minus"></i></button>
                        <button type="button" class="btn btn-tool" data-card-widget="remove" data-toggle="tooltip"
                                title="Remove">
                            <i class="fas fa-times"></i></button>
                    </div>
                </div>
                <div class="card-body">
                    Start creating your amazing application!d
                </div>
                &lt;!&ndash; /.card-body &ndash;&gt;
                <div class="card-footer">
                    Footer
                </div>
                &lt;!&ndash; /.card-footer&ndash;&gt;
            </div>-->
            <!-- /.card -->
            <iframe id="menuFrame" name="menuFrame" src="fail.html" style="overflow:visible;" scrolling="yes" frameborder="no" height="100%" width="100%"></iframe>
        </section>
        <!-- /.content -->
    </div>
    <!-- /.content-wrapper -->

    <footer class="main-footer">
        <div class="float-right d-none d-sm-block">
            <b>Version</b> 3.0.4
        </div>
        <strong>Copyright &copy; 2014-2019 <a href="http://adminlte.io">AdminLTE.io</a>.</strong> All rights
        reserved.
    </footer>

    <!-- Control Sidebar -->
    <aside class="control-sidebar control-sidebar-dark">
        <!-- Control sidebar content goes here -->
    </aside>
    <!-- /.control-sidebar -->
</div>
<!-- ./wrapper -->

<!-- jQuery -->
<script src="plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- AdminLTE App -->
<script src="dist/js/adminlte.min.js"></script>
<!-- AdminLTE for demo purposes -->
<script src="dist/js/demo.js"></script>
<script src="plugins/vue.js" type="text/javascript"></script>
<script type="text/javascript">
    $(function () {
        $.ajax({
            type: "post",
            url: "/rest/getTree",
            async: true,
            success: function (data) {
                console.log(data);
                $("#myHtml").append(data);
            }
        });
    });
</script>
</body>
</html>

 

おすすめ

転載: blog.csdn.net/x18094/article/details/105922138