比如数据库中的 menu 表如上图所示。为角色设定相应权限,需要为角色分配相应的菜单。我们可以设计一张角色和菜单关联的表来保存角色和菜单之间的关系,或者将菜单的 id 拼接成字符串保存在角色表中。同样的我们也可以使用 BigInteger 进行2的权值校验来实现。
BigInteger 保存并校验菜单权限
BigInteger 中有两个方法,分别为:setBit() 和 testBit()
- setBit(n):计算 2^n 的值,比如 setBit(3) = 2^3 = 8
- sum.testBit(n): 检验 sum 中是否有 2^n,有返回 true ,没有返回 false。
所以我们可以使用以上两个方法,将菜单的 id 作为指数,将角色具有的所有菜单权限进行2的权的和计算,例如具有1,3,5 的菜单权限即保存:2^1 + 2^3 + 2^5 的值
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;
}
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;
}
对权限进行检验的时候使用
/**
* 测试是否具有指定编码的权限
* @param sum
* @param targetRights
* @return
*/
public static boolean testRights(BigInteger sum,int targetRights){
return sum.testBit(targetRights);
}
/**
* 测试是否具有指定编码的权限
* @param sum
* @param targetRights
* @return
*/
public static boolean testRights(String sum,int targetRights){
if(Tools.isEmpty(sum))
return false;
return testRights(new BigInteger(sum),targetRights);
}
/**
* 测试是否具有指定编码的权限
* @param sum
* @param targetRights
* @return
*/
public static boolean testRights(String sum,String targetRights){
if(Tools.isEmpty(sum))
return false;
return testRights(new BigInteger(sum),targetRights);
}
/**
* 测试是否具有指定编码的权限
* @param sum
* @param targetRights
* @return
*/
public static boolean testRights(BigInteger sum,String targetRights){
return testRights(sum,Integer.parseInt(targetRights));
}
根据权限获取菜单
- roleRights : 权限的2的权和值,保存角色的菜单权限
- menuList:获取所有菜单
- 根据 roleRights 判断是否具有菜单权限,递归搜索其子菜单
- 有则遍历其子菜单
- 没有则跳过
/**根据角色权限获取本权限的菜单列表(递归处理)
* @param menuList:传入的总菜单
* @param roleRights:加密的权限字符串
* @return
*/
public List<Menu> readMenu(List<Menu> menuList,String roleRights){
for(int i=0;i<menuList.size();i++){
menuList.get(i).setHasMenu(RightsHelper.testRights(roleRights, menuList.get(i).getMENU_ID()));
if(menuList.get(i).isHasMenu()){ //判断是否有此菜单权限
this.readMenu(menuList.get(i).getSubMenu(), roleRights);//是:继续排查其子菜单
}
}
return menuList;
}