接着 上面的说
给每个权限组 设定不同的权限
这个是 给 鹏哥 所在的 市场操作 权限组 设定权限
...
下面给佳哥 还有我 设定权限
就不截图啦..
就这么个事 现在开始说代码级别的设计
粗力度 用的是过滤器来 过滤 每一个请求 现在用struts2 特有的拦截器 来实现 这个功能
还是分步骤 一步一步来 比较好
第一 创建一个limit 注解
/**
* 自定义注解
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Limit{
String module(); //模块名称
String privilege(); //操作名称
}
注解的作用 就是 为啦 给 给所操作的方法上面加一个表示 等过一会要用 再解释~~
第二 :创建一个自定义拦截器
public class LimitInterceptor extends MethodFilterInterceptor{
public String doIntercept(ActionInvocation invocation) throws Exception {
//获取请求的action对象
Object action=invocation.getAction();
//获取请求的方法的名称
String methodName=invocation.getProxy().getMethod();
System.out.println("methodName "+methodName);
System.err.println("进入到啦拦截器中.....");
//获取action中的方法的封装类(action中的方法没有参数)
Method method=action.getClass().getMethod(methodName, null);
//获取request对象
HttpServletRequest request=ServletActionContext.getRequest();
//检查注解
boolean flag=isCheckLimit(request,method);
if(!flag){
System.out.println("没有权限");
//没有权限
return "popmsg_popedom";
}
System.out.println("有权限");
//有权限,可以调用action中的方法
String returnvalue=invocation.invoke();
return returnvalue;
}
public boolean isCheckLimit(HttpServletRequest request, Method method) {
if(method==null){
return false;
}
//获取当前的登陆用户
SysUser sysUser=SessionUtils.getSysUserFormSession(request);
if(sysUser==null){
return false;
}
if(sysUser.getSysRole()==null){
return false;
}
//获取当前登陆用户的权限组id
String roleId=sysUser.getSysRole().getId();
//处理注解
/*
* @Limit(module="group",privilege="list")
public String list(){
*/
boolean isAnnotationPresent= method.isAnnotationPresent(Limit.class);
//不存在注解
if(!isAnnotationPresent){
return false;
}
//存在注解
Limit limit=method.getAnnotation(Limit.class);
//获取注解上的值
String module=limit.module(); //模块名称
String privilege=limit.privilege(); //操作名称
boolean flag=false;
//查询sys_popedom_privilege表中的所有的数据
ISysPopedomPrivilegeService sysPopedomPrivilegeService=
(ISysPopedomPrivilegeService)ServiceProvinder.getService(ISysPopedomPrivilegeService.SERVICE_NAME);
List<SysPopedomPrivilege> list=sysPopedomPrivilegeService.findAllSysPopedomPrivileges();
if(list!=null&&list.size()>0){
for(int i=0;i<list.size();i++){
SysPopedomPrivilege s=list.get(i);
if(s!=null){
if(roleId.equals(s.getId().getRoleId())&&module.equals(s.getId().getPopedomModule())
&&privilege.equals(s.getId().getPopedomPrivilege())){
flag=true;
break;
}
}
}
}
return flag;
}
}
自定义拦截器也需要配置哦 记得呀! 在struts2的配置文中配置一下
<package name="sys" namespace="/sys" extends="struts-default">
<interceptors>
<interceptor name="limitInterceptor" class="com.crm.interceptor.LimitInterceptor"/>
<interceptor-stack name="limitStack">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="limitInterceptor">
<!-- 配置哪些方法不被拦截器 -->
<param name="excludeMethods">isLogin,top,left</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- struts运行时,执行的拦截器栈 -->
<default-interceptor-ref name="limitStack"/>
<!-- 转到没有权限的页面 -->
<global-results>
<result name="popmsg_popedom">/WEB-INF/page/popmsg_popedom.jsp</result>
</global-results>
.. N个action....
</package>
第三步 在你功能实现的action中得方法上加入注解
例如
@Limit(module="user",privilege="delete")
public String delete(){
//获取删除的id
String [] sids=request.getParameterValues("ids");
//转成整形数组
Integer ids[]=DataType.converterStringArray2IntegerArray(sids);
if(ids!=null&&ids.length>0){
//删除
sysUserService.deleteSysUserByIds(ids);
return "listAction";
}
return null;
}
//
@Limit(module="role",privilege="listPopedom")
public String listPopedom(){
//获取角色id
String roleId=request.getParameter("roleId");
//吧权限组 放到request 中在页面可以读取里面的信息 然后显示
SysRole sysRole=sysRoleService.findSysRoleById(roleId);
request.setAttribute("sysRole",sysRole);
//查询数据库吧系统中所有功能查询处理(实现定义好的)在页面通过复选框来全部显示出来
//因为这个表中存放着权限的模板 title之类的
List<SysPopedom> sysPopedoms=sysPopedomService.findAllSysPopedoms();
request.setAttribute("sysPopedoms", sysPopedoms);
//回显功能 查询 这个表中然后 通过数据 在页面进行选中操作
List<SysPopedomPrivilege> sysPopedomPriviles=sysPopedomPrivilegeService.findSysPopedomPrivilegesByRoleId(roleId);
request.setAttribute("sysPopedomPriviles", sysPopedomPriviles);
return "listPopedom";
}
...N个 都需要加上
要和数据库中得对应啊
哦了 只需上面三步就能搞定
这就搞定了
---------------------------
现在开始解释
当我没请求 一个action中得方法时 都会呗拦截器拦截到(顾名思义 拦截器就是 拦截所有的东西)
他觉得 你的请求 正确 ok 就放行 如果 看你不顺眼 就 不让你过
我们 在每个方法上面 都加入啦这个注解 @Limit(module="role",privilege="listPopedom")
注解中module 是模块的名称 说白了 就是 你要操作的action 中得名称 就是你是什么模块 什么 部门 的 意思 priviege 就是 你具体是做什么 c r u d 之类的
因为我们在数据库中存储好啦 具体的操作
通过我们 给相应的 权限组 设计相应的权限 也就是是说保存到啦 数据库中得 操作权限表中(中间表)poeodom_privilege 表中
我们 可以在拦截器中得 doIntercept 中进行判断
通过 反射机制 我们可以狠容易的拿到 方法上的注解
然后 和数据库中得进行比较 如果 数据库有这个操作的权限 就 现实 你能操作的
比如说 数据库中 (poeodom_privilege表)存储的是 role add
而 你在 SysRoleAction 中add上 写啦 @Limit(module="role",privilege="add")
就代表 你能用这个方法进行添加
如果 你数据库中没有存在 role uplate
就算你 的 SysRoleAction 中得uplate 上写啦 @Limit(module="role",privilege="uplate")
应该好理解把
下面写点代码 狠变态的代码
设这权限界面的代码
<s:form name="ActionForm" method="post" action="sysRoleAction_updatePopedom.do" namespace="/sys">
<s:hidden name="roleId" value="%{#request.sysRole.id}" />
<br/>
<div class="control">
<button type='button' class='button' onMouseOver="this.className='button_over';"
onMouseOut="this.className='button';" onClick="SelectAllBox()"><img src="${pageContext.request.contextPath}/ui/images/button/quanbuxz.png" border='0' align='absmiddle'> 全部选中</button>
<button type='button' class='button' onMouseOver="this.className='button_over';"
onMouseOut="this.className='button';" onClick="UnSelectAllBox()"><img src="${pageContext.request.contextPath}/ui/images/button/quanbubxz.png" border='0' align='absmiddle'> 全部不选中</button>
<button type='button' class='button' onMouseOver="this.className='button_over';"
onMouseOut="this.className='button';" onClick="document.ActionForm.submit();"><img src="${pageContext.request.contextPath}/ui/images/button/baocun.png" border='0' align='absmiddle'> 保存</button>
<button type='button' class='button' onMouseOver="this.className='button_over';"
onMouseOut="this.className='button';" onClick="parent.close();"><img src="${pageContext.request.contextPath}/ui/images/button/guanbi.png" border='0' align='absmiddle'> 关闭</button>
</div>
<table width="100%" border="0" cellpadding="0" cellspacing="0" bgcolor="#6A82A8">
<tr>
<td align="center" height="25"><span style="color:#FFFFFF; font-weight:bold">操作权限组:${sysRole.name}</span></td>
</tr>
</table>
<div class="border" style="padding:3px">
<c:if test="${! empty requestScope.sysPopedoms}">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
<c:forEach items="${requestScope.sysPopedoms}" var="sysPopedomSup">
<c:if test="${sysPopedomSup.id.popedomModule==sysPopedomSup.id.popedomPrivilege}">
<fieldset style='padding:5px;clear:left;'>
<!-- 遍历权限组包含的权限 处理父的复选框回显 -->
<c:forEach items="${requestScope.sysPopedomPriviles}" var="sysPopedomPrivile">
<c:if test="${sysPopedomSup.id.popedomModule==sysPopedomPrivile.id.popedomModule
&&sysPopedomSup.id.popedomPrivilege==sysPopedomPrivile.id.popedomPrivilege}">
<c:set value="checked" var="xx" scope="page"/>
</c:if>
</c:forEach>
<legend><input type='checkbox' class='checkbox' name='popedomModule' ${xx}
value='${sysPopedomSup.id.popedomModule},${sysPopedomSup.id.popedomPrivilege}'
id='${sysPopedomSup.id.popedomModule}_${sysPopedomSup.id.popedomPrivilege}' title="${sysPopedomSup.title}"
onClick='goSelect(this.id)'>${sysPopedomSup.popedomName}
</legend>
<c:remove var="xx" scope="page"/>
<!-- 遍历权限组包含的权限 处理父的复选框回显-->
<c:forEach items="${requestScope.sysPopedoms}" var="sysPopedomSub">
<c:if test="${sysPopedomSup.id.popedomModule==sysPopedomSub.id.popedomModule
&&sysPopedomSub.id.popedomModule!=sysPopedomSub.id.popedomPrivilege}">
<!-- 遍历权限组包含的权限 处理子的复选框回显 -->
<c:forEach items="${requestScope.sysPopedomPriviles}" var="sysPopedomPrivile">
<c:if test="${sysPopedomSub.id.popedomModule==sysPopedomPrivile.id.popedomModule
&&sysPopedomSub.id.popedomPrivilege==sysPopedomPrivile.id.popedomPrivilege}">
<c:set value="checked" var="xxx" scope="page"/>
</c:if>
</c:forEach>
<div><input type='checkbox' class='checkbox' name='popedomModule'
title="${sysPopedomSub.title}" ${xxx}
value='${sysPopedomSub.id.popedomModule},${sysPopedomSub.id.popedomPrivilege}'
id='${sysPopedomSub.id.popedomModule}_${sysPopedomSub.id.popedomPrivilege}'
onClick='goSelect(this.id)'>${sysPopedomSub.popedomName}</div>
<c:remove var="xxx" scope="page"/>
<!-- 遍历权限组包含的权限 处理子的复选框回显 -->
</c:if>
</c:forEach>
</fieldset>
</c:if>
</c:forEach>
</td>
</tr>
</table>
</c:if>
</div>
</s:form>
js的函数
<script language="javascript">
function goSelect(id){
var valueStr=$("#"+id).val();
var array=valueStr.split(",");
if(array[0] != array[1]){
if($("#"+id)[0].checked){
var supid=array[0]+"_"+array[0];
$("#"+ supid).attr("checked","checked");
}else{
var $jihe=$("input[type='checkbox'][value^="+array[0]+"]:not([value$="+array[0]+"])");
var flag=false;
$jihe.each(function(index,domEle){
if(this.checked){
flag=true;
return;
}
});
if(!flag){
var supid=array[0]+"_"+array[0];
$("#"+ supid).attr("checked",null);
}
}
}
if(array[0]==array[1]){
if($("#"+id)[0].checked){
$("input[type='checkbox'][value^="+array[0]+"]").attr("checked","checked");
}else{
$("input[type='checkbox'][value^="+array[0]+"]").attr("checked",null);
}
}
}
function SelectAllBox(){
$("input[type=checkbox][name=popedomModule]").attr("checked","checked");
}
function UnSelectAllBox(){
$("input[type=checkbox][name=popedomModule]").attr("checked",null);
}
</script>
还有处理菜单权限的
<s:form name="ActionForm" method="post" action="sysRoleAction_updateMenu.do" namespace="/sys">
<s:hidden name="roleId" value="%{#request.sysRole.id}"></s:hidden>
<br/>
<div class="control">
<button type='button' class='button' onMouseOver="this.className='button_over';" onMouseOut="this.className='button';"
onClick="SelectAllBox()">
<img src="${pageContext.request.contextPath}/ui/images/button/quanbuxz.png" border='0'
align='absmiddle'> 全部选中</button>
<button type='button' class='button' onMouseOver="this.className='button_over';" onMouseOut="this.className='button';"
onClick="UnSelectAllBox()">
<img src="${pageContext.request.contextPath}/ui/images/button/quanbubxz.png" border='0'
align='absmiddle'> 全部不选中</button>
<button type='button' class='button' onMouseOver="this.className='button_over';" onMouseOut="this.className='button';"
onClick="document.forms[0].submit();">
<img src="${pageContext.request.contextPath}/ui/images/button/baocun.png" border='0'
align='absmiddle'> 保存</button>
<button type='button' class='button' onMouseOver="this.className='button_over';" onMouseOut="this.className='button';"
onClick="parent.close();">
<img src="${pageContext.request.contextPath}/ui/images/button/guanbi.png" border='0'
align='absmiddle'> 关闭</button>
</div>
<table width="100%" border="0" cellpadding="0" cellspacing="0" bgcolor="#6A82A8">
<tr>
<td align="center" height="25"><span style="color:#FFFFFF; font-weight:bold">操作权限组:<s:property value="%{#request.sysRole.name}"/></span></td>
</tr>
</table>
<div class="border" style="padding:3px">
<c:if test="${! empty sysMenus}">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
<c:forEach items="${sysMenus}" var="sysMenu">
<c:if test="${sysMenu.id.menuModule==sysMenu.id.menuPrivilege}">
<fieldset style='padding:5px;clear:left;'>
<!-- 处理父菜单的选中状态 -->
<c:if test="${! empty sysMenuPrivileges}">
<c:forEach items="${sysMenuPrivileges}" var="sysMenuPrivilege">
<c:if test="${sysMenu.id.menuModule==sysMenuPrivilege.id.menuModule
&&sysMenu.id.menuPrivilege==sysMenuPrivilege.id.menuPrivilege}">
<c:set value="checked" var="xx" scope="page"/>
</c:if>
</c:forEach>
</c:if>
<legend><input type='checkbox' class='checkbox' name='menuModule' ${xx}
value='${sysMenu.id.menuModule},${sysMenu.id.menuPrivilege}'
id='${sysMenu.id.menuModule}_${sysMenu.id.menuPrivilege}'
onClick='goSelect(this.id)'>${sysMenu.menuName}
</legend>
<c:remove var="xx" scope="page"/>
<!-- 处理父菜单的选中状态 -->
<c:forEach items="${sysMenus}" var="sysMenuSub">
<c:if test="${sysMenuSub.id.menuModule!=sysMenuSub.id.menuPrivilege
&&sysMenu.id.menuModule==sysMenuSub.id.menuModule}">
<!-- 处理子菜单的选中状态 -->
<c:if test="${! empty sysMenuPrivileges}">
<c:forEach items="${sysMenuPrivileges}" var="sysMenuPrivilegexx">
<c:if test="${sysMenuSub.id.menuModule==sysMenuPrivilegexx.id.menuModule
&&sysMenuSub.id.menuPrivilege==sysMenuPrivilegexx.id.menuPrivilege}">
<c:set value="checked" var="xxx" scope="page"/>
<%
System.out.println("xxxxxxxxxxxxxxxxxxx");
%>
</c:if>
</c:forEach>
</c:if>
<div><input type='checkbox' class='checkbox' name='menuModule' ${xxx}
value='${sysMenuSub.id.menuModule},${sysMenuSub.id.menuPrivilege}'
id='${sysMenuSub.id.menuModule}_${sysMenuSub.id.menuPrivilege}'
id='company_base' onClick='goSelect(this.id)' >${sysMenuSub.menuName}</div>
<c:remove var="xxx" scope="page"/>
<!-- 处理子菜单的选中状态 -->
</c:if>
</c:forEach>
</fieldset>
</c:if>
</c:forEach>
</td>
</tr>
</table>
</c:if>
</div>
</s:form>
说完啦 操作板的 我有点累啦
开始讲菜单版的
第一要明白 菜单 办 就是你要现实的 菜单
如果你是admin 你拥有所有的菜单
但是 你如果只是一个销售部门 员工 就登陆系统就没有必要现实那么多菜单 就算有 那么多菜单你也不能用 你已经别操作板的权限给控制啦
所有最好的解决方案就是 谁 登陆 就现实 谁所需要的菜单
菜单的实现 也需要 那几个表 原理都一样 需要中介表之类的
就一次性写出来啊啊
#############################################################################################################
#菜单表
CREATE TABLE sys_menu
(
menuModule VARCHAR(30), #模块名称
menuPrivilege VARCHAR(30), #操作名称
sort INTEGER(11), #排序字段
menuName VARCHAR(200), #中文名称
title VARCHAR(200), #标题
url VARCHAR(200), #链接路径
target VARCHAR(20), #目标框架
icon VARCHAR(20), #使用的图标
remark TEXT, #说明
PRIMARY KEY(menuModule,menuPrivilege)
)
#############################################################################################################
#菜单权限表
CREATE TABLE sys_menu_privilege
(
roleId VARCHAR(36), #权限组编号
menuModule VARCHAR(30), #模块名称
menuPrivilege VARCHAR(30), #操作名称
PRIMARY KEY(roleId,menuModule,menuPrivilege)
)
他也是 需要 关联的
第一种 粗粒度的 用啦一个绝招 过滤器
第二种 操作板的 用啦一个更绝的 拦截器
现在到操作板啦 的 怎么办 来个超级绝的 自定义标签
public class CheckMemuTag implements SimpleTag {
private PageContext pageContext;
//标签体
private JspFragment jspFragment;
//<itcast:checkMemu module="${sysMenu.id.menuModule}" privilege="${sysMenu.id.menuPrivilege}">
private String module;
private String privilege;
public void doTag() throws JspException, IOException {
//获取request对象
HttpServletRequest request=(HttpServletRequest)pageContext.getRequest();
//获取当前登陆用户
SysUser sysUser=SessionUtils.getSysUserFormSession(request);
if(sysUser==null){
return;
}
if(sysUser.getSysRole()==null){
return;
}
//获取当前登陆用户对应的权限组id
String roleId=sysUser.getSysRole().getId();
//获取菜单操作权限的业务层 sys_menu_privilege
ISysMenuPrivilegeService sysMenuPrivilegeService=
(ISysMenuPrivilegeService)ServiceProvinder.getService(ISysMenuPrivilegeService.SERVICE_NAME);
//获取菜单操作权限表中的所有数据 sys_menu_privilege,返回值List集合
List<SysMenuPrivilege> list=sysMenuPrivilegeService.findAllSysMenuPrivileges();
//遍历集合
if(list!=null&&list.size()>0){
for(int i=0;i<list.size();i++){
SysMenuPrivilege s=list.get(i);
if(StringUtils.isNotBlank(roleId)&&StringUtils.isNotBlank(module)&&StringUtils.isNotBlank(privilege)){
//比对权限id+模块名称+操作名称
if(roleId.equals(s.getId().getRoleId())&&module.equals(s.getId().getMenuModule())
&&privilege.equals(s.getId().getMenuPrivilege())){
//如果在集合中存在,输出标签体
this.jspFragment.invoke(null);
break;
}
}
}
}
}
public JspTag getParent() {
return null;
}
public void setJspBody(JspFragment jspFragment) {
this.jspFragment=jspFragment;
}
public void setJspContext(JspContext pc) {
this.pageContext=(PageContext) pc;
}
public void setParent(JspTag arg0) {
}
public void setModule(String module) {
this.module = module;
}
public void setPrivilege(String privilege) {
this.privilege = privilege;
}
}
这样在 main中left的 菜单显示中
<c:if test="${! empty applicationScope.sysMenus}">
<div id="main">
<div id="sidetree">
<div class="treeheader">操作菜单</div>
<div id="sidetreecontrol"><a href="?#">Collapse All</a> | <a href="?#">Expand All</a></div>
<ul id="tree">
<c:forEach items="${applicationScope.sysMenus}" var="sysMenu">
<c:if test="${sysMenu.id.menuModule==sysMenu.id.menuPrivilege}">
<itcast:checkMemu module="${sysMenu.id.menuModule}" privilege="${sysMenu.id.menuPrivilege}">
<li><img src="${pageContext.request.contextPath}/ui/images${sysMenu.icon}" width="17" height="17">
<strong>${sysMenu.menuName}</strong>
<c:forEach items="${applicationScope.sysMenus}" var="sysMenuSub">
<c:if test="${sysMenuSub.id.menuModule!=sysMenuSub.id.menuPrivilege
&&sysMenu.id.menuModule==sysMenuSub.id.menuModule}">
<itcast:checkMemu module="${sysMenuSub.id.menuModule}" privilege="${sysMenuSub.id.menuPrivilege}">
<ul>
<li><img src="${pageContext.request.contextPath}/ui/images${sysMenuSub.icon}" width="17" height="17">
<a href="${pageContext.request.contextPath}${sysMenuSub.url}" target="${sysMenuSub.target}">${sysMenuSub.menuName}</a></li>
</ul>
</itcast:checkMemu>
</c:if>
</c:forEach>
</li>
</itcast:checkMemu>
</c:if>
</c:forEach>
</ul>
</div>
</div>
</c:if>
就可以这样定义啦
就能很好的实现菜单的控制
---------------------------------
可能自定义标签有些同学不懂
不要紧
第一 创建一个类 要实现 SimpleTag 这个接口 实现他的方法 (当让还可以实现很多tag接口)
第二 在doTag 中处理业务
第三 整个tld文件 让jsp认识你的标签
<?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>myitcast 1.o core library</description>
<display-name>itcast core</display-name>
<tlib-version>1.0</tlib-version>
<short-name>itcast</short-name>
<uri>http://www.itcast.cn/jsp/jstl/core</uri>
<tag>
<name>checkMemu</name>
<tag-class>com.crm.tag.CheckMemuTag</tag-class>
<!-- 标签体不能为空 -->
<body-content>scriptless</body-content>
<attribute>
<name>module</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>privilege</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
第三 就是在 页面中使用啦 当然也要引用你的tld文件啊
<%@ taglib uri="/WEB-INF/tld/myitcast.tld" prefix="itcast"%>\
我有点累啦 先睡啦