关于权限模块的设计

权限模块
一级菜单:
<div id="navMenu">
	<ul>
		<c:forEach items="${firstMenuList }" var="firstMenu" varStatus="status">
			<li <c:if test="${firstMenu.popedomID == firstMenuID }">class="selected" </c:if>><a οnclick="reflushPage('${firstMenu.popedomID }');" href="javascript:void(0);"><span>${firstMenu.name }</span></a></li>
		</c:forEach>
	</ul>
</div>
二三级菜单
<div id="leftside">
	<div id="sidebar_s">
		<div class="collapse">
			<div class="toggleCollapse"><div></div></div>
		</div>
	</div>
	<div id="sidebar">
		<div class="toggleCollapse"><h2>菜单</h2><div>collapse</div></div>			
		<div class="accordion" fillSpace="sideBar">
			<c:forEach items="${secondMenuList }" var="secondMenu" varStatus="status2">
				<div class="accordionHeader">
					<h2><span>Folder</span>${secondMenu.name }</h2>
				</div>
				<div class="accordionContent">
					<ul class="tree treeFolder">
						<c:forEach items="${thirdMenuList }" var="thirdMenu" varStatus="status3">
							<c:if test="${secondMenu.popedomID == thirdMenu.pid }">
								<li><a href="<%=basePath%>/${thirdMenu.url}?navTab=MyNav${status3.index }" target="${thirdMenu.target}" rel="MyNav${status3.index }">${thirdMenu.name }</a></li>
							</c:if>
						</c:forEach>
					</ul>
				</div>
			</c:forEach>
		</div>
	</div>
</div>

权限模块要点:
List<Privilege> topList = privilegeService.findTopList();
ActionContext.getContext().getValueStack().set("topList",topList);

if ($.browser.msie) {
	window.setInterval("CollectGarbage();", 10000);
}

<c:forEach var="" items=${topList}>
	<c:forEach>
		<li></li>
	</c:forEach>
</c:forEach>


jqurey中一些方法:
	.parent()
	.parents()
	
	.children()
	.find()
	
	siblings()
	prev()
	next()

treeview选中效果情况
1.选中,取消某个权限时,同时选中或取消其下级权限    看html页面结构,通过边看页面,边写js代码
	$(this).siblings('ul').find('input').attr('checked',this.checked);
					过滤条件    
2.当选中某个权限时,同时选中上级权限
	if(this.checked){
		$(this).parents('li').children('input').attr('checked',true);
	}
3.当取消某个权限时,如果同级别没有被选中,就取消其直接上级权限
	if($(this).parent('li').siblings('li').find('input:checked').size() == 0 ){
		$(this).parent().parent().siblings('input').attr('checked',false);
	}
	
	
注意使用jquery的find方法	.find('input:checked') 
							.attr('checked',true)
							
							
权限模块要点:
List<Privilege> topList = privilegeService.findTopList();
ActionContext.getContext().getValueStack().set("topList",topList);

一但系统确定,权限就确定了
权限表
	id	name	pid 	url

每个人登录进来,没必要再查询一遍权限。
可以这样考虑: 在项目启动的时候,将所有权限数据加载进来

写过滤器
	init()
写servlet
	init()
写监听器ServletContextListener
	编写规范	
	1.编写类继承ServletContextListener
	2.在web.xml中注册
	<!-- 自己监听器 -->
	    <listener>
			<description>HelloWorld</description>
			<listener-class>cn.sxf.common.listener.TestComet</listener-class>
		</listener>
		这个监听器在配置文件中是有顺序的,先spring的, 再自己的监听器,因为自己的模块要使用spring模块的东西
	3.  spring源码中,最高级的bean工厂: BeanFactory	接口
												ApplicationContext
													ClassPathXmlApplicationContext
													WebXmlApplicationContext一般在web项目中使用	
		
	
		public class OAInitListener implements ServletContextListener{
			//初始化的方法
			public void contextInitialized(ServletContextEvent sce){
					//获取spring工厂	application.setAttribute(“”)  key比较长
					//	第一种:WebXmlApplicationContext ctx = application.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
					//  第二种:application的获取,application = sce.getServletContext();
								WebXmlApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(application);
										在web项目中,真正的实现类是XmlWebApplicationContext类
												
					//从spring工厂中获取privilegeServices	产生的为代理对象,所以为接口,不可以是类
								IprivilegeService ps = (IprivilegeService)ctx.getBean("privilegeServiceImpl");
								
					//加载权限数据
								List<Privilege> privilegeTopList = ps.findTopList();
								
					//查询所有需要进行校验的请求url
								List<String> urlList = ps.findAllUrls();		/*String hql = "select p.url from privilege p "*/
								sce.getServletContext().setAttribute("urlList",urlList);
								
					//将权限数据放入application作用域
					sce.getServletContext().setAttribute("privelegeTopList",privelegeTopList);
			}
		}
		前台获取application域中的值		value="#application.privilegeTopList"
	
	4.  使用立即加载的方式
			no session or session close 报错
			openSessionInView这个过滤器解决延迟加载,是在一次访问的时候,
								浏览器------》   Action  -------》  Service	--------》 Dao				DB
																	事务	返回代理对象,没查
				到浏览器展示的时候,才真正的去查,一般事务控制在service层	open Session
																			begin transaction
																			commit
																			closes session
				开启opensessionInview延迟,opensession/close session 到Action前, 只是一次请求
			
			privilege.hbm.xml权限加载,立即加载子权限	lazy=false
	5.验证权限,解决延迟加载情况
		<s:itrator value = "#application.privilegeTopList">
			<s:if test="">
				<li>
					<div></div>
					<ul>
						<li></li>
						<li></li>
					</ul>
				</li>
			</s:if>
		</s:itrator>
		
		在User实体类中,添加验证权限是否存在
		public boolean checkPrivilegeByName(String name){
			for(Role r : roles){
				for(Privilege p : r.getPrivileges){
					if(name.equals(p.getName())){
						return true;
					}
				}
			}
			return false;
		}
		
		<s:if test="#session.loginUser.checkPrivilegerByName(name)"/> 	------ognl
		当用户登录成功后,立即加载role, set lazy = false;
	6.对超级管理员的设置
		具有各种操作,不用授权,具有所有权限
		if("admin".equals(loginName)){
			return true;
		}
	7.右侧链接按照权限展示
		<s:if test="#session.loginName.checkPrivilegeByName('部门删除')">
			<s:a>删除</s:a>
		</s:if>
	
	8.编写拦截器进行权限检查
		不用拦截器的影响:如果知道操作的地址,可以通过地址栏输入参数进行删除,之前做的仅是在页面显示不显示
		没能从根本上进行权限的控制
		
		通过拦截器来解决	自己写拦截器,拦截所有的action请求
			1.	实现接口interceptor 或继承 AbstractInterceptor
				public String intercept(ActionInvocation a1) throws Exception{
					
					//return null;	后面的拦截器不执行了
					return a1.invoke();
				}
			2.
				<!--自定义拦截器 -->
				<interceptors>
					<interceptor name="checkPrivilege" class="cn.itcast.CheckPrivilegeInterciptor"></interceptor>
						
					<intercept-stack name="myStack">
						<interceptor-ref name="checkPrivilege"></interceptor-ref>
						<interceptor-ref name="defaultStack"></interceptor-ref>
					</interceptor_stack>	
				</interceptors>
				
				<default-interceptors-ref  name="myStack"/>
			3. 进行权限检查
				struts.xml中
					<global-results>
						<result name="loginUI">/index.jsp</result>
						<result name="noPrivilege">/noPrivilegeUI.jsp</result>
					</global-results>
				1.如果用户没有登录
						1.1 如果用户访问的是登录功能, 放行
						1.2 如果不是登录功能,就跳转到登录页面
						
				2.如果用户登录
						2.1 如果用户有权限,就放行
							
						2.2 如果没有权限,跳转到没有权限提示页面
				
				public String CheckPrivilegeInterceptor(ActionInvocation ai){
					ActionProxy proxy = ai.getProxy();
					String namespace = proxy.getNamespace();
					String actionName = proxy.getActionName();
					String url = namespace + actionName;
					
					if(url.endWith("UI")){
						url = url.endWith(0,url.length()-2);
					}
					User user = (User)ServletActionContext.getRequest().getSession().getAttribute("loginUser);
					if(user == null){
						if(url.equls("/userAction_login")){
							return a1.invoke();
						}else{
							return "loginUI";
						}
					}else{
						List<String> urlList = ServletActionContext.getServletContext().getAttribute("urlList");
						//如果当前请求需要进行校验
						if(urlList.contains(url)){
							if(user.checkPrivilegeByUrl(url)){
								return ai.invoke();
							}else{
								return "noPrivilegeUI";
							}						
						}
						//如果当前请求不需要进行校验
						else{
							ai.invoke();
						}
					}
					}
			
				/**
				*	用户实体
				*/
				public class User{
					private String loginName;
					private Set<Role>  roles = new HashSet<Role>();
					
					public boolean isAdmin(){
						return "admin".equals(loginName);
					}
					
					public boolean checkPrivilegeByUrl(String url){
						if(isAdmin()){
							return true;
						}
						for(Role r : roles){
							for(Privilege p : r.getPrivileges()){
								if(url.equals(p.getUrl())){
									return true;
								}
							}
						}
						return false;
					}
					public String toString(){
						return loginName + "==" + loginPassword;
					}
				}
				

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值