java权限设计大纲

1.1 权限管理介绍

什么权限

l 哪些功能可以被哪些用户使用

l 用户可以使用哪些功能

图解权限:


用户管理    userAction_manager.action

查看日志    logAction_query.action

添加商品    goodsAction_save.action

权限解决方案:

如何知道用户有哪些权限: 把用户拥有权限的URL存储起来,根据URL判断就知道它是否有权限

用户的权限是根据项目的需求动态变化的,所以权限的本身也需要维护,权限要动态给用户分配、动态的回收

权限解决方案A:

权限模型B:

重点回顾:

权限就是控制功能的使用(功能对应着URL)。

对功能的控制就是对URL的访问控制。

在我们的程序中,一个功能对应一个或两个URL

例如列表或删除功能,只对应一个URL.

例如添加或修改功能,对应两个URL..add, ..addUI

权限的实现步骤:

1. 初始化权限数据:项目做好后,把需要控制的权限URL存储到权限表中

2. 超级管理员:此管理员. 默认拥有所有权限, 以后就通过此管理员给用户授权

分配权限

1.2 给角色分配权限,项目中创建若干个角色, 给每个角色授权

1.3 给用户分配角色, 用户的权限就是角色权限的集合

使用权限

l 登录、注销、主页面。

l 左侧的菜单是根据权限显示的。(没有权限的菜单不可见)

右侧页面中的链接是根据权限显示的。(没有权限的删除和更新不可见)

权限分类:有些权限默认所有用户都拥有. 例如注销、登录…….

 

创建角色与权限的表结构

(他们是多对多的关系,创建完毕之后有3张表)

/*------权限表用来存储权限名称和权限URL-------*/

drop table if exists role_privilege;

drop table if exists privilege;

drop table if exists role;

 

create table privilege

(

    pid int not null auto_increment,

    /* 权限名称 */ 

    pname varchar(200),

    /* 权限URL地址*/

    purl varchar(200),

    /* 权限菜单所属的父菜单ID */

    parentId int,

    /* 此权限功能是否要显示在左边*/

    isleft boolean,

    primary key(pid)

);

 

create table role

(

rid int not null auto_increment,

/* 角色名称 */

rname varchar(200),

/* 角色介绍 */

detail varchar(200),

primary key(rid)

);

 

create table role_privilege

(

rid int,

pid int,

primary key(rid,pid)

);

 

alter table privilegeadd constraint foreign key (parentId)

references privilege (pid);

 

alter table role_privilegeadd constraint foreign key (rid)

references role (rid);

 

alter table role_privilegeadd constraint foreign key (pid)

references privilege (pid);

 

SELECT * FROM privilege;

SELECT * FROM role;

SELECT * FROM role_privilege;

 

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('商品管理','goodsAction_all',null,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('类别管理','categoryAction_all',null,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('订单管理','forderAction_all',null,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('会员管理','usersAction_all',null,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('角色管理','roleAction_all',null,true);

 

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('商品添加','goodsAction_saveUI',1,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('商品添加实现','goodsAction_save',1,false);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('商品查询','goodsAction_queryUI',1,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('商品查询实现','goodsAction_query',1,false);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('商品更新','goodsAction_updateUI',1,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('商品更新实现','goodsAction_update',1,false);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('商品删除','goodsAction_delete',1,true);

 

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('类别添加','categoryAction_saveUI',2,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('类别添加实现','categoryAction_save',2,false);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('类别查询','categoryAction_queryUI',2,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('类别查询实现','categoryAction_query',2,false);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('类别更新','categoryAction_updateUI',2,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('类别更新实现','categoryAction_update',2,false);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('类别删除','categoryAction_delete',2,true);

 

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('订单查询','forderAction_queryUI',3,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('订单查询实现','forderAction_query',3,false);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('订单修改','forderAction_updateUI',3,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('订单修改实现','forderAction_update',3,false);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('订单删除','forderAction_delete',3,true);

 

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('会员查询','usersAction_queryUI',4,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('会员查询实现','usersAction_query',4,false);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('会员修改','usersAction_updateUI',4,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('会员修改实现','usersAction_update',4,false);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('会员删除','usersAction_delete',4,true);

 

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('角色添加','roleAction_saveUI',5,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('角色添加实现','roleAction_save',5,false);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('角色查询','roleAction_queryUI',5,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('角色查询实现','roleAction_query',5,false);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('角色修改','roleAction_updateUI',5,true);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('角色修改实现','roleAction_update',5,false);

INSERT INTO privilege (pname,purl,parentId,isleft)VALUES ('角色删除','roleAction_delete',5,true);

 

SELECT * FROM privilege;

SELECT * FROM role;

SELECT * FROM role_privilege;

INSERT INTO role (rname,detail)VALUES ('客服','拥有基本的权限');

INSERT INTO role_privilege (rid,pid)values (1,1);

INSERT INTO role_privilege (rid,pid)values (1,23);

INSERT INTO role_privilege (rid,pid)values (1,13);

INSERT INTO role_privilege (rid,pid)values (1,11);

 

 

查询某一个角色的权限信息SQL语句:

/*查询角色的权限信息*/

SELECT r.*,p.* FROM role r INNER JOIN role_privilege rpON r.rid=rp.rid

INNER JOIN privilege pON rp.pid=p.pid;

权限的实体类为:

public class Privilegeimplements java.io.Serializable {

 

private static final long serialVersionUID = -3096838392822714616L;

 

private Integer pid;

private String pname;

private String purl;

private Boolean isleft;

/* 如果此菜单拥有父菜单,则父菜单存储到此属性中*/

private Privilege privilege;

/* 如果此菜单有子菜单,则子菜单可以存储到此属性中*/

private Set<Privilege>childrens = new HashSet<Privilege>(0);

public Integer getPid() {

return pid;

}

public void setPid(Integer pid) {

this.pid = pid;

}

public String getPname() {

return pname;

}

public void setPname(String pname) {

this.pname = pname;

}

public String getPurl() {

return purl;

}

public void setPurl(String purl) {

this.purl = purl;

}

public Boolean getIsleft() {

return isleft;

}

public void setIsleft(Boolean isleft) {

this.isleft = isleft;

}

public Privilege getPrivilege() {

return privilege;

}

public void setPrivilege(Privilege privilege) {

this.privilege = privilege;

}

public Set<Privilege> getChildrens() {

return childrens;

}

public void setChildrens(Set<Privilege> childrens) {

this.childrens = childrens;

}

}

角色的实体为:

public class Roleimplements java.io.Serializable {

 

private static final long serialVersionUID = -7851427548653281059L;

 

private Integer rid;

private String rname;

private String detail;

private Set<Privilege>privileges = new HashSet<Privilege>(0);

 

public Set<Privilege> getPrivileges() {

return privileges;

}

public void setPrivileges(Set<Privilege> privileges) {

this.privileges = privileges;

}

public Role() {

}

// Property accessors

public Integer getRid() {

return this.rid;

}

public void setRid(Integer rid) {

this.rid = rid;

}

public String getRname() {

return this.rname;

}

 

public void setRname(String rname) {

this.rname = rname;

}

public String getDetail() {

return this.detail;

}

public void setDetail(String detail) {

this.detail = detail;

}

}

角色的映射文件为:

<hibernate-mapping>

    <class name="cn.itcast.shop.pojo.Role" table="role">

        <id name="rid" type="java.lang.Integer">

            <column name="rid" />

            <generator class="native" />

        </id>

        

        <property name="rname" type="java.lang.String">

            <column name="rname" length="100" />

        </property>

        

        <property name="detail" type="java.lang.String">

            <column name="detail" length="200" />

        </property>

        

        <set name="privileges" table="role_privilege" catalog="shop">

            <key>

                <!-- 外键 rid -->

                <column name="rid" not-null="true" />

            </key>

            <!-- rid 匹配的 pid 通过pid 去privilege加载具体的privilege实体  -->

            <many-to-many entity-name="cn.itcast.shop.pojo.Privilege">

                <column name="pid" not-null="true" />

            </many-to-many>

        </set>

    </class>

</hibernate-mapping>

权限的映射文件为:

<hibernate-mapping>

    <class name="cn.itcast.shop.pojo.Privilege" table="privilege">

        <id name="pid" type="java.lang.Integer">

            <column name="pid" />

            <generator class="native"></generator>

        </id>

        <property name="pname" type="java.lang.String">

            <column name="pname" length="100" />

        </property>

        <property name="purl" type="java.lang.String">

            <column name="purl" length="200" />

        </property>

        <property name="isleft" type="java.lang.Boolean">

            <column name="isleft" />

        </property>

        

        <many-to-one name="privilege" class="cn.itcast.shop.pojo.Privilege" fetch="select">

            <column name="parentId" />

        </many-to-one>

        

        <set name="childrens" inverse="true">

            <key>

                <column name="parentId" />

            </key>

            <one-to-many class="cn.itcast.shop.pojo.Privilege" />

        </set>

    </class>

</hibernate-mapping>

完成角色的 CRUD操作

由于权限是要先赋值给角色的,所以先完成角色的CRUD操作

 

给角色授权, 如果此角色已经有权限则回显

 

Action核心代码如下:

public String updateUI() {

// 获取当前角色信息,其中包括,权限信息,为了方便回显

Role role = roleService.get(model.getRid());

session.put("role", role);

// 获取当前用户的权限pid用于回显

String pids = privilegeService.getPrivilegePid(role.getPrivileges());

request.put("pids", pids);

// 查询系统所有权限,因为此功能常见,而且权限不会改变,所以可以存储到app

request.put("privileges",privilegeService.query());

return "updateUI";

}

 

public String update() {

Set<Privilege> privileges = new HashSet<Privilege>();

for (int pid :pids) {

Privilege privilege = new Privilege();

privilege.setPid(pid);

privileges.add(privilege);

}

Role role = (Role) session.get("role");

role.setPrivileges(privileges);

roleService.update(role);

return "queryUI";

}

采用contains标签来回显示:

<function>

    <description>

      Tests if an input string contains the specified substring.

    </description>

    <name>contains</name>

    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>

    <function-signature>boolean contains(java.lang.String, java.lang.String)</function-signature>

    <example>

      <c:if test="${fn:contains(name, searchString)}">

    </example>

  </function>

 回显示页面代码如下:

<body> 

       您正在更新的角色为:[${role.rname}]:

    <form action="${pageContext.request.contextPath}/roleAction_update.action" method="post">

             所属权限为:<br/>

       <c:forEach items="${privileges}"var="privilege">

          ${privilege.pid}

          <input type="checkbox" value="${privilege.pid}" name="pids" ${fn:contains(requestScope.pids,privilege.pid)?"checked":""}/>${privilege.pname}/${privilege.purl}<br/>

       </c:forEach>

  <input type="submit" value="更新" />

 </form>

  </body>

注意:采用此有错误.只支持字符串 如果选择了12  那么回显的时候1 2 都会被选中.如果JSTL支持字符数组则不会出现此问题 但是JSTL没有字符数组函数,没有可以自定义

自定义JSTL函数回显

自定义函数库:
 1、定义类和方法(方法必须是public static 
 2、编写自定义tld文件,并且将此文件放到WEB-INFWEB-INF任意子目录下
 3、在jsp中采用taglib指令引入自定义函数库
 4、采用 前缀+冒号(:+函数名 调用即可 

自定义类为:

public class MyJSTLFunction {

public static boolean  contains(String[] strArr, String searchString) {

for (String temp : strArr) {

if (temp.equals(searchString)) {

return true;

}

}

return false;

}

}

MyJSTL.tld文件为:

<?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>JSTL 1.1 functions library</description>

  <display-name>JSTL functions</display-name>

  <tlib-version>1.1</tlib-version>

  <short-name>my</short-name>

  <uri>http://cn.itcast.shop.jstl/myjstl</uri>

 

  <function>

    <name>contains</name>

    <function-class>cn.itcast.shop.jstl.MyJSTLFunction</function-class>

    <function-signature>boolean contains(java.lang.String[], java.lang.String)</function-signature>

  </function>

</taglib>

页面调用如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>

<%@ taglib uri="http://cn.itcast.shop.jstl/myjstl" prefix="my" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

    <title>My JSP 'updateUI.jsp' starting page</title>

 

<meta http-equiv="pragma" content="no-cache">

<meta http-equiv="cache-control" content="no-cache">

<meta http-equiv="expires" content="0">    

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

<meta http-equiv="description" content="This is my page">

<!--

<link rel="stylesheet" type="text/css"href="styles.css">

-->

 

  </head>

  

  <body> 

       您正在更新的角色为:[${role.rname}]:

    <form action="${pageContext.request.contextPath}/roleAction_update.action" method="post">

             所属权限为:<br/>

       <c:forEach items="${privileges}"var="privilege">

          ${privilege.pid}

          <input type="checkbox" value="${privilege.pid}" name="pids" ${my:contains(requestScope.pids,privilege.pid)?"checked":""}/>${privilege.pname}/${privilege.purl}<br/>

       </c:forEach>

  <input type="submit" value="更新" />

 </form>

  </body>

</html>

 

完成基于树状的权限查询

@SuppressWarnings("unchecked")

public List<Privilege> queryPrivilegeTree() {

return hibernateTemplate.find("FROM Privilege p WHERE p.privilege IS NULL");

}

添加树形菜单的功能:

前面已经完成了对权限的授权操作, 但是界面显示的奇丑无比, 如何制作好看的显示外观呢.最典型的做法就是,采用树形菜单显示层次结构,在讲解树型菜单插件的时候我们先回顾一下采用ul li的方式如何来显示菜单操作

<script type="text/javascript" src="jquery-1.7.min.js"></script>

  <script type="text/javascript">

$(function(){

$("span").click(function(){

$(this).next().toggle();

});

});

  </script>

 

 <body>

     <ul>

    <li><span>系统管理</span>

<ul>

<li><span>用户管理</span>

<ul>

   <li>用户添加</li>

   <li>用户查询</li>

</ul>

</li>

<li>订单管理</li>

<li>类别管理</li>

</ul>

</li>

 <ul>

 </body>

页面显示代码如下:

您正在更新的角色为:[${role.rname}]:

<form

action="${pageContext.request.contextPath}/roleAction_update.action"

method="post">

所属权限为:

<br />

<ul id="root" class="filetree">

<c:forEach items="${privileges}"var="privilege">

<li>

<input id="chk_${privilege.pid}" type="checkbox" value="${privilege.pid}" name="pids" 

${my:contains(requestScope.pids,privilege.pid)?"checked":""}/>

<label for="chk_${privilege.pid}">${privilege.pname}</label>

<ul>

<c:forEach items="${privilege.childrens}"var="children">

<li>

<input id="chk_${children.pid}" type="checkbox" value="${children.pid}" name="pids" 

${my:contains(requestScope.pids,children.pid)?"checked":""}/>

<label for="chk_${children.pid}">${children.pname}</label>

</li>

</c:forEach>

</ul>

</li>

</c:forEach>

</ul>

<input type="submit" value="更新" />

</form>

 

讲解树状结构的Jquery插件

 

Jquery完成父子关系权限按钮

$("[type=checkbox]").click(function(){

   // 选中取消的时候同时选中取消下级权限    $(this).siblings("ul").find("input").attr("checked",this.checked);

   // 当选中某一个权限的时候,要选中上级的所有权限,取消的时候,则不取消

   if(this.checked){    $(this).parents("li").children("input").attr("checked",true);

}

});

 

由于没办法上传配图若有感兴趣的 可以去这下载 有完整的配图   http://download.csdn.net/detail/my_name_nb/9734589
发布了72 篇原创文章 · 获赞 108 · 访问量 29万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览