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