完成了前面的一些工作,准备测试一下使用AOP实现权限管理.
首先,写了一个增加版块的action,这个比较简单了,没有什么问题,只是在写代码的过程中没有注意大小写,花了点时间而己.
接着写一个Interceptor类,并将其定义为切面,使用@Aspect,同时将其交给spring管理,使用@Component注解.代码如下:
@Component
@Aspect
public class LoginInterceptor {
// @PointCut("execution(* bbs.web.action..*.*(..))") 第一个*返回类型 ..当前包及子包
// 第二个*类,第三个*方法,接下的..任意参数
@Pointcut("execution(* bbs.web.action..B*.*(..))")
private void anyMethod() {
}
@Around("anyMethod()")
public String isLogin(ProceedingJoinPoint jp) throws Throwable {
// TODO Auto-generated method stub
User user = (User) ActionContext.getContext().getSession().get("user");
if (user == null)
return "login";
return (String) jp.proceed();
}
}
使用环绕通知(around advice).拦截BoardAction
这一些操作都比较简单了,第一次运行,出现了没有指定方法的错误,仔细分析后,想起了,有一种AOP是使用接口创建代理对象实现的,但我的BoardAction并没有使用接口编程,于是,将BoardAction中抽取一个接口,让BoardAction实现这个接口.测试后成功,会跳到登录窗口.
同时,又想到,还有一种AOP,是通过子类的方法创建代理对象的,它使用cglib的jar包,上网查了一下,只要在<aop:aspectj-autoproxy proxy-target-class="true" />这个配置中使用proxy-target-class="true" 就可以了,测试成功.
总结:spring默认使用接口创建代理对象实现AOP,如果不使用接口编程,可以使用cglib,通过子类实现AOP,做如上配置即可.
使用cglib用到的jar包 在spring 的 lib/cglib下.
但是当登录成功后,运行addboard.jsp,提交内容后,执行BoardAction的add方法时,出现了错误,大致内容是board.name是空.仔细分析后发现,并没有把addboard.jsp post 到 action的一些参数,映射到BoardAction的private Board board;属性.
上网找了很久很久,没有任何结果.有类似错误的贴子,都没有解决方法.
这里简单分析一下:
Struts2,通过拦截器,拦截到对action的请求,并将其参数映射给action 的成员变量
而Spring通过AOP,创建了一个代理类,它是action的子类,这个子类的名称是随机产生的(通过查看出错信息可以看到,每次出错的类并不一样,前缀就是action的类名)
at bbs.web.action.BoardAction$$EnhancerByCGLIB$$24e41fc4.add(<generated>) 这句是错误信息,通过这个类别就可以明白,这是一个由CGLIB产生的类,它是bbs.web.action.BoardAction的子类,出错是在它的add方法。
not-null property references a null or transient value: bbs.domain.bean.Board.name 这句是错误。
当web client提交信息时,实际上执行到的是action的那个代理类,而不是action本身,而struts2并没有向代理类映射相应的参数值.
如何解决呢?研究中。。。。当然,不用AOP,使用struts2的拦截器也一样可以实现权限控制。