【struts基础】Struts2的拦截器

来源:互联网 发布:手机防辐射软件 编辑:程序博客网 时间:2024/06/06 17:52

  拦截器的定义:


       在访问某个Action或者Action的某个方法的时候,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现。


 拦截器栈的定义:


       Struts2拦截器栈就是拦截器按一定的顺序联结成一条链,在访问被拦截方法或者字段的时候,struts2拦截器链中的拦截器就会按其之前的顺序被调用。


拦截器的原理:


       当请求到达ServletDispatcher的时候,Struts2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表list,最后一个个的调用列表中的拦截器。这些都是由于动态代理的使用。动态代理是代理对象根据客户的需求做出不同的处理,对于客户来说,只要知道一个代理对象即可。当Action请求到来的时候,会由系统的代理生成一个Action的代理对象,由这个代理对象调用Action的execute或者指定的方法,并在struts.xml中查找与该Action对应的拦截器,如果有对应的拦截器,就在Action的方法执行前或者后调用这些拦截器,如果没有对应的拦截器则执行Action的方法,其中拦截器的调用是通过ActionInvocation来实现的。


     Struts2的拦截器的具体配置文件在struts-default.xml,比如上传文件的拦截器、国际化的拦截器等等,请见以下struts2-core的jar包的文件。


    拦截器和Action并没有直接的发生关联,完全是通过代理组织与Action协同工作的。


   接口Interceptor中仅仅有三个方法,分别是destroy、init、和核心方法intercept。


例子:

     在登录中判断权限,使用拦截器,


     首先在struts.xml中配置声明拦截器,并且加上全局的配置。代码如下:


<interceptors><!-- 声明一个拦截器 --><interceptor name="checkePrivilege" class="cn.itcast.oa.interceptor.CheckPrivilegeInterceptor"></interceptor><!-- 重新定义defaultStack拦截器栈,需要先判断权限 --><interceptor-stack name="defaultStack"><interceptor-ref name="checkePrivilege" /><interceptor-ref name="defaultStack" /></interceptor-stack></interceptors><!-- 配置全局的Result --><global-results><result name="loginUI">/WEB-INF/jsp/userAction/loginUI.jsp</result><result name="noPrivilegeError">/noPrivilegeError.jsp</result></global-results>

     具体实现是继承AbstractInterceptor,判断权限的代码:


 

package cn.itcast.oa.interceptor;import cn.itcast.oa.domain.User;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.AbstractInterceptor;public class CheckPrivilegeInterceptor extends AbstractInterceptor {public String intercept(ActionInvocation invocation) throws Exception {// System.out.println("-----> 之前");// String result = invocation.invoke(); // 放行// System.out.println("-----> 之后");// return result;// 获取当前用户User user = (User) ActionContext.getContext().getSession().get("user");// 获取当前访问的URL,并去掉当前应用程序的前缀(也就是 namespaceName + actionName )String namespace = invocation.getProxy().getNamespace();String actionName = invocation.getProxy().getActionName();String privilegeUrl = null;if (namespace.endsWith("/")) {privilegeUrl = namespace + actionName;} else {privilegeUrl = namespace + "/" + actionName;}// 要去掉开头的'/'if (privilegeUrl.startsWith("/")) {privilegeUrl = privilegeUrl.substring(1);}// 如果未登录用户if (user == null) {if (privilegeUrl.startsWith("userAction_login")) { // userAction_login, userAction_loginUI// 如果是正在使用登录功能,就放行return invocation.invoke();} else {// 如果不是去登录,就转到登录页面return "loginUI";}}// 如果已登录用户(就判断权限)else {if (user.hasPrivilegeByUrl(privilegeUrl)) {// 如果有权限,就放行return invocation.invoke();} else {// 如果没有权限,就转到提示页面return "noPrivilegeError";}}}}

      这样就可以轻松的在登录的时候实现权限问题了。