这里我介绍一种很常用,也比较Professor的权限控制思路。
最近看到了一个项目的权限是根据bigineger来进行计算的菜单权限,觉得还是不错,存储上只需要存储在一个字段里就可以了,通过计算算出该角色的菜单权限即可,效率也非常的快,放在session中也非常的小,下面简单说一下思路。
把具体的权限设置为一个正整数值,如果一个用户有多个权限的话,比如1,2权限,那么我们设置值的时候就是num.setBit(1),num.setBit(2),然后把返回的num值保存在session中,要验证是否有权限的话,只要从session中取得保存的num,然后执行下num.test(权限值),如果返回true就是有权限的,否则就是无权限的
首先,将界面中选好的菜单树,勾选完成后传到后台,后台通过转成字符串数组来进行设值(以下也给出了int数组的形式)
/**
* 利用BigInteger对权限进行2的权的和计算
* @param rights int型权限编码数组
* @return 2的权的和
*/
public static BigInteger sumRights(int[] rights) {
BigInteger num=new BigInteger("0");
for (int i = 0; i < rights.length; i++) {
num=num.setBit(rights[i]);
}
return num;
}
/**
* 利用BigInteger对权限进行2的权的和计算
* @param rights String型权限编码数组
* @return 2的权的和
*/
public static BigInteger sumRights(String[] rights) {
BigInteger num=new BigInteger("0");
for (int i = 0; i < rights.length; i++) {
num=num.setBit(Integer.parseInt(rights[i]));
}
return num;
}
通过上面方法,返回一个BigInteger,然后将这个数字存入所属角色的菜单权限字段中。注意的是:这里的菜单ID必须是数字,String[] rights为所选菜单的数组,通过setbit方法一一设置进num中。
其次,再获取权限的时候,也一样,通过把之前存入的菜单权限的biginteger和菜单ID做对比来判断是否具有该菜单权限
/**
* 测试是否具有指定编码的权限
* @param sum
* @param targetRights
* @return
*/
public static boolean testRights(String sum,int targetRights){
if(Tools.isEmpty(sum))
return false;
return new BigInteger(sum).testBit(targetRights);
}
sum为对应角色的菜单权限值,targetRights为具体菜单ID,通过biginteger的testBit方法来判断是否存在里面,如果存在就返回true,不存在就返回false.biginteger通过set的值,其实是2的权的和。下面有一个列子:
com.hundsun.network.post.settle.job;
import java.math.BigInteger;
public class TestBigInteger {
public static void main(String[] args) {
//初始
BigInteger num = new BigInteger("0");
num = num.setBit(2);
num = num.setBit(1);
System.out.println(num);
System.out.println(num.testBit(2));
System.out.println(num.testBit(1));
System.out.println(num.testBit(3));
}
}
返回的结果是:
6
true
true
false
为什么是6呢? 6= 2^2 + 2^1 其实计算的值是2的权的和
通过这种方式,不管是解析和查询其实效率都是很高的,占用session的空间也非常的小,一个整数就代表了所有的权限,验证的时候计算速度也很快。不为是一个好的权限设计思路。
本文摘自:http://blog.csdn.net/hys21/article/details/51161381 略加说明,感谢原作者