最近在做一个网站类型项目,主要负责后台,ui框架选型为jquery easy ui,项目架构为spring mvc + spring jdbc,简单易用好上手!搭建好框架后开始了第一个任务,设计并实现一套简单的权限管理功能。
一套最基本的权限管理包括用户、角色、资源。
实现效果:
数据库设计,设计如下:
用户:user
角色:role
用户-角色:user_role
资源:resource(包括上级菜单、子菜单、按钮等资源)
角色-资源:role_resource
标准的权限管理系统设计为以上5张表。
注:用户、用户-角色我就不做说明了,这两个是很简单的两块,用户的crud,以及为用户分配角色(多对多的关系)稍微琢磨一下就清楚了,下面都是针对为角色分配权限的实现
后台实现
展示层采用ztree树
role.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ include file="/views/back/include/taglib.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
< html xmlns = "http://www.w3.org/1999/xhtml" >
< head >
< meta name = "decorator" content = "back" />
< script type = "text/javaScript" >
//打开菜单窗口
function openMenuDialog(){
var selected = $("#list").datagrid('getSelected');
if (selected != null) {
$("#id").val(selected.id);
queryMenus(selected.id);
$("#menuWindow").window("open");
} else {
$.messager.alert('提示', "未选择数据!");
}
}
//角色-菜单信息入库
function ajaxSubmit(rid,idstr){
$.post("${ctx}/roleMenu/save.jhtml",{"roleId":rid,"ids":idstr},function(obj){
$.messager.alert('提示',obj.msg);
$("#menuWindow").window('close');
},'json');
}
</ script >
<!-- ztree -->
< script type = "text/javascript" >
var tree = "";
var setting = {
check : {
chkboxType:{"Y":"ps","N":"s"},//勾选checkbox对于父子节点的关联关系,取消勾选时不关联父
chkStyle:"checkbox",
enable : true //是否复选框
},
//数据
data : {
simpleData : {
enable : true
}
}
};
//查询菜单信息
function queryMenus(roleId){
$.post('${ctx}/role/treedata.jhtml', {'roleId':roleId}, function(zNodes) {
for (var i = 0; i < zNodes.length ; i++) {
if (zNodes[i].isParent) {
} else {
//zNodes[i] .icon = "${ctxStatic}/images/532.ico" ;//设置图标
}
}
tree = $.fn.zTree.init($("#tree"), setting, zNodes);
tree.expandAll(true);//全部展开
//var nodes = treeObj .getNodes();
}, 'json');
}
//获取选中节点
function onCheck(){
var rid = $("#id").val();
var treeObj=$.fn.zTree.getZTreeObj("tree");
var nodes = treeObj .getCheckedNodes(true);
var ids = new Array();
for(var i = 0 ;i<nodes.length;i++){
//获取选中节点的值
ids.push(nodes[i].id);
// v+=nodes[i].id + ",";
//alert(nodes[i].id);
}
ajaxSubmit(rid,ids);
}
</script>
</ head >
< body >
<!-- 数据表格 -->
< table id = "list" url = '${ctx}/role/list/page.jhtml' method = 'post'
class = "easyui-datagrid" style = "width:100%;" fitcolumns = "true"
toolbar = '#tb' pagination = 'true' rownumbers = 'true' singleSelect = 'true' >
< thead >
< tr >
< th field = 'name' sortable = 'true' width = '100' >角色名称</ th >
< th field = 'description' width = '200' align = 'right' >描述</ th >
< th field = 'createTimeFormat' width = '150' align = 'center' >创建时间</ th >
</ tr >
</ thead >
</ table >
<!-- 编辑栏 -->
< div id = "tb" style = "padding:5px 5px;" >
< div >
< p2p:permission module = "role" code = "add" >< a href = "#" class = "easyui-linkbutton" iconCls = "icon-add" onclick = "openCreateDialog();" >新增</ a ></ p2p:permission >
< p2p:permission module = "role" code = "edit" >< a href = "#" class = "easyui-linkbutton" iconCls = "icon-edit" onclick = "openUpdateDialog();" >编辑</ a ></ p2p:permission >
< p2p:permission module = "role" code = "delete" >< a href = "#" class = "easyui-linkbutton" iconCls = "icon-remove" onclick = "del();" >删除</ a ></ p2p:permission >
< p2p:permission module = "role" code = "authority" >< a href = "#" class = "easyui-linkbutton" iconCls = "icon-edit" onclick = "openMenuDialog();" >设置权限</ a ></ p2p:permission >
</ div >
<!-- 搜索项 -->
< div style = "margin-top:5px;padding-left:5px" >
用户名: < input id = "query_name" class = "easyui-textbox" type = "text" style = "width:110px" />
创建日期: < input id = "query_startDate" class = "easyui-datebox" style = "width:110px" >
至: < input id = "query_endDate" class = "easyui-datebox" style = "width:110px" >
< a onclick = "reload();" href = "#" class = "easyui-linkbutton" iconCls = "icon-search" >查询</ a >
</ div >
</ div >
<!-- 权限窗口 -->
< div id = "menuWindow" class = "easyui-window" title = "配置权限" data-options = "modal:true,iconCls:'icon-save',footer:'#menuWindowfooter'" style = "width:350px;height:420px;padding:10px" >
< div id = "tree" class = "ztree" style = "padding: 10px 20px;" ></ div >
</ div >
< div id = "menuWindowfooter" style = "padding:5px;text-align:right;" >
< a href = "#" onclick = "onCheck();" class = "easyui-linkbutton" data-options = "iconCls:'icon-save'" >提交</ a >
</ div >
</ body >
</ html >
|
action层
RoleAction.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
@RequestMapping (value = "/treedata.jhtml" )
@ResponseBody
public String treedata(HttpServletRequest request, Model model) {
DynamicParams params = new DynamicParams(request);
List<Map<String, Object>> mapList = Lists.newArrayList();
params.put( "allMenu" , "allMenu" );
List<Menu> list = authManager.findMenuList(params);
List<RoleMenu> roleMenus = authManager.findRoleMenuList(params);
for ( int i = 0 ; i < list.size(); i++) {
Menu e = list.get(i);
Map<String, Object> map = Maps.newHashMap();
map.put( "id" , e.getId());
map.put( "pId" , e.getParentId() != null ? e.getParentId() : 0 );
map.put( "name" , e.getName());
for (RoleMenu roleMenu : roleMenus) {
if (roleMenu.getMenuId() == e.getId()) {
map.put( "checked" , true );
}
}
mapList.add(map);
}
return toJson(mapList);
}
|
service层
AuthManager.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
// 菜单管理
public List<Menu> findMenuList(DynamicParams params) {
List<Menu> menus = new ArrayList<Menu>();
if ( "allMenu" .equals(params.getString( "allMenu" ))) {
menus = menuDao.findList(params);
} else {
// 通过用户查询角色
List<UserRole> userRoles = userRoleDao.findList(params);
// 通过角色查询菜单
List<RoleMenu> roleMenus = new ArrayList<RoleMenu>();
if (userRoles != null && userRoles.size() > 0 ) {
for (UserRole userRole : userRoles) {
params = new DynamicParams();
if (userRole != null ) {
if (userRole.getRoleId().equals(params.getString( "rid" ))) {
break ;
}
params.put( "roleId" , userRole.getRoleId().toString());
List<RoleMenu> rms = roleMenuDao.findList(params);
for (RoleMenu roleMenu : rms) {
roleMenus.add(roleMenu);
}
}
}
}
// 查询菜单信息
for (RoleMenu roleMenu : roleMenus) {
if (roleMenu != null ) {
Menu menu = menuDao.find(roleMenu.getMenuId());
if (menu != null ) {
menus.add(menu);
}
}
}
menus = removeDuplicate(menus);
Collections.sort(menus);
}
return menus;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/**
* 去除菜单中重复项
*
* @param list
* @return
*/
private List<Menu> removeDuplicate(List<Menu> list) {
List<Menu> result = new ArrayList<Menu>();
Set<Long> menuIds = new HashSet<Long>();
for ( int i = 0 ; i < list.size(); i++) {
Menu m = list.get(i);
if (m != null && menuIds.add(m.getId())) {
result.add(m);
}
}
return result;
}
|
1
2
3
4
|
public List<RoleMenu> findRoleMenuList(DynamicParams params) {
List<RoleMenu> roleMenus = roleMenuDao.findList(params);
return roleMenus;
}
|
Dao层
menuDao
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@Override
protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
sql.append( "select s.* from sys_menu s where 1=1 " );
String parentId = params.getString( "parentId" );
if (StringUtils.isNotBlank(parentId)) {
sql.append( " and parent_id = ? " );
args.add(parentId);
}
String sort = params.getString( "sort" );
String order = params.getString( "order" );
if (StringUtils.isNotBlank(sort)) {
sql.append( " order by " ).append(hump2underline(sort));
if (StringUtils.isNotBlank(order)) {
sql.append( " " + order);
} else {
sql.append( " desc " );
}
} else {
sql.append( "order by sort asc,id desc " );
}
}
|
userRoleDao
1
2
3
4
5
6
7
8
9
|
@Override
protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
sql.append( "select s.* from sys_user_role s where 1=1 " );
Long adminId = params.getLong( "adminId" );
if (adminId != null ) {
sql.append( " and s.user_id = ?" );
args.add(adminId);
}
}
|
roleMenuDao
1
2
3
4
5
6
7
8
9
|
@Override
protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
sql.append( "select s.* from " ).append( "sys_role_menu" ).append( " s where 1=1 " );
Long adminId = params.getLong( "roleId" );
if (adminId != null ) {
sql.append( " and s.role_id = ?" );
args.add(adminId);
}
}
|
在WEB-INF目录下建立文件夹tlds 建立自定义标签文件shiros.tld,我们通过自定义标签实现页面按钮的控制。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<span style= "color:#333333;" ><?xml version= "1.0" encoding= "UTF-8" ?>
<taglib xmlns= "http://java.sun.com/xml/ns/j2ee" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation= "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version= "2.0" >
<description>p2p permission taglib</description>
<display-name>permission taglib</display-name>
<tlib-version> 1.0 </tlib-version>
< short -name>p2p_back</ short -name>
<uri>http: //vanfon.p2p.cn/</uri>
<tag>
<description>权限校验标签,有权限就显示标签体的内容,否则不显示</description>
<name>permission</name>
<tag- class >com.vanfon.p2p.back.tag.PermissionTag</tag- class >
<body-content>JSP</body-content>
<attribute>
<description></description>
<name>module</name>
<required> true </required>
<rtexprvalue> false </rtexprvalue>
</attribute>
<attribute>
<description></description>
<name>code</name>
<required> true </required>
<rtexprvalue> false </rtexprvalue>
</attribute>
</tag>
</taglib></span>
|
自定义标签类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
package com.vanfon.p2p.back.tag;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import com.vanfon.p2p.entity.system.Admin;
import com.vanfon.p2p.entity.system.Menu;
import com.vanfon.p2p.manager.system.AuthManager;
import com.vanfon.p2p.utils.DynamicParams;
import com.vanfon.p2p.utils.SpringContextHolder;
/**
* 权限控制标签
*
* @author zhangwx
* @date 2015-2-5
*/
public class PermissionTag extends TagSupport {
/**
*
*/
private static final long serialVersionUID = 4592227792811389132L;
private String module; // 属性名必须与JSP自定义标签的属性名一样
private String code;
public String getModule() {
return module;
}
public void setModule(String module) {
this .module = module;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this .code = code;
}
@Override
public int doStartTag() throws JspException {
boolean result = false ;
HttpServletRequest request = (HttpServletRequest) this .pageContext.getRequest(); // 通过成员变量获取HttpServletRequest对象
Admin admin = (Admin) request.getSession().getAttribute( "admin" ); // 获取登录到系统的用户
if (admin != null ) {
if ( "1" .equals(String.valueOf(admin.getIfsuper()))) { // 超级管理员
result = true ;
} else {
DynamicParams params = new DynamicParams();
params.put( "id" , String.valueOf(admin.getId()));
params.put( "module" , this .module);
params.put( "code" , this .code);
AuthManager authManager = SpringContextHolder.getBean(AuthManager. class );
List<Menu> userRoleAuths = authManager.findUserRoleAuthList(params);
if (userRoleAuths != null && userRoleAuths.size() > 0 ) {
result = true ;
}
}
}
return result ? EVAL_BODY_INCLUDE : SKIP_BODY;
}
}
|
以上就是该权限管理中权限树的大体实现,完成了java web实现用户权限管理的功能,希望对大家的学习有所帮助。