在 Java 中,我们经常使用注解来标记 Controller 接口是否有权限。下面是一个简单的例子,展示如何创建自定义注解并使用它来判断 Controller 接口是否有权限。
首先,我们定义一个新的注解@ACL
:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// 定义一个名为ACL的注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ACL {
String[] roles(); // 用于指定哪些角色可以访问被标记的方法
}
复制代码
在这个例子中,@ACL
注解有一个属性roles
,它是一个字符串数组,用于指定哪些角色可以访问被标记的方法。
接下来,我们创建一个示例 Controller 接口,并在其中的方法上使用这个新的注解:
public interface UserController {
@ACL(roles = {"ADMIN", "USER"})
void createUser(); // 可以被ADMIN和USER角色访问
@ACL(roles = {"ADMIN"})
void deleteUser(); // 只能被ADMIN角色访问
void getUser(); // 没有特殊权限要求
}
复制代码
在这个例子中,createUser
方法可以被ADMIN
和USER
角色访问,而deleteUser
方法只能被ADMIN
角色访问。getUser
方法没有特殊权限要求。
然后,我们需要编写一个方法来检查当前用户是否具有执行某个方法所需的权限。我们可以使用反射来实现这一点:
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
public class ACLChecker {
// 检查当前用户是否具有执行某个方法所需的权限
public static boolean hasAccess(Object controller, String methodName, List<String> userRoles) {
try {
Method method = controller.getClass().getMethod(methodName); // 获取指定的方法
if (method.isAnnotationPresent(ACL.class)) { // 检查方法是否有ACL注解
ACL acl = method.getAnnotation(ACL.class); // 获取ACL注解
return Arrays.stream(acl.roles()).anyMatch(userRoles::contains); // 检查用户角色是否在注解的角色列表中
}
} catch (NoSuchMethodException e) {
e.printStackTrace(); // 捕获并打印异常
}
return false; // 如果方法没有ACL注解或用户角色不在注解的角色列表中,返回false
}
public static void main(String[] args) {
UserController userController = new UserController() {
@Override
public void createUser() {
System.out.println("Creating user..."); // 创建用户操作
}
@Override
public void deleteUser() {
System.out.println("Deleting user..."); // 删除用户操作
}
@Override
public void getUser() {
System.out.println("Getting user..."); // 获取用户操作
}
};
// 模拟当前用户的角色
List<String> currentUserRoles = Arrays.asList("USER");
// 检查不同方法的访问权限
System.out.println("Has access to create user: " + hasAccess(userController, "createUser", currentUserRoles)); // true
System.out.println("Has access to delete user: " + hasAccess(userController, "deleteUser", currentUserRoles)); // false
System.out.println("Has access to get user: " + hasAccess(userController, "getUser", currentUserRoles)); // false
}
}
复制代码
在这个例子中,hasAccess
方法接受一个控制器对象、方法名称和用户角色列表作为参数。它使用反射来获取指定的方法,并检查该方法是否具有@ACL
注解。如果注解存在,它会检查注解中的roles
值是否与用户的任何角色匹配。
运行main
方法时,你会看到以下输出:
Has access to create user: true // 表示当前用户有权限执行createUser方法
Has access to delete user: false // 表示当前用户没有权限执行deleteUser方法
Has access to get user: false // 表示当前用户没有权限执行getUser方法
复制代码
评论