权限模块
一级菜单:
<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;
}
}
关于权限模块的设计
最新推荐文章于 2023-12-02 21:45:00 发布