今天看到一个项目使用了BigInteger.setBit与BigInteger.testBit来实现权限控制,觉得很有趣,mark一下。存储上只需要存储在一个字段里就可以了,通过计算算出该角色的菜单权限即可,效率也非常的快,放在session中也非常的小,下面简单说一下思路。
首先,将界面中选好的菜单树,勾选完成后传到后台,后台通过转成字符串数组来进行设值
通过上面方法,返回一个BigInteger,然后将这个数字存入所属角色的菜单权限字段中。注意的是:这里的菜单ID必须是数字, String[] rights为所选菜单的数组,通过setbit方法一一设置进num中。
其奖,再获取权限的时候,也一样,通过把之前存入的菜单权限的biginteger和菜单ID做对比来判断是否具有该菜单权限
sum为对应角色的菜单权限值, targetRights为具体菜单ID,通过biginteger的testBit方法来判断是否存在里面,如果存在就返回true,不存在就返回false.
biginteger通过set的值,其实是2的权的和。下面有一个列子:
num的值为6,是这样计算的2^2+1^2=6。通过这种方式,不管是解析和查询其实效率都是很高的,占用session的空间也非常的小,不为是一个好的权限设计思路。
列出一下这两个方法的解释:
1.testBit方法的解释:
boolean java.math.BigInteger.testBit(int n)
Returns true
if and only if the designated bit is set. (Computes ((this & (1<<n)) != 0)
.)
-
Parameters:
- n index of bit to test. Returns:
-
true
if and only if the designated bit is set.
Throws:
ArithmeticException - n
is negative.
意思就是将1左移n位,与this做&运算,其实就是判断当前数(要写成二进制)第n+1位上的数是不是为1,是的话返回true
2.setBit方法的解释
BigInteger java.math.BigInteger.setBit(int n)
Returns a BigInteger whose value is equivalent to this BigInteger with the designated bit set. (Computes(this | (1<<n))
.)
-
Parameters:
- n index of bit to set. Returns:
-
this | (1<<n)
Throws:
ArithmeticException -
n
is negative.
意思就是将1左移n位,与this对象做|运算,这样的话,就会将this的二进制格式的第n+1位的数变为1.这样很明显就和上一个方法形成一对,
n可以作为某个功能编号,而角色可以使用setBit的方法设置编号,然后使用testBit来测试是不是含有n编号的功能。
如果每次有添加多个新的功能,那么就用这些功能编号依次给原来的角色编号执行setBit得到新的角色编号。