技能修炼:
在S2SH集成环境中使用Struts2的Interceptor拦截器实现权限的控制。
准备知识:
★ 自定义注解的编写: @interface ****★ Struts2 Interceptor拦截器的编写和配置 1、 编写一个拦截器实现Interceptor接口或者继承AbstractInterceptor 2、 在struts.xml文件中注册自定义拦截器 3、 在需要使用的Action中引用自定义拦截器。 ****★ 了解Struts2拦截器原理 AOP面向切面编程和动态代理
提示
使用Spring的AOP也可以实现权限的控制,但是经过Spring的AOP方法处理后再交给Struts2时,注意Struts2中上下文参数丢失问题。
Struts2的拦截器使用了动态代理,从动态代理类中获取调用方法名并通过invocation.getAction().getClass().getMethod(methodName)获取被调用的方法。然后根据session中保存的用户权限和从方法注解中获取的权限进行判断,看用户是否具有调用该方法的权限进行处理。
下面是使用Struts2的Interceptor拦截器实现权限控制的例子
这里我们使用注解为每个Action的方法声明权限。
首先创建自定义注解Permission,用于设置权限:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Permission {
/** 模块名称 /
String module();
/* 权限名称 */
String privilege();
}
其中的Permission的module和privilege为模块和模块对应的权限,每个用户登录时都把权限信息保存到session中,方便在拦截器中对权限的判断。
在想要设置权限的方法加入自定义的Permission注解用于标识该方法的权限:
@Permission(module=“order”, privilege=“confirmOrder”)
public String confirmOrder(){…}
接下来最重要的就是编写拦截器对权限进行判断,并作出正确的处理:
public class PrivilegeInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = 742285864455102141L;
/**
* 1、通过动态代理类和反射机制获取调用的方法
* 2、获取方法的Permission注解
* 3、获取Permission中包含的权限信息(构造SystemPrivilege权限类)
* 4、和用户的权限信息进行对比(PrivilegeGroup中的SystemPrivilege)判断用户的权限
*/
@Override
public String intercept(ActionInvocation invocation) throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
if(WebUtil.getRequestURI(request).startsWith("/MusicalInstrumentsStore/control/")){
String methodName = invocation.getProxy().getMethod();
Method method = invocation.getAction().getClass().getMethod(methodName);
if(method!=null && method.isAnnotationPresent(Permission.class)){
System.out.println("Call the Action Method:" + method.toString());
//获取当期执行的Action上的注解
Permission permission = method.getAnnotation(Permission.class);
System.out.println("当前需要的权限为:" + permission.module());
//获取当期执行的Action方法需要的权限
SystemPrivilege methodPrivilege = new SystemPrivilege(new SystemPrivilegePK(permission.module(),permission.privilege()));
//WebUtil.getEmployee(request) 方法是从session中获取保存的employee信息,包括权限集合
Employee employee = WebUtil.getEmployee(request);
//循环判断用户是否具有该权限,如果有则继续执行,否则返回提示视图
for(PrivilegeGroup group : employee.getGroups()){
if(group.getPrivileges().contains(methodPrivilege)){
return invocation.invoke();
}
}
System.out.println("权限不足");
return "privilegemessage";
}
System.out.println("未设置权限");
return invocation.invoke();
}
System.out.println("所有权限");
return invocation.invoke();
}
}