struts拦截器

来源:互联网 发布:高清影视下载软件 编辑:程序博客网 时间:2024/06/06 05:09
Struts2的拦截器的实现原理
Struts2的设计者们把共有的逻辑独立出来,实现成一个个拦截器,既体现了软件复用的思想,又方便程序员使用。 Struts2中提供了大量的拦截器,多个拦截器可以组成一个拦截器栈,系统为我们配置了一个默认的拦截器栈 defaultStack,具体包括那些拦截器以及他们的顺序可以在 Struts2的开发包的 struts-default.xml中找到。在每次对你的 Action的 execute()方法请求时,系统会生成一个 ActionInvocation对象,这个对象保存了 action和你所配置的所有的拦截器以及一些状态信息。比如你的应用使用的是 defaultStack,系统将会以拦截器栈配置的顺序将每个拦截器包装成一个个 InterceptorMapping(包含拦截器名字和对应的拦截器对象 )组成一个 Iterator保存在 ActionInvocation中。在执行 ActionInvocation的 invoke()方法时会对这个 Iterator进行迭代,每次取出一个 InterceptorMapping,然后执行对应 Interceptor的 intercept(ActionInVocation inv)方法,而 intercept(ActionInInvocation inv)方法又包含当前的 ActionInInvcation对象作为参数,而在每个拦截器中又会调用 inv的 invoke()方法,这样就会进入下一个拦截器执行了,这样直到最后一个拦截器执行完,然后执行 Action的 execute()方法 (假设你没有配置访问方法,默认执行 Action的 execute()方法 )。在执行完 execute()方法取得了 result后又以相反的顺序走出拦截器栈,这时可以做些清理工作。最后系统得到了一个 result,然后根据 result的类型做进一步操作。Struts2的拦截器的实现原理和过滤器的实现差不多,对你真正想执行的 execute()方法进行拦截,然后插入一些自己的逻辑。如果没有拦截器,这些要插入的逻辑就得写在你自己的 Action实现中,而且每个 Action实现都要写这些功能逻辑,这样的实现非常繁琐。而 Struts2的设计者们把这些共有的逻辑独立出来,实现成一个个拦截器,既体现了软件复用的思想,又方便程序员使用。 Struts2中提供了大量的拦截器,多个拦截器可以组成一个拦截器栈,系统为我们配置了一个默认的拦截器栈 defaultStack,具
体包括那些拦截器以及他们的顺序可以在 Struts2的开发包的 struts-default.xml中找到。在每次对你的 Action的 execute()方法请求时,系统会生成一个 ActionInvocation对象,这个对象保存了 action和你所配置的所有的拦截器以及一些状态信息。比如你的应用使用的是 defaultStack,系统将会以拦截器栈配置的顺序将每个拦截器包装成一个个 InterceptorMapping(包含拦截器名字和对应的拦截器对象 )组成一个 Iterator保存在 ActionInvocation中。在执行 ActionInvocation的 invoke()方法时会对这个 Iterator进行迭代,每次取出一个 InterceptorMapping,然后执行对应 Interceptor的 intercept(ActionInVocation inv)方法,而 intercept(ActionInInvocation inv)方法又包含当前的 ActionInInvcation对象作为参数,而在每个拦截器中又会调用 inv的 invoke()方法,这样就会进入下一个拦截器执行了,这样直到最后一个拦截器执行完,然后执行 Action的 execute()方法 (假设你没有配置访问方法,默认执行 Action的 execute()方法 )。在执行完 execute()方法取得了 result后又以相反的顺序走出拦截器栈,这时可以做些清理工作。最后系统得到了一个 result,然后根据 result的类型做进一步操作。

配置中常出现错误
“The content of element type "package" must match "(result-types?,interceptors?,default-interceptor-ref?,default-action-ref?,default-class-ref?,global-results?,global-exception-mappings?,action*)". ”
这个错误的意思是,package里元素必须按照一定的顺序排列。这个顺序就是
result-types
interceptors
default-interceptor-ref
default-action-ref
default-class-ref
global-results
global-exception-mappings
action*(就是所有的action放到最后)

xml文件配置
<!-- 拦截为登陆用户 -->
<interceptors>
<interceptor name="checklogin" class="com.farm.util.CheckLoginInterceptor" />
<interceptor-stack name="interceptorStack">
<interceptor-ref name="checklogin" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="interceptorStack" />

               <!--配置一个全局变量用于接收拦截器传来的参数-->
                <global-results>
<result name="exception-error">/errors/error.jsp</result>
<result name="login-error">/login.jsp</result>
</global-results>
                拦截器

如何自定义一个拦截器?

自定义一个拦截器需要三步:

1 自定义一个实现Interceptor接口(或者继承自AbstractInterceptor)的类。

2 在strutx.xml中注册上一步中定义的拦截器。

3 在需要使用的Action中引用上述定义的拦截器,为了方便也可将拦截器定义为默认的拦截器,这样在不加特殊声明的情况下所有的Action都被这个拦截器拦截。

 

Interceptor接口声明了三个方法:

 

public interface Interceptor extends Serializable {

 

    void destroy();

 

    void init();

 

    String intercept(ActionInvocation invocation) throws Exception;

}

 

Init方法在拦截器类被创建之后,在对Action镜像拦截之前调用,相当于一个post-constructor方法,使用这个方法可以给拦截器类做必要的初始话操作。

 

Destroy方法在拦截器被垃圾回收之前调用,用来回收init方法初始化的资源。

 

Intercept是拦截器的主要拦截方法,如果需要调用后续的Action或者拦截器,只需要在该方法中调用invocation.invoke()方法即可,在该方法调用的前后可以插入Action调用前后拦截器需要做的方法。如果不需要调用后续的方法,则返回一个String类型的对象即可,例如Action.SUCCESS。

另外AbstractInterceptor提供了一个简单的Interceptor的实现,这个实现为:

public abstract class AbstractInterceptor implements Interceptor {

 

     public void init() {

    }

   

    public void destroy() {

    }

 

 

    public abstract String intercept(ActionInvocation invocation) throws Exception;

}

在不需要编写init和destroy方法的时候,只需要从AbstractInterceptor继承而来,实现intercept方法即可。



package com.farm.util;
import java.util.Map;
import com.farm.action.ApplyOrPassOrRefuse;
import com.farm.action.CheckUserAction;
import com.farm.action.LoginAction;
import com.farm.action.RegisterAction;
import com.farm.model.UserBean;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class CheckLoginInterceptor extends AbstractInterceptor {
public static final String LOGIN_KEY = "user";
public static final String LOGIN_PAGE = "login-error";


public String intercept(ActionInvocation actionInvocation) throws Exception {
Object action = actionInvocation.getAction();

if (action instanceof LoginAction
|| action instanceof RegisterAction)
return actionInvocation.invoke();


// 对LoginAction不做该项拦截

Map<String, Object> session = actionInvocation.getInvocationContext()
.getSession();
UserBean user = (UserBean) session.get(LOGIN_KEY);
if (user == null
|| (action instanceof ApplyOrPassOrRefuse && !user.getType()
.equals("核销审查员"))
|| (action instanceof CheckUserAction && !user.getType()
.equals("系统管理员")))
return LOGIN_PAGE;
else
return actionInvocation.invoke();
}
}


0 0
原创粉丝点击