1、咱们平时作项目的时候与权限相关的基本都由技术主干作好了,或者只是套用其余项目的,修修改改,通常人不多有机会涉及权限这一块,或会从头至尾去实现一遍权限,事实上权限并不比实际开发业务好实现,或实现了代码老是不那么完美,若是你没有本身实现过一遍权限管理,你知道怎么根据拥有的菜单权限动态显示左侧菜单导航?而且设置展开,收缩,选中样式?接下来我准备本身去探索下,而后再看看那些大神的实现,看本身有哪些是欠缺考虑的,或者能够改进的。别人实现好的总归是别人的,你拿来用,也只是暂时用,过不久就忘了,本身写的再很差,你总归会在其中学到点什么,对不对?关于菜单显示,我想分为两个阶段,一是从后台获取权限树,二是在前台显示权限树,这一节先作后台的,但愿一个晚上搞定。java
2、为回答上述几个问题,我初步的设想是这样的。sql
一、将每次请求都记录在一个全局变量,已供后面判断哪一个菜单须要展开,哪一个菜单须要显示选中样式。缓存
二、根据当前登陆用户获取其全部菜单权限,再和系统全部菜单权限匹配,匹配上的就显示,匹配不上就不显示ide
3、具体实现测试
一、怎么保存每次请求呢,咱们首先想到的是拦截器和缓存。首先定义一个全局变量,而后在定义一个拦截器,拦截全部方法上的请求,每次请求的都将url赋值个全局变量,最后再将这个全局变量放入到缓存,后面能够随时随地获取,代码以下:url
(1)配置cache插件插件
// 加载缓存插件 me.add(new EhCachePlugin());
(2)pom.xml配置调试
<!-- ehcache 2 缓存--> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>2.6.11</version> </dependency>
(3)配置缓存code
<?xml version="1.0" encoding="UTF-8"?> <ehcache updateCheck="false" monitoring="autodetect" dynamicConfig="false"> <defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="7200" timeToLiveSeconds="7200" overflowToDisk="true" diskSpoolBufferSizeMB="10" /> <cache name="_canyou_action_key_" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="10" timeToLiveSeconds="10" overflowToDisk="true" diskSpoolBufferSizeMB="10" /> </ehcache>
(4)定义拦截器xml
public class ActionInceptor implements Interceptor { @Override public void intercept(Invocation inv) { if(ShiroMethod.findUserIdByUsername() != null) { //这里使用登录用户名为cachename CacheKit.put(ShiroKit.ACTION_KEY_CACHE_NAME,ShiroMethod.findUserIdByUsername(), inv.getActionKey()); } } }
(5)使用拦截器
me.addGlobalActionInterceptor(new ActionInceptor());
二、下面开始获取权限树,首先先获取全部的菜单权限,而后再根据用户获取所拥有的菜单权限
(1)获取全部菜单权限
sql
###获取全部菜单权限 #sql("findAllMenuPermission") select * from sys_permission where action_type = 1 #end
java
/** * 获取全部菜单权限 * @return */ public List<Permission> findAllMenuPermission(){ SqlPara sqlPara = dao.getSqlPara("sys.findAllMenuPermission"); return dao.find(sqlPara); }
(2)获取登录用户拥有的菜单权限,代码不详细说明,这个很简单。
二、怎么获得将要显示在页面的导航菜单呢,废话很少说,请看代码:(后面确定要完善的)
(1)获取权限树;
(1)获取权限树; package cn.learning.system.kit; import java.util.List; import cn.learning.system.shiro.ShiroKit; import cn.learning.system.shiro.ShiroMethod; import com.jfinal.plugin.activerecord.Record; import com.learnging.system.model.Permission; public class Menukit { /** * 获取将要显示在页面的全部菜单 * @return */ public List<Record> getMenusTree (){ List<Permission> allMenuPerms = ShiroMethod.findAllMenuPermission(); List<Permission> userMenuPerms = ShiroMethod.findMenuePermissionByUserId(); List<Record> list = MenusTree(allMenuPerms, userMenuPerms); return list; } /** * 根据全部菜单权限和用户拥有的菜单权限获得当前能够显示在页面的菜单 * @param allMenuPerms * @param userMenuPerms * @return */ private List<Record> MenusTree(List<Permission> allMenuPerms,List<Permission> userMenuPerms) { String currentPermission = ShiroKit.ACTION_KEY_CACHE_NAME; //获取存放当前请求路径 List<Record> menusTree = null ; for(Permission perm : userMenuPerms) { Record record = new Record(); if(allMenuPerms.contains(perm)){//若是拥有的菜单权限包含在全部菜单权限中,那么就设置相关值,若是不包含则不显示 record.set("Id", perm.getId()); record.set("ActionType", perm.getActionType()); record.set("ActionUrl", perm.getActionUrl()); record.set("MenuLevel", perm.getMenuLevel()); if(perm.getActionUrl().equals(currentPermission)){//选中请求的路径 record.set("Selected", true); } menusTree.add(record); } } return menusTree; } }
(2)接下来的问题就是怎么在前台能够获取到后台方法,将权限树展现在页面,以下配置模板引擎便可:
/** * 设置引擎模板 */ @Override public void configEngine(Engine me) { me.addSharedMethod(new cn.learning.system.kit.Menukit()); }
4、我想象的后台就这么一鼓作气了,就那么简单,固然可能会有不少考虑不周的,可能代码还有bug,毕竟我还没来得及调试测试,等以后作了页面显示再一块儿调试吧,今天感受累了。大周末都没完全放松休息下,我都被本身感动了。