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,畢竟我還沒來得及調試測試,等以後作了頁面顯示再一塊兒調試吧,今天感受累了。大週末都沒完全放鬆休息下,我都被本身感動了。