准备工作
1.权限的类
public class Permission{
private Long id;
private String name;
private String expression;
}
2.权限的的映射
<hibernate-mapping package="domain">
<class name="Permission" table="permission">
<id name="id" >
<generator class="native"/>
</id>
<property name="name" />
<property name="expression"/>
</class>
</hibernate-mapping>
权限的注解
1.注解类
@Target(ElementType.METHOD) //该注解标记在方法上
@Retention(RetentionPolicy.RUNTIME) //在运行时候解析
public @interface RequiredPermission {
//定义属性,必须填写
String value();
}
2.标记Action类中的方法
以部门类为例
注解都是标记在Action类的方法上
public class DepartmentAction extends BaseAction {
@Autowired
private DepartmentService departmentService;
@RequiredPermission("查看部门列表")
public String execute() throws Exception {
//业务代码
return LIST;
}
@RequiredPermission("编辑部门")
public String input() throws Exception {
//业务代码
return "input";
}
@RequiredPermission("修改/增加部门")
public String save() throws Exception{
//业务代码
return SUCCESS;
}
@RequiredPermission("删除部门")
public String delete() throws Exception{
//业务代码
return SUCCESS;
}
}
权限的加载
目的:将每个被注解的方法,生成一个权限对象,存储到数据库中.
1.权限的Action
public class PermissionAction extends BaseAction{
@Autowired
private PermissionService permissionService;
@RequiredPermission("查看权限列表")
public String execute() throws Exception {
Page<List<Permission>> page = permissionService.list(query);
super.putContext("page", page);
return LIST;
}
@RequiredPermission("加载权限")
public String reload() {
//通过页面请求,再加载权限
permissionService.reload();
return SUCCESS;
}
}
2.权限的加载方法
过程
- 通过Spring容器,获取所有Action类
- 遍历每个Action的每个方法,查找到被主键的方法
- 通过注解对象的value值,方法对象生成的表达式,生成权限对象存入数据库
注意点:为了防止重复存入数据库,要查看方法表达式是否已经存于数据库.该方法写在注解的service类中
使用到的方法:
- 获得Action类的实例的map:
ctx.getBeansOfType(所有Action类的共有父类);
(对其遍历,要将map变成set) - 判断是否被注解
方法对象.isAnnotationPresent(注解类)
- 获得注解类对象
方法对象.getAnnotation(注解类);
- 获得主键的value值:
注解对象.value();
//Spring的容器
@Autowired
private ApplicationContext ctx;
//重新加载权限
public void reload() {
System.out.println("加载权限");
//获取数据库中已有的权限表达式的set集合
Set<String> expList =new HashSet<>();
List<Permission> ps = this.list();
for (Permission permission : ps) {
expList.add(permission.getExpression());
}
//从容器获取所有的action类,key=id;value=实例
Map<String, BaseAction> actions = ctx.getBeansOfType(BaseAction.class);
//将action变成set后遍历,
for (Entry<String,BaseAction> entry:actions.entrySet()) {
Class<? extends BaseAction> clz = entry.getValue().getClass();
//获得Action类中的方法对象的数组
Method[] methods = clz.getDeclaredMethods();
for(Method m:methods) {
if(m.isAnnotationPresent(RequiredPermission.class)) {
//获取注解对象
RequiredPermission rq = m.getAnnotation(RequiredPermission.class);
//获取权限的name属性(注解对象value)
String name = rq.value();
//获取权限的表达式
String expression=PermissionUtil.creatEXP(m);
//判断数据库是否已经有了该权限
if(!expList.contains(expression)) {
//生成权限对象
Permission permission = new Permission(name,expression);
//保存权限到数据库
System.out.println(permission);
dao.save(permission);
}
}
}
}
}
//通过方法名获得权限表达式
//表达式"类的全限名:方法名 "
public static String creatEXP(Method m) {
StringBuilder str = new StringBuilder(100);
//获得全限名
Class<?> clz = m.getDeclaringClass();
String clzName = clz.getName();
//获得方法名
String methodName= m.getName();
//拼成表达式
str.append(clzName).append(":").append(methodName);
return str.toString();
}