在Struts中基于Spring的AOP MethodInterceptor(拦截器)的权限验证
本程序是关于"某考试系统"中的aop应用.说实话,aop在spring应该算是个难点,它主是起到了"代理"的作用,aop会为你调用的方法的对象生成代理,这个代理是继承调用MethodInterceptor这个拦截器的对象的,所以,具备原有对象的所有方法与特性.AOP不神秘,它就是EJB的进化,只是EJB需要显式的实现接口,而AOP不用,它会自动帮你生成代理,来做很多事情,AOP,我觉得它在处理事务的时候用的比较多所谓声明式的事务就是由此而来.
当系统管理员进行后台管理或考生前台进行考试时,提交的请求都交给系统的控制器处理.例如在struts-config.xml文件中并未配置Action的实现类,仅仅配置了每个Action的url以及对应的局部forward映射.
所有的Action都交给Spring容器进行管理,用户请求发送到ActionServlet后,ActionServlet将请求转发到Spring容器里的控制器.Spring的AOP魔法发生在这个地方,当ActionServlet将请求发送到控制器时,并不是转给程序员实现的控制器,而是转给了控制器代理-------------控制器代理会先执行权限检查,如果用户已经登录,回调程序员实现的控制器,否则直接进入登录页面.
部分源代码如下
publicclassAuthorityInterceptorimplementsMethodInterceptor
{
publicObjectinvoke(MethodInvocationinvocation)throwsThrowable
{
HttpServletRequestrequest=null;
ActionMappingmapping=null;
Object[]args=invocation.getArguments();
for(inti=0;i<args.length;i++)
{
if(args[i]instanceofHttpServletRequest)request=(HttpServletRequest)args[i];
if(args[i]instanceofActionMapping)mapping=(ActionMapping)args[i];
}
Objectadmin=request.getSession().getAttribute("admin");
if(admin!=null&&((String)admin).equals("admin"))
{
returninvocation.proceed();
}
else
{
request.setAttribute("msg","您还没有登录,请先登录");
returnmapping.findForward("admin");
}
}
}
该应用是在*.xml中来调用的..(用struts的mvc,然后托管给spring的ioc容器来管理的,配置也是由spring来处理的)
<beanclass="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<propertyname="beanNames">
<list>
<value>/processAddStudent</value>
<value>/listStudent</value>
<value>/delStudent</value>
<value>/processAddTest</value>
<value>/addQuestion</value>
<value>/delQuestion</value>
<value>/processAddQuestion</value>
</list>
</property>
<propertyname="interceptorNames">
<list>
<value>authorityInterceptor</value>
</list>
</property>
</bean>
<beanid="authorityInterceptor"class="org.yeeku.action.authority.AuthorityInterceptor"/>
//解释后的代码
publicclassAuthorityInterceptorimplementsMethodInterceptor
{
publicObjectinvoke(MethodInvocationinvocation)throwsThrowable
{
HttpServletRequestrequest=null;
ActionMappingmapping=null;
-----------注解1开始
通过invocation.getArguments()可以获取代理对象的参数
代理的参数是ActionMapping,ActionForm,HttpServletRequest,HttpServletResponse四个
只不过,这里根据实际情况,我们只需要使用HttpServletRequest,ActionMapping罢了
因为这里你要通过request获取session和通过mapping跳转页面
因为Object[]args=invocation.getArguments();规定,返回的必须是一个数组
所以,没办法,只能迭代把要用的找出来
而我们在XML配置的对象都是StrutsAction
每一个StrutsAction方法都形如这样,
publicActionForwardaddBlog(ActionMappingmapping,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)
所以,通过
for(inti=0;i<args.length;i++)
{
if(args[i]instanceofHttpServletRequest)request=(HttpServletRequest)args[i];
if(args[i]instanceofActionMapping)mapping=(ActionMapping)args[i];
}
可以从那里迭代出来
你既然都有调用Struts了,mapping,form,request,response肯定都已经注入了,咱们运行Struts,是在mapping,form,request,
response都具备的情况下,使用的
所以,Object[]args=invocation.getArguments();
得到应该对象的所有参数是完全可以的
--------注解1结束
Object[]args=invocation.getArguments();
---------加这两句是因为要通过request获取session并且在判断没有权限的时候要通过mapping跳转页面
for(inti=0;i<args.length;i++)
{
if(args[i]instanceofHttpServletRequest)request=(HttpServletRequest)args[i];
if(args[i]instanceofActionMapping)mapping=(ActionMapping)args[i];
}
Objectadmin=request.getSession().getAttribute("admin");
----------
如果权限有问题,
那么invocation.procceed()就不会执行,意味着你的那个Action对象**方法也不会执行,但此时
mapping是存在的,来一下findForward("admin");
----------
if(admin!=null&&((String)admin).equals("admin"))
{
returninvocation.proceed();
}
else
{
request.setAttribute("msg","您还没有登录,请先登录");
returnmapping.findForward("admin");
}
}
}