OA-登陆权限及权限树的实现

1.数据回现:
  不论什么回显只需在跳转页面时,传递属性值即可

2.设置级联操作:如:删除顶级部门时,删除所有子部门
  casecade:根据需要设置

3.查找顶级部门,查找子部门
   1)("from Department d where d.parent is NULL").list
   2)("from Department d where d.parent.id=?").setParameter(0,parentId).list

4.OGNL表达式
   1)判断:userAction_%{id==null? 'add':'edit'}
   2)获取数组某个值如:%{#departmentList[0].parent.id}

5.树状结构
  1)工具类:
-------------------------------------------------------------------------------
/**
     * 遍历部门树,得到所有的部门列表,并修改了名称以表示层次。
     *
     * @param topList
     * @return
     */
    public static List getAllDepartments(List topList) {
        List list = new ArrayList();
        walkDepartmentTrees(topList, "┣", list);
        return list;
    }

    /*
     * 遍历部门树,把遍历出来的部门都放到指定的集合中
     */
    private static void walkDepartmentTrees(Collection topList, String prefix, List list) {
        for (Department top : topList) {
            // 顶点
            Department copy = new Department(); // 原对象是在Session中的对象,是持久化状态,所以要使用副本。
            copy.setId(top.getId());
            copy.setName(prefix + top.getName());
            list.add(copy);
            // 子树
            walkDepartmentTrees(top.getChildren(), " " + prefix, list); // 使用的是全角的空格
        }
    }

-------------------------------------------------------------------------------------
   2)配置子部门排序:
      
========================================================================================================

6.登陆权限的实现:

   思路:

     1)创建监听器继承ServletContextListener接口,监听服务器容器的创建销毁
     2)在init中获取所有的权限信息,放入application作用域

     3)在页面进行权限的判断显示(主菜单)

   1.建立用户===角色===权限的多对多关系,创建表,映射
   2.初始化权限数据,初始化超级管理员      MD5加密的使用:DigestUtils.md5Hex("admin")
   3.设置权限树(权限管理)的显示及效果      roleAction/setPrivilegeUI.jsp
   4.     1)创建监听器继承ServletContextListener接口,监听服务器容器的创建销毁
          2)在init中获取所有的权限信息,放入application作用域
          ----------------------------------------------------------------------
                    
      public void contextInitialized(ServletContextEvent sce) {
                                ServletContext application=sce.getServletContext();
                                
                                //得到service的对象实例
                                ApplicationContext ac=WebApplicationContextUtils.getWebApplicationContext(application);
                                PrivilegeService privilegeService=(PrivilegeService) ac.getBean("privilegeServiceImpl");
                                
                                
                                //准备所有顶级权限的集合(顶级菜单)
                                List topPrivilegeList=privilegeService.findTopList();
                                application.setAttribute("topPrivilegeList", topPrivilegeList);
                                System.out.println("------已准备好顶级权限的数据----------");
                                
                                //准备所有权限的url集合(用于拦截器中权限的判断,防止用户手工输入地址)
                                 List allPrivilegeUrls=privilegeService.getAllPrivilegeUrls();
                                 application.setAttribute("allPrivilegeUrls",allPrivilegeUrls);
                                    System.out.println("------已准备好所有权限的url数据");
                            }

          ----------------------------------------------------------------------
           3)在页面进行权限的判断显示(主菜单)
                ①懒加载异常的处理
                                        将所有相关联的数据(role,user,privilege):lazy="false"
                ①核心代码:
                                         页面:    homeAction/left.jsp
          -----------------------------------------------------------------------
                           
    

    -------------------------------------------------------------------------------------------------------
                                          后台: domian/user.hasPrivilegeByName
                                        
 public boolean hasPrivilegeByName(String privilegeName){
                                            //超级管理员有所有的权限
                                            if(isAdmin()){
                                                return true;
                                            }
                                            
                                            //一般用户有权限才返回true
                                            for(Role role:roles){
                                                for(Privilege privilege:role.getPrivileges()){
                                                    if(privilege.getName().equals(privilegeName)){
                                                        return true;
                                                    }
                                                }
                                            }
                                            return false;
                                        }         


    ---------------------------------------------------------------------------------------------------------
           
         5.进行三级菜单的判断显示(方案:重写的doendTag方法)
                  1)重写类  org/apache/struts2/views/jsp/ui/AnchorTag.java
                  2)重写方法
           --------------------------------------------------------------------------------------------------
                            
   public int doEndTag() throws JspException {
                                    //获取当前用户
                                    User user= (User) pageContext.getSession().getAttribute("user");
                                    
                                    //获取当前url  如果有参数就要去掉后面的参数字符串
                                    String privilegeUrl=action;
                                    System.out.println(action+"----------------------------");
                                    int pos=privilegeUrl.indexOf("?");
                                    if(pos>-1){
                                        privilegeUrl=privilegeUrl.substring(0,pos);
                                    }
                                    
                                    if(user.hasPrivilegeByUrl(privilegeUrl)){
                                        //如果有权限则正常的生成与输出a标签
                                        return super.doEndTag();
                                    }else{
                                        //没有权限不显示任何东西,继续执行页面中后面的代码
                                        return EVAL_PAGE;
                                    }
                                }

           
           ---------------------------------------------------------------------------------------------------
          6.配建登陆拦截器实现intercepter接口,进行登陆拦截判断(判断用户是否登陆,防止用户直接输入地址)
              1)在监听器中,将所有的权限url放入application中(不包含null(主菜单)和重复的)
              2)在拦截器中判断用户:                       类:CheckPrivilegeInterceptor
                     1.是否已经登陆,及是否正要去登陆                                
                     2.判断已登陆用户的权限(从url集合中排除公共权限,如:注销,登陆)      方法:user.hasPrivilegeByUrl();
           ---------------------------------------------------------------------------------------------------------------
 
  public class CheckPrivilegeInterceptor extends AbstractInterceptor {
    public String intercept(ActionInvocation invocation) throws Exception {
        //获取当前用户
        User user=(User) ActionContext.getContext().getSession().get("user");
        //获取当前访问的url,并去掉当前应用 的前缀(也就是nameSpace+actionName)
        String privilegeUrl=null;
        String namespace=invocation.getProxy().getNamespace();
        String actionName=invocation.getProxy().getActionName();
        
        if(namespace.endsWith("/")){
            privilegeUrl=namespace+actionName;
        }else{
            privilegeUrl=namespace+"/"+actionName;
        }
        
        //去掉开头的‘/’
        if(privilegeUrl.startsWith("/")){
            privilegeUrl=privilegeUrl.substring(1);
        }
        
        //如果未登陆用户
        if(user==null){
            if(privilegeUrl.startsWith("userAction_login")){
                //如果是去登陆,则放行
                return invocation.invoke();
            }else{
                //如果不是去登陆,就转到登陆界面
                return "loginUI";
            }
        }else{
            //如果已经登陆,则判断权限
            if(user.hasPrivilegeByUrl(privilegeUrl)){
                //如果有权限就放行
                return invocation.invoke();
            }else{
                //如果没有就转到提示页面
                return "noPrivilegeError";
            }
        }
        
    }

}
               --------------------------------------------------------------------------------------------------------
public boolean hasPrivilegeByUrl(String privilegeUrl) {
        // 超级管理员有所有的权限
        if (isAdmin()) {
            return true;
        }

        // 如果以UI后缀结尾,就去掉UI后缀,以得到对应的权限(例如:addUI与add是同一个权限)
        if (privilegeUrl.endsWith("UI")) {
            privilegeUrl = privilegeUrl.substring(0, privilegeUrl.length() - 2);
        }
        
        //取出数据库中所有的权限url
        List allPrivilegeUrls=(List) ActionContext.getContext().getApplication().get("allPrivilegeUrls");
        
        if(!allPrivilegeUrls.contains(privilegeUrl)){
            //设置不需要控制的功能,权限 如:userAction_loginUI/login/homeAction_index
            return true;
        }else{
            //要控制的功能
            // 其他用户要是有权限才返回true
            for (Role role : roles) {
                for (Privilege privilege : role.getPrivileges()) {
                    if (privilegeUrl.equals(privilege.getUrl())) {
                        return true;
                    }
                }
            }
        }
        
            return false;
    }


           ================================================================================================================
          7.细节处理:
             1) 解决服务器重启session失效问题           :     序列化  implements Serializable  
             2)session过期导致登陆页面层叠嵌套问题          :   刷新上级窗口
                     if (window.parent != window) {
                           window.parent.location.reload(true);     
                      }
                     
                     
                     
                     
            
        
        
              
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                 
   




你可能感兴趣的:(OA-登陆权限及权限树的实现)