上一小节实现了登录的实现,本小节实现登录后根据用户名查询当前用户的角色所关联的所有权限,然后进行菜单的显示。登录成功后,如下图所示,管理设置是一级菜单,管理员列表,角色管理,权限管理是二级菜单。

先来看一下,AdminUser类,Role类,Permission类

AdminUser类

package com.supin51.domain;

import org.apache.ibatis.type.Alias;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List; /**
* @Author:ShaoJiang
* @description:
* @Date: created in 上午10:05 2019/1/21
* @Modified By:
*/
@Alias("adminUser")
public class AdminUser implements Serializable { private Integer id;
@NotBlank(message = "用户名不能为空")
@Length(min = ,max = ,message = "用户名格式必须在4-12位字符之间")
private String LoginName;
@NotBlank(message = "密码不能为空")
@Size(min = ,max = ,message = "密码必须在6-12位任意字符之间")
private String password;
private Integer state; //用户角色集合,多对多关系,一个用户=多个角色,该属性显示用户的角色名称
private String userRoles; public AdminUser() {super();} public AdminUser(Integer id, String loginName, String password, Integer state) {
this.id = id;
LoginName = loginName;
this.password = password;
this.state = state;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getLoginName() {
return LoginName;
} public void setLoginName(String loginName) {
LoginName = loginName;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public Integer getState() {
return state;
} public void setState(Integer state) {
this.state = state;
} public String getUserRoles() {
return userRoles;
} public void setUserRoles(String userRoles) {
this.userRoles = userRoles;
}
}

Role类

package com.supin51.domain;

import org.apache.ibatis.type.Alias;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank; import java.io.Serializable; /**
* @Author:ShaoJiang
* @description:
* @Date: created in 下午2:08 2019/1/24
* @Modified By:
*/
@Alias("role")
public class Role implements Serializable { private Integer id;
@NotBlank(message = "角色名不能为空")
@Length(max = ,message = "角色名字符数过长")
private String roleName;
private String roleRemark; public Role() {
} public Role(Integer id, String roleName, String roleRemark) {
this.id = id;
this.roleName = roleName;
this.roleRemark = roleRemark;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getRoleName() {
return roleName;
} public void setRoleName(String roleName) {
this.roleName = roleName;
} public String getRoleRemark() {
return roleRemark;
} public void setRoleRemark(String roleRemark) {
this.roleRemark = roleRemark;
} }

Permission类:

package com.supin51.domain;

import org.apache.ibatis.type.Alias;

import java.io.Serializable;
import java.util.List; /**
* @Author:ShaoJiang
* @description:
* @Date: created in 上午10:47 2019/1/22
* @Modified By:
*/
@Alias("permission")
public class Permission implements Serializable { private Integer id;//权限编号
private Integer parentId;//父节点编号
private String name;//权限名称
private String code;//权限代码
private String url;//权限URL
private String icon;//权限图标样式
private String category;//权限类别
private String remark;//权限备注 //子权限集合
List<Permission> childPermissions; public Permission() {
} public Permission(Integer id, Integer parentId, String name,
String code, String url, String icon,
String category, String remark) {
this.id = id;
this.parentId = parentId;
this.name = name;
this.code = code;
this.url = url;
this.icon = icon;
this.category = category;
this.remark = remark;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public Integer getParentId() {
return parentId;
} public void setParentId(Integer parentId) {
this.parentId = parentId;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getCode() {
return code;
} public void setCode(String code) {
this.code = code;
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url;
} public String getIcon() {
return icon;
} public void setIcon(String icon) {
this.icon = icon;
} public String getCategory() {
return category;
} public void setCategory(String category) {
this.category = category;
} public String getRemark() {
return remark;
} public void setRemark(String remark) {
this.remark = remark;
} public List<Permission> getChildPermissions() {
return childPermissions;
} public void setChildPermissions(List<Permission> childPermissions) {
this.childPermissions = childPermissions;
} @Override
public String toString() {
return "Permission{" +
"id=" + id +
", parentId=" + parentId +
", name='" + name + '\'' +
", code='" + code + '\'' +
", url='" + url + '\'' +
", icon='" + icon + '\'' +
", category='" + category + '\'' +
", remark='" + remark + '\'' +
", childPermissions=" + childPermissions +
'}';
}
}

数据库t_permission表的结构

t_role表

t_admin表:password储存的全是加密过的密码

t_amdin_role表:用户和角色的关系表(中间表)

t_role_permission表:角色和权限的关系表(中间表)

可以看到,用户admin有2个角色:管理员和aaa,管理员拥有所有权限,aaa也拥有了所有权限

登录成功后跳转到主页后

AdminController中的代码

/**
* 加载主页
* @return
*/
@RequestMapping("/main")
public String main(HttpSession session,Model model) { if(session.getAttribute("adminUser")!=null){ logger.info("adminUser:"+session.getAttribute("adminUser").toString()); AdminUser adminUser = (AdminUser)session.getAttribute("adminUser"); //查找登录用户角色下的所有权限
List<Permission> allPermissionsList
= adminUserService.findAdminUserRolePermissionList(adminUser.getLoginName().toString());
       
      
       //如果没有权限,直接返回主页
if(allPermissionsList.size()<=)
{
return "main";
} //遍历所有节点,先查找出根节点集合
List<Permission> permissionList = new ArrayList<Permission>();
for(Permission p:allPermissionsList){
//parentId为0的代表根节点
if(p.getParentId().toString().equals("")
||p.getParentId()==){
permissionList.add(p);
}
} //外层循环根节点集合
for(Permission p:permissionList){
//声明一个集合用于装载子节点
List<Permission> childPermissions = new ArrayList<Permission>();
//内层遍历所有权限列表
for(Permission p2:allPermissionsList){
//如果节点的parentId等于根节点父节点的ID
if(p.getId().equals(p2.getParentId())){
//添加节点到子节点集合
childPermissions.add(p2);
} }
//设置根节点下的子节点集合
p.setChildPermissions(childPermissions);
} logger.info(Arrays.asList(permissionList).toString());
       //加载到requestScope内,在页面进行获取
model.addAttribute("permissionList",permissionList); } return "main";
}

当用户拥有两个角色,角色中拥有相同的权限时,怎么获取和显示呢?

这里主要讲解一下,获取用户所有角色下的所有权限的持久层方法

AdminUserMapper.xml ----对应AdminUserDao接口类

<!--查找登录用户下所有角色权限信息-->
<select id="findAdminUserRolePermissionList"
parameterType="string" resultType="com.supin51.domain.Permission">
SELECT DISTINCT tp.*
FROM t_admin ta
LEFT JOIN t_admin_role tar
ON tar.adminId = ta.id
LEFT JOIN t_role tr
ON tar.roleId = tr.id
LEFT JOIN t_role_permission trp
ON trp.roleId = tr.id
LEFT JOIN t_permission tp
ON tp.id = trp.permissionId
WHERE ta.loginName = #{loginName}
AND tp.parentId IS NOT NULL
</select>

这个是多表连接查询,其中使用了关键字:DISTINCT(去重),因为一个用户可以有多个角色,一个角色可以有多个权限,当用户同时拥有2个角色或以上时,而两个角色中都拥有相同的权限时,必须要使用这个关键字DISTINCT(去重),否则相同的权限也会一并查询出来显示。

main.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: shaojiang
Date: //
Time: 下午7:
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="renderer" content="webkit|ie-comp|ie-stand">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link rel="Bookmark" href="/favicon.ico" >
<link rel="Shortcut Icon" href="/favicon.ico" />
<!--[if lt IE ]>
<script type="text/javascript" src="/statics/lib/html5shiv.js"></script>
<script type="text/javascript" src="/statics/lib/respond.min.js"></script>
<![endif]-->
<link rel="stylesheet" type="text/css" href="/statics/h-ui/css/H-ui.min.css" />
<link rel="stylesheet" type="text/css" href="/statics/h-ui.admin/css/H-ui.admin.css" />
<link rel="stylesheet" type="text/css" href="/statics/lib/Hui-iconfont/1.0.8/iconfont.css" />
<link rel="stylesheet" type="text/css" href="/statics/h-ui.admin/skin/default/skin.css" id="skin" />
<link rel="stylesheet" type="text/css" href="/statics/h-ui.admin/css/style.css" />
<!--[if IE ]>
<script type="text/javascript" src="/statics/lib/DD_belatedPNG_0.0.8a-min.js" ></script>
<script>DD_belatedPNG.fix('*');</script>
<![endif]-->
<title>H-ui.admin v3.</title>
</head>
<body>
<header class="navbar-wrapper">
<div class="navbar navbar-fixed-top">
<div class="container-fluid cl"> <a class="logo navbar-logo f-l mr-10 hidden-xs" href="/aboutHui.shtml">H-ui.admin</a> <a class="logo navbar-logo-m f-l mr-10 visible-xs" href="/aboutHui.shtml">H-ui</a>
<span class="logo navbar-slogan f-l mr-10 hidden-xs">v3.</span>
<a aria-hidden="false" class="nav-toggle Hui-iconfont visible-xs" href="javascript:;"></a>
<nav id="Hui-userbar" class="nav navbar-nav navbar-userbar hidden-xs">
<ul class="cl">
<li></li>
<li class="dropDown dropDown_hover">
<a href="#" class="dropDown_A">当前用户:${sessionScope.adminUser.loginName}<i class="Hui-iconfont"></i></a>
<ul class="dropDown-menu menu radius box-shadow">
<li><a href="javascript:;" onclick="modifyPwd()" >修改密码</a></li>
<li><a href="javascript:;" onclick="logout()" >退出</a></li>
</ul>
</li>
<li id="Hui-msg"> <a href="#" title="消息"><span class="badge badge-danger"></span><i class="Hui-iconfont" style="font-size:18px"></i></a> </li>
<li id="Hui-skin" class="dropDown right dropDown_hover"> <a href="javascript:;" class="dropDown_A" title="换肤"><i class="Hui-iconfont" style="font-size:18px"></i></a>
<ul class="dropDown-menu menu radius box-shadow">
<li><a href="javascript:;" data-val="default" title="默认(黑色)">默认(黑色)</a></li>
<li><a href="javascript:;" data-val="blue" title="蓝色">蓝色</a></li>
<li><a href="javascript:;" data-val="green" title="绿色">绿色</a></li>
<li><a href="javascript:;" data-val="red" title="红色">红色</a></li>
<li><a href="javascript:;" data-val="yellow" title="黄色">黄色</a></li>
<li><a href="javascript:;" data-val="orange" title="橙色">橙色</a></li>
</ul>
</li>
</ul>
</nav>
</div>
</div>
</header>
<aside class="Hui-aside">
<div class="menu_dropdown bk_2">
<%--这里控制权限菜单的显示--%>
<c:forEach var="item" items="${permissionList}" begin="">
<dl>
<dt><i class="${item.icon}"></i> ${item.name}<i class="Hui-iconfont menu_dropdown-arrow"></i></dt>
<dd>
<ul>
<c:forEach var="item_subitem" items="${item.childPermissions}">
<li><a data-href="${item_subitem.url}" data-title="${item_subitem.name}" href="javascript:void(0)">${item_subitem.name}</a></li>
</c:forEach>
</ul>
</dd>
</dl>
</c:forEach>
</div>
</aside>
<div class="dislpayArrow hidden-xs"><a class="pngfix" href="javascript:void(0);" onClick="displaynavbar(this)"></a></div>
<section class="Hui-article-box">
<div id="Hui-tabNav" class="Hui-tabNav hidden-xs">
<div class="Hui-tabNav-wp">
<ul id="min_title_list" class="acrossTab cl">
<li class="active">
<span title="我的桌面" data-href="welcome.html">我的桌面</span>
<em></em></li>
</ul>
</div>
<div class="Hui-tabNav-more btn-group"><a id="js-tabNav-prev" class="btn radius btn-default size-S" href="javascript:;"><i class="Hui-iconfont"></i></a><a id="js-tabNav-next" class="btn radius btn-default size-S" href="javascript:;"><i class="Hui-iconfont"></i></a></div>
</div>
<div id="iframe_box" class="Hui-article">
<div class="show_iframe">
<div style="display:none" class="loading"></div>
<iframe scrolling="yes" frameborder="" src="/admin/welcome"></iframe>
</div>
</div>
</section> <div class="contextMenu" id="Huiadminmenu">
<ul>
<li id="closethis">关闭当前 </li>
<li id="closeall">关闭全部 </li>
</ul>
</div>
<!--_footer 作为公共模版分离出去-->
<script type="text/javascript" src="/statics/lib/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="/statics/lib/layer/2.4/layer.js"></script>
<script type="text/javascript" src="/statics/h-ui/js/H-ui.min.js"></script>
<script type="text/javascript" src="/statics/h-ui.admin/js/H-ui.admin.js"></script>
<!--/_footer 作为公共模版分离出去--> <!--请在下方写此页面业务相关的脚本-->
<script type="text/javascript" src="/statics/lib/jquery.contextmenu/jquery.contextmenu.r2.js"></script>
<script type="text/javascript">
$(function(){
/*$("#min_title_list li").contextMenu('Huiadminmenu', {
bindings: {
'closethis': function(t) {
console.log(t);
if(t.find("i")){
t.find("i").trigger("click");
}
},
'closeall': function(t) {
alert('Trigger was '+t.id+'\nAction was Email');
},
}
});*/
});
/*修改密码*/
function modifyPwd(){
parent.layer.open({
title:'修改登录密码',
maxmin: true,
type: ,
shadeClose: false, //点击遮罩关闭
shade: 0.5,//阴影
content: '/admin/update-login-password.action',
area: ['500px', '300px']
});
} /*退出系统*/
function logout() {
layer.open({
title: '注销登录?',
content: '确定要退出该系统?'
,btn: ['确定', '取消']
,yes: function(index, layero){
//按钮【按钮一】的回调
layer.close(index);
window.location.href = "/admin/logout";
},btn2: function(index, layero){
//按钮【按钮二】的回调
},btn3: function(index, layero){
//按钮【按钮三】的回调
}
,cancel: function(){
//右上角关闭回调
}
});
} </script>
</body>
</html>

logout方法

 /**
* 退出系统
* @return
*/
@RequestMapping("/logout")
public String logout(HttpServletRequest request, SessionStatus sessionState )
{
Enumeration<String> em = request.getSession().getAttributeNames();
while (em.hasMoreElements())
{
request.getSession().removeAttribute(em.nextElement().toString());
}
request.getSession().removeAttribute("adminUser");
//注销登录,销毁session
request.getSession().invalidate();
//sessionStatus中的setComplete方法可以将session中的内容全部清空
sessionState.setComplete(); //重定向到到登录页面action
return "redirect:/admin/login";
}

换一个账户:tom登录,可以看到tom什么权限菜单也没有,因为tom属于未分组角色,所以登录后也看不到任何的菜单,只有默认的修改密码一个功能可用。

至此,权限菜单的动态显示完成,本小节结束。下一小节将讲解点击菜单进行权限的拦截验证放行跳转,以及控制页面的权限按钮(三级菜单)显示。

JavaEE权限管理系统的搭建(五)--------RBAC权限管理中的权限菜单的显示的更多相关文章

  1. Asp.Net Core 项目实战之权限管理系统(7) 组织机构、角色、用户权限

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  2. JavaEE权限管理系统的搭建(四)--------使用拦截器实现登录认证和apache shiro密码加密

    RBAC 基于角色的权限访问控制(Role-Based Access Control)在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限.这就极大地简化了权限的管理.在一个 ...

  3. JavaEE权限管理系统的搭建(一)--------项目中用到的知识点概括

    转战Java有一段时间了,.net 已不再开发的新的工程,基本上在维护,最近大半年时间在学习Java,今天抽空将学习的到的知识,应用到了一个权限管理系统的小项目中,特此记录一下.代码如有不对之处,希望 ...

  4. JavaEE权限管理系统的搭建(八)--------角色的增删改

    如下图所示,添加角色的同时,要给角色分配权限菜单,关于权限数的显示,我实现了两种方式,普通方式和Ztree方式, 普通方式展示树: 主要代码部分: /** * 进入角色添加页面 * @param mo ...

  5. JavaEE权限管理系统的搭建(六)--------使用拦截器实现菜单URL的跳转权限验证和页面的三级菜单权限按钮显示

    本小结讲解,点击菜单进行页面跳转,看下图,点击管理员列表后会被认证拦截器首先拦截,验证用户是否登录,如果登录就放行,紧接着会被权限验证拦截器再次拦截,拦截的时候,会根据URL地址上找到对应的方法,然后 ...

  6. ABP module-zero +AdminLTE+Bootstrap Table+jQuery权限管理系统第十三节--RBAC模式及ABP权限管理(附送福利)

    ABP+AdminLTE+Bootstrap Table权限管理系统一期 Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate- ...

  7. ABP module-zero +AdminLTE+Bootstrap Table+jQuery权限管理系统第十五节--缓存小结与ABP框架项目中 Redis Cache的实现

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 缓存 为什么要用缓存 为什么要用缓存呢,说缓存之前先说使用缓存的优点. 减少寄宿服务器的往返调用(round-tr ...

  8. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十四):权限控制(Shiro 注解)

    在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 当前,我们基于导航菜单的显示和操作按钮的禁用状态,实现了页面可见性和 ...

  9. JavaEE权限管理系统的搭建(三)--------springmvc和mabatis整合环境搭建

    本节介绍如何环境的搭建和配置: 首先要在父工程引入jar包依赖: <!-- 通过属性定义指定jar的版本 --> <properties> <spring.version ...

随机推荐

  1. 突破Http协议

    突破Http协议 我到不先说什么Http什么的,对于HTTP的彻底理解是http是应用层的一个程序,就像我们写的诸多客户端和服务器模型,我们可能为了可靠,为了方便数据的解析,我们在数据包中其实就是结构 ...

  2. 机器学习——XGBoost

    基础概念 XGBoost(eXtreme Gradient Boosting)是GradientBoosting算法的一个优化的版本,针对传统GBDT算法做了很多细节改进,包括损失函数.正则化.切分点 ...

  3. C++ 编译器

    C++编译器 当我们定义了一个类的时候, C++编译器在默认的情况下会为我们添加默认的构造方法, 拷贝构造方法, 析构函数和=运算符 在第一次创建对象的语句中如: MyString myString ...

  4. Observer(观察者)设计模式[转]

    Observer设计模式中主要包括如下两类对象: Subject:监视对象,它往往包含着其他对象所感兴趣的内容.在本范例中,热水器就是一个监视对象,它包含的其他对象所感兴趣的内容,就是tempratu ...

  5. 01.c#中的访问修饰符

    public  公开的 private 私有的,只能在当前类的内部访问 protected  受保护的,只能在当前内的内部以及该类的子类可以访问. internal    可以在同一个程序(项目)集中 ...

  6. 2017 年 9 月 27 日 js(文本框内容添加到select)

    写法 <!DOCTYPE html><html>    <head>        <meta charset="UTF-8">   ...

  7. jquery autocomplete jqueryui报错

    使用jquery autocomplete 但是却报错jquery ui 0 TypeError: t[0] is undefined 本地部署是没有问题的,但是放到正式上面就会出错. 同时mvc的m ...

  8. kafka自定义序列化器

    <kafka权威指南> Customer.java public class Customer { private int customId; private String custome ...

  9. 关于消息推送的补充,主要介绍服务端的实现,包含object c 版本 c 版本 java 版本 php 版本 (转)

    要实现消息推送功能,我们可以采用第三方(腾讯:信鸽:百度:云推送:极光推送:友盟):当然,因为各种原因,我们不能使用第三方的推送服务,那我们就需要自己编写服务端.在网上寻觅了很久,找到一篇很不错的讲解 ...

  10. Django的模型层

    一.ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人 ...