在有些系统中,可能会用到按钮级的权限管理。
这里使用jsp自定义标签来实现。
0、基础配置。建表
###角色对应的操作按钮
1.1.1角色对应的按钮关联表,角色下有哪些按钮是可以访问的
CREATE TABLE `system_role_operation` (
`role_id` int(11) DEFAULT NULL COMMENT '角色id',
`operation_code` varchar(50) DEFAULT NULL COMMENT '操作按钮,menuid_type.如20_view'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
###菜单对应的按钮
1.1.2菜单下有哪些按钮
alter table system_menu add buttons varchar(255) DEFAULT NULL COMMENT 'view,add,update,delete,import,export,audit,icd,item操作按钮以逗号分隔,audit审核,icd关联icd,item关联主题';
1、添加自定义标签
1.1在WEB-INF/tags下新建role.tld
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>ck</short-name> <!-- 判断用户是否用户该按钮权限 --> <tag> <name>hasPermission</name> <tag-class>com.hys.auth.util.RoleButton</tag-class> <body-content>JSP</body-content> <attribute> <name>buttonId</name> <required>true</required> <rtexprvalue>true</rtexprvalue> <description>buttonId</description> </attribute> </tag> </taglib>
1.2建标签处理类RoleButton
package com.hys.auth.util; import java.util.Set; import javax.servlet.jsp.tagext.TagSupport; /** * 自定义按钮权限标签 * 传入按钮标识,判断登录用户是否拥有该按钮权限 * 有权限则显示对应按钮,否则隐藏 * @author lifei * */ public class RoleButton extends TagSupport { /** * */ private static final long serialVersionUID = 2403021954970892155L; private String buttonId; public int doStartTag() { boolean result =false; //用户登录时,取出所属的按钮id,存放在session中 Set<String> operationCodes = (Set<String>)pageContext.getSession().getAttribute(com.hys.auth.constants.Constants.operationCodes); if(null!=operationCodes&&operationCodes.size()>0){ if(null!=buttonId&&!"".equals(buttonId)&&operationCodes.contains(buttonId)){//用户的权限是否包含功能权限 result = true; }} return result? TagSupport.EVAL_BODY_INCLUDE : SKIP_BODY;//真:返回EVAL_BODY_INCLUDE(执行标签);假:返回SKIP_BODY(跳过标签不执行) } public String getButtonId() { return buttonId; } public void setButtonId(String buttonId) { this.buttonId = buttonId; } }
2控制访问
2.1)在登录Cotroller中取出用户所有的操作按钮并放入session中。这里我就简单只写了下sql.
Cotroller中
request.getSession().setAttribute(com.hys.auth.constants.Constants.operationCodes, operationCodeSet);//存放用户所有操作按钮 request.getSession().setAttribute(com.hys.auth.constants.Constants.MENU_LIST_USER, userAllMenuList);//存放用户所有菜单
sql中
public List<String> getOperationCode(Long userId) { Object[] obj=new Object[1]; obj[0]=userId; String sql="select distinct operation_code from system_role_operation ro " + "left join system_role r on ro.role_id=r.ROLE_ID " + "left join system_account_role ra on r.ROLE_ID=ra.ROLE_ID " + "left join system_account a on ra.ACCOUNT_ID=a.ACCOUNT_ID where USER_ID=?"; return getJdbcTemplate().queryForList(sql,obj,String.class); }
2.2)写Filter,取出menuId存放在request中,方便页面中定位按钮id.按钮id组成(菜单id_type 如(menuId_view),20_view是menuId为20的查看标签。)
2.2.1)定义拦截范围
<!-- buttonPermissionFilter --> <filter> <filter-name>buttonPermissionFilter</filter-name> <filter-class>com.hys.auth.filter.ButtonPermissionFilter</filter-class> </filter>c <filter-mapping> <filter-name>buttonPermissionFilter</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping>2.2.2)定义拦截器
package com.hys.auth.filter; import java.io.IOException; import java.util.List; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; import com.hys.auth.constants.Constants; import com.hys.exam.model.system.SystemMenu; /** *本过滤器主要获取用户点击的菜单,如果是menu菜单,则把menu带入到jsp中。 *在使用按钮级别权限时使用。按钮id为:menuid_view,20_view代表id为20的菜单下的view标签是可以显示的 * */ public class ButtonPermissionFilter implements Filter { private static final Logger logger=Logger.getLogger(ButtonPermissionFilter.class); @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req=(HttpServletRequest)request; String url=req.getRequestURI(); String queryurl=req.getQueryString(); if(null!=queryurl){ url+="?"+queryurl; } List<SystemMenu> userAllMenuList=(List<SystemMenu>)req.getSession().getAttribute(com.hys.auth.constants.Constants.MENU_LIST_USER); if(userAllMenuList!=null){ for(SystemMenu menu:userAllMenuList){ if(url.contains(menu.getUrl())){ request.setAttribute(Constants.MENU_ID, menu.getId()); logger.info("menuId:"+menu.getId()+"--name:"+menu.getName()+"--url:"+url+"--menuUrl:"+menu.getUrl()); break; } } } chain.doFilter(request, response); } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } }3、页面中使用。
3.1)在公共页面中引入标签
<%@ taglib uri="/WEB-INF/tags/role.tld" prefix="weeho"%>
3.2)在需要控制的按钮地方添加以下标签包围。##view,add,update,delete,import,export,audit
<weeho:hasPermission buttonId="${menuId}_add">
</weeho:hasPermission>
######附上授权菜单添加checkbox全选操作部分代码。
jsp中checkbox:
<tr> <td class="menuCheck">${peixunTwomenu.name}<input type="checkbox" class = "systemMenu1" id = "systemMenu_${peixunTwomenu.id}" value = "${peixunTwomenu.id}" <c:if test="${peixunTwomenu.state==2}">disabled</c:if> /></td> <td class="optionCheck"> <input type="checkbox" class = "systemOperation" id = "systemOperation_${peixunTwomenu.id}_view" value = "${peixunTwomenu.id}_view" <c:if test="${peixunTwomenu.state==2}">disabled</c:if> />查看 <input type="checkbox" class = "systemOperation" id = "systemOperation_${peixunTwomenu.id}_add" value = "${peixunTwomenu.id}_add" <c:if test="${peixunTwomenu.state==2}">disabled</c:if> />新增 <input type="checkbox" class = "systemOperation" id = "systemOperation_${peixunTwomenu.id}_update" value = "${peixunTwomenu.id}_update" <c:if test="${peixunTwomenu.state==2}">disabled</c:if> />修改 <input type="checkbox" class = "systemOperation" id = "systemOperation_${peixunTwomenu.id}_delete" value = "${peixunTwomenu.id}_delete" <c:if test="${peixunTwomenu.state==2}">disabled</c:if> />删除 </td> </tr>
js控制全选:
$(function(){ //复选框 $(".menuCheck input:checkbox").click(function(){ $(this).closest("tr").find(".optionCheck input:checkbox").prop("checked",$(this).prop("checked")); }); $(".optionCheck input:checkbox").click(function(){ var l =$(this).parent().find("input:checked").length; if($(this).prop("checked")){ $(this).closest("tr").find(".menuCheck input:checkbox").prop("checked",true); } else{ if(l==0){ $(this).closest("tr").find(".menuCheck input:checkbox").prop("checked",false); } } }); });
//如果是动态生成的checkbox。则使用以下代码。
//按钮复选框选择事件 $("body").on("click","input.checkAll:checkbox",function(){ $(this).closest("p").find("span input:checkbox").prop("checked",$(this).prop("checked")); }); $("body").on("click","input.systemOperation:checkbox",function(){ var l =$(this).parent().find("input:checked").length; if($(this).prop("checked")){ $(this).closest("p").find("input.checkAll:checkbox").prop("checked",true); } else{ if(l==0){ $(this).closest("p").find("input.checkAll:checkbox").prop("checked",false); } } });
获取所选checkbox js代码:
//操作权限 var oprationRole = ""; $(".systemOperation").each(function(key,val){ if($(this).prop("checked")) { oprationRole += $(this).val() + ","; } });