在平时的工作中,有时会遇到权限问题,尤其是OA系统上,关于权限的问题尤为重要,这里我使用二进制中的运算符来实现类似的功能
快速入门
每一个操作权限都用一个二进制数表示(1、10、100、1000)。总共的权限种类有2^n种,n即代表权限类别
public static void main(String[] args) {
// 每一个操作权限都用一个二进制数表示(1、10、100、1000)。总共的权限种类有2^n种,n即代表权限类别
int first = 1; // 001 状态first
int second = 2; // 010 状态second
int third = 4; // 100 状态third
int firstsecond = first | second; // 001 | 010 = 011 初始状态
System.out.println(firstsecond | third); // 011 | 100 = 111 添加third的状态
System.out.println(firstsecond & (~second)); // 011 & (~010) = 011 & 101 = 001 去除second的状态
System.out.println((firstsecond & second) == second); // 011 & 010 = 010 判断是否有second的权限:(firstsethirdond & second)==second
System.out.println((firstsecond & third) == third); // 011 & 100 = 000
/**
* 运算符 运算 例子 结果
& AND(与) false&true FALSE
| OR(或) false|true TRUE
^ XOR(异或) false^true TRUE
! NOT(非) !false TRUE
&& AND(短路) false&&true FALSE
|| OR(短路) false||true TRUE
*
*
*
* 1.权限的分配(或运算)
* firstsecond | third
*
* 2、权限的删除(求补、与运算)
* firstsecond & (~second)
*
* 3、权限的验证(与运算)
* (firstsecond & second) == second
*/
}
可以看到上面定义了三种权限,first,second,third,总结起来就是使用如下运算符来实现:
- 权限的分配(或运算)
- 权限的删除(求补、与运算)
- 权限的验证(与运算)
仿论坛权限控制
上面一个简单的理解demo过后,我写了一个稍微复杂的栗子,来实现不同的权限控制。
private static int regist = 1; // 001 用户注册
private static int login = 2; // 010 用户登录
private static int addTop = 4; // 100 添加头条
private static int checkRegist = 8; // 1000 审核注册用户
private static int deleteUser = 16; // 10000 删除所有用户
private static int initPermission = 2; //所有用户的初始化权限,即都拥有登录权限
可以看到,这里定义了五种权限,初始权限是2,即表示所有用户都有登录的权限。
/**
* 普通用户
* 1.用户注册 001 1
* 2.用户登录 010 2
*
* 普通管理员
* 3.添加头条 100 4
* 4.审核注册用户 1000 8
*
* 超级管理员
* 3.添加头条 100 4
* 4.审核注册用户 1000 8
* 5.删除所有用户 10000 16
*/
上面定义了三种不同的用户,并且都有不同的权限,下面为不同的用户添加不同的权限,注意这里默认所有的用户都有登录的权限。
初始化用户权限
/**
* 初始化所有用户和权限
*/
private static void initPermissionAndUsers() {
// 添加所有权限
mAllPermissions.put(regist,"用户注册");
mAllPermissions.put(login,"用户登录");
mAllPermissions.put(addTop,"添加头条");
mAllPermissions.put(checkRegist,"审核注册用户");
mAllPermissions.put(deleteUser,"删除所有用户");
// 添加所有用户类型
mAllUsers.put("普通用户",2);
mAllUsers.put("管理员",2);
mAllUsers.put("超级管理员",2);
// 为不同用户设置权限
for (String userInfo : mAllUsers.keySet()) {
switch (userInfo) {
case "普通用户": {
mAllUsers.put("普通用户",mAllUsers.get("普通用户") | 1);
}
case "管理员": {
mAllUsers.put("管理员",mAllUsers.get("管理员") | 2 | 4 | 8);
}
case "超级管理员": {
mAllUsers.put("超级管理员",mAllUsers.get("超级管理员") | 2 | 4 | 8 | 16);
break;
}
default:
break;
}
}
}
可以看到,和我们上面的分析是一样的,如果需要为某一个用户添加某一个权限,只需要将其当前所拥有的权限和该权限进行”或”运算即可。下面添加打印所有用户拥有的权限的方法:
打印所有用户权限
/**
* 打印出所有的用户拥有的权限
*/
private static void printAllUserPermission() {
for (String userInfo : mAllUsers.keySet()) {
checkUserPermission(userInfo);
System.out.println("\n");
}
}
/**
* 检查当前用户类型有哪些权限
* @param userInfo 用户类型
*/
private static void checkUserPermission(String userInfo) {
for (Integer key : mAllPermissions.keySet()) {
//权限的验证(与运算)
boolean hasPermission = (mAllUsers.get(userInfo) & key) == key;
if (hasPermission) {
System.out.println(userInfo+"拥有 "+mAllPermissions.get(key)+" 权限");
}
}
}
上面的代码主要做了权限的验证工作,如果当前用户拥有该权限,就打印出来,此时运行效果如下:
验证用户权限
其实上面打印所有用户权限的方法里,已经是验证用户的权限了,下面我在具体一点,添加了一个验证当前用户是否具有某一权限的方法:
/**
* 检查userInfo类型的用户是否拥有permission权限
* @param userInfo
* @param permission
*/
private static void checkUserHasPermission(String userInfo, int permission) {
boolean hasPermission = (mAllUsers.get(userInfo) & permission) == permission;
if (hasPermission) {
System.out.println(userInfo+" 拥有 "+mAllPermissions.get(permission)+" 权限");
} else {
System.out.println(userInfo+" 没有 "+mAllPermissions.get(permission)+" 权限");
}
}
具体验证调用如下:
checkUserHasPermission("普通用户",4);
checkUserHasPermission("管理员",4);
去除用户权限
现在,尝试将”管理员”的”添加头条”权限移除掉,在移除之前,先检查其是否拥有该权限,移除以后,在check一下,看下是否移除成功。
- 权限的删除(求补、与运算)
/**
* 移除当前userInfo的permission权限
* @param userInfo
* @param permission
*/
private static void removeUserPermission(String userInfo, int permission) {
mAllUsers.put(userInfo,mAllUsers.get(userInfo) & (~permission));
System.out.println(userInfo+" 被去除了 ========= "+mAllPermissions.get(permission));
}
checkUserHasPermission("管理员",4);
removeUserPermission("管理员",4);
checkUserHasPermission("管理员",4);
此时运行结果如下:
ok,关于二进制权限的管理控制就到这里了。