在有些系统中,可能会用到按钮级的权限管理。
这里使用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>
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() + ",";
}
});