Url权限匹配方式调优
2017-06-13 00:06
176 查看
前言
最近一直做权限框架的优化,在此期间优化了不同权限框架的不同代码,有shiro-cas的,还有SpringAop的,现在小编说一下自己在项目中是如何优化权限字符串的匹配过程。需求
不同的用户对应着不同的角色,不同的角色拥有不同的资源,小编的项目中的资源是一些具体的Url,现在项目中的权限是这么做的,当用户访问某个资源时,系统会拿着目标资源去和该用户拥有的资源一一去匹配,用户的资源是放在List中的,那么问题来了,匹配的过程很耗时,具体看代码。匹配资源V1.0
public boolean checkAccess(String flag, HttpSession session) { String loginName = (String) session.getAttribute("userLoginName"); boolean desFlag=false; //1 根据用户的登录名得到用户拥有的资源 List<String> list = permissionMapper.getPermissions(loginName); //2 拿着将要访问的资源(flag)与用户拥有的资源一一匹配, //匹配成功后跳出循环,返回true,否则返回false if (list != null && list.size() > 0) { for (String str : list) { if(str.equals(flag)){ desFlag=true; break; } } } return desFlag; }
上面匹配的过程是在for循环中,查找的匹配的时间复杂度是O(n)。
匹配资源V2.0
public Map<String, String> authorityMap = null; @Override public boolean checkAccess(String flag, HttpSession session) { String desUrl=""; boolean desFlag=false; //1 在session中获取登录名 String loginName = (String) session.getAttribute("un"); //2 在session中获取用户角色ID Integer roleID= (Integer) session.getAttribute("roleID"); String ROLE_ID_MAP=roleID.toString()+"_"+"MAP"; //3 在redis中查找存放资源的map,若map存在,则通过目标资源获取 authorityMap=jedisClient.hgetAll(ROLE_ID_MAP); if (authorityMap!=null && authorityMap.size()>0){ //3.1 匹配资源 这是的时间复杂度大约为O(1) desUrl=authorityMap.get(flag); }else { //3.2 若存放资源的map不存在,在数据库中将资源搜出来,放入map中, //这时候map的key就是资源(Url)value 是1 目的是省内存 List<String> list = permissionMapper.getPermissions(loginName); if (list != null && list.size() > 0) { for (String str : list) { authorityMap.put(str,"1"); } //3.3 匹配资源 这是的时间复杂度大约为O(1) desUrl=authorityMap.get(flag); //3.4 将map放入redis中 jedisClient.hmset(ROLE_ID_MAP,authorityMap); } } //4 判断资源是否匹配成功 if (StringUtils.isNoneBlank(desUrl)){ desFlag=true; } return desFlag; }
上面的做法是,用HashMap来代替List,然后将存放资源的map放入redis中缓存起来,这样以来不用每次匹配时去数据库中查找,最重要的是在map中查找元素的时间复杂度是O(1),比在list中做匹配的时间复杂度O(n)要低。
操作redis的方法
@Override public String hmset(String key, Map<String, String> map) { Jedis jedis = jedisPool.getResource(); String result=jedis.hmset(key,map); jedis.close(); return result; } @Override public List<String> hmget(String key, String filed) { Jedis jedis = jedisPool.getResource(); List<String> result=jedis.hmget(filed); jedis.close(); return result; } @Override public Map<String, String> hgetAll(String key) { Jedis jedis = jedisPool.getResource(); Map<String, String> value; value = jedis.hgetAll(key ); jedis.close(); return value; }
注意
小编用的redis客户端的版本号是2.7.2,故可以用jedis.close()来归还资源,如果用的是低版本的那么必须用
jedisPool.returnResource(jedis);来归还资源,要不程序运行一段时间后就会卡死。这算是运用redis的一个经验吧!
相关文章推荐
- Spring Security通过URL模式匹配的声明式权限控制
- 简述Struts2的url匹配方式
- url-pattern主要有四种匹配方式
- //使用**异步**任务方式 HttpUrlConnection方式 要在清单列表设置连接网络权限
- java安全框架-Shiro学习笔记(六)-url匹配方式+shiro标签使用+session会话机制
- urls.py中url匹配的方式
- java web.xml配置文件中url-pattern路径匹配方式
- URL-based 方式和 HTML-based方式的差别(摘自关河)
- 以程序的方式操纵NTFS的文件权限(一)
- 以程序的方式操作NTFS的文件权限
- Servlet和Filter的url匹配以及url-pattern详解
- JSP中href(url)与sumbit的提交数据方式对比(土地资源项目Javabean技术应用心得)
- 通过试验探索Access 2000/XP 数据库的最佳 NTFS 权限设置Microsoft Jet 数据库引擎打不开文件'D:\wwwroot\test\data\'。 它已经被别的用户以独占方式打开,或没有查看数据的权限。
- 无法在Web服务器上启动调试。您不具备调试此应用程序的权限,此项目的URL位于Internet区域。
- URL-based 方式和 HTML-based方式的差别(摘自关河)
- 以程序的方式操纵NTFS的文件权限(三)
- 2个页面间不通过Session与url的传值方式
- 2个页面间不通过Session与url的传值方式。
- 2个页面间不通过Session与url的传值方式。 选择自 syeerzy 的 Blog
- url带参数的实现方式