在使用spring的aop拦截技术的时候,我们在调用ProceedingJoinPoint的proceed()方法
的时候,在执行struts2的方法的时候,struts2的堆栈里面的数据会丢失,如何解决??比方说我们在用struts2来做登陆的时候用户名和密码,只要我们用spring拦截在执行该方法的时候
在堆栈里面的username和password就会为空
的时候,在执行struts2的方法的时候,struts2的堆栈里面的数据会丢失,如何解决??比方说我们在用struts2来做登陆的时候用户名和密码,只要我们用spring拦截在执行该方法的时候
在堆栈里面的username和password就会为空
private void anyMethod() {}//声明一个切入点
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
//if() {//判断用户是否有权限
System.out.println("进入方法");
Object result = pjp.proceed();
System.out.println("执行的方法:" + pjp.getSignature().getName());
Method method = pjp.getTarget().getClass().getMethod(pjp.getSignature().getName());
Permission permission = method.getAnnotation(Permission.class);
if(permission!=null) {
System.out.println("---"+permission.model());
System.out.println("---"+permission.privilegeValue());
}
/**
* 在这里我们就可以利用上面的参数来判断权限
*/
System.out.println("退出方法");
//}
return result;
}
/**
* 校验用户是否具有执行当前方法的权限
*/
private boolean validate(Method method) {
if(method!=null && method.isAnnotationPresent(Permission.class)){
Permission permission = method.getAnnotation(Permission.class);
/* 得到当前方法的系统权限 */
SystemPrivilege privilege = new SystemPrivilege(new SystemPrivilegePK(permission.model(),permission.privilegeValue()));
/* 得到用户拥有的所有权限 */
Employee employee = (Employee)ActionContext.getContext().getSession().get("employee");
for(PrivilegeGroup p : employee.getGroups()) {
if(p.getPrivileges().contains(privilege))return true;
}
return false;
}
return true;
}
}
HttpServletRequest request = (HttpServletRequest)pjp.getArgs()[2];
HttpSession session = request.getSession();
拦截Struts1.x时,我是这样取得session的。后来我一直用Spring @MVC,这个WEB框架很牛的,灵活得难以想象,它可以让程序员给Action中的方法的参数随意定制,例如:
public String logon(HttpServletRequest request, String userName, String password){
//Todo
}
logon()方法中的参数可以随意制定,我这里定制了三个,那么request对象Spring MVC会自动填充(实例化),剩下的userName和password可以在url参数中或form表单中传过来。后来我想,方法签名中匹配一个HttpServletRequest参数,Spring就能自动实体化,那么在切入点方法中也加一个HttpServletRequest参数恺不是也能实体化?幸运的是我猜中了。即:
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {}方法参数中加入HttpServletRequest参数:
public Object doBasicProfiling(ProceedingJoinPoint pjp, HttpServletRequest request) throws Throwable {
HttpSession session = request.getSession();
}
其实request实例能不能被Spring实例化成功,取得决拦截配置,我的这个配置是:
@Around("pointcut() && isPrivlegeCheck() && args(*,request,..)")//环绕通知
这个request对象仍然是借助于被拦截的方法中的request参数对象。
Struts2我很少用它了(用惯了Spring就很难再接受那种侵入式编程框架),但应该也可以寻求解决方案,按照上面的思路提供一个比较笨拙的办法:在Action中设置一个HttpServletRequest属性,在被拦截的方法中为该属性赋值,写个简单的代码://Action for Struts2
public class UserAction implements Action { //被拦截的方法
@拦截配置
public String execute(){
//Todo
} //获得J2EE标准的request对象
public HttpServletRequest getRequest(){
return ServletActionContext.getRequest();
}
}//Aop point
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
Object result = pjp.proceed();//先让被拦截的方法运行
UserAction action = (UserAction)pjp.getThis();//不是知道是不是这个方法,返回代理对象
HttpServletRequest request = action.getRequest();
//取得empolyee对象,分析权限,
if(validate(xxx)){
return result;
}else{
request.setAttribute("message","您无权进入...");
return message;
}
}