您的位置:首页 > 其它

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的一个经验吧!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  框架 优化 权限管理