锁定老帖子 主题:struts2 拦截器
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-07-21
引用 默认的的拦截器栈被设计成能满足大部分应用的需要,所以不再需要添加新的拦截器或更改拦截器栈。
不同的action可能有不同的关注点, 一些action需要表单验证,一些action需要文件上传功能,一些action需要防止双重提交……struts框架使用“Interceptor”策略使得解决这些关注点变得容易。 理解拦截器 在action执行前后interceptor都要被执行。框架的大部分核心功能(包括类型转化,防止双重提交等……)都是借助拦截器来实现的。 所有的拦截器都是插件式的,你可以为你的action精确的设置需要的拦截器。 action生命周期 配置拦截器 <package name="default" extends="struts-default"> <interceptors> <interceptor name="timer" class=".."/> <interceptor name="logger" class=".."/> </interceptors> <action name="login" class="tutorial.Login"> <interceptor-ref name="timer"/> <interceptor-ref name="logger"/> <result name="input">login.jsp</result> <result name="success" type="redirect-action">/secure/home</result> </action> </package> 拦截器栈 在大部分web程序中,我们发现需要屡次使用相同的拦截器序列。 此时, 我们可以把这些拦截器序列绑定为一个拦截器栈,而无需重申这些拦截器列表。 <package name="default" extends="struts-default"> <interceptors> <interceptor name="timer" class=".."/> <interceptor name="logger" class=".."/> <interceptor-stack name="myStack"> <interceptor-ref name="timer"/> <interceptor-ref name="logger"/> </interceptor-stack> </interceptors> <action name="login" class="tutuorial.Login"> <interceptor-ref name="myStack"/> <result name="input">login.jsp</result> <result name="success" type="redirect-action">/secure/home</result> </action> </package> 几个重要的拦截器 在struts配置文件中,拦截器类被定义为键值对的形式。 拦截器的名字在 struts-default.xml中都进行了定义,如果你继承了 struts-default.xml包,后面的操作你可以通过引用来使用拦截器;如果没有继承struts-default.xml,你需要在<interceptors>中指定名字和名字对应的拦截器类来引用拦截器。
从2.0.7版本后拦截器和Result中含有的连字符号都被转化为来骆驼格式。 如:(model-driven 被转化为modelDriven)。 直到Struts 2.1.0, 原有的连字符号格式以别名的形式仍被使用。 方法过滤 覆写拦截器参数 一个抽象的过滤器被用于过滤方法的名字。 excludeMethods : 不被包含的方法的名字。 includeMethods : 包含的方法的名字。 如果方法的名字在excludeMethods和includeMethods都适合, 那么将包含方法的名字, includeMethods比excludeMethods的 优先级高。 方法1 <action name="myAction" class="myActionClass"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="params"/> <interceptor-ref name="servlet-config"/> <interceptor-ref name="prepare"/> <interceptor-ref name="i18n"/> <interceptor-ref name="chain"/> <interceptor-ref name="model-driven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="static-params"/> <interceptor-ref name="params"/> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">myValidationExcudeMethod</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">myWorkflowExcludeMethod</param> </interceptor-ref> </action> 方法2 <action name="myAction" class="myActionClass"> <interceptor-ref name="defaultStack"> <param name="validation.excludeMethods">myValidationExcludeMethod</param> <param name="workflow.excludeMethods">myWorkflowExcludeMethod</param> </interceptor-ref> </action> 拦截器的执行顺序 拦截器提供了一种对处理前后进行包装的思想, 这种观念大大减少了代码副本。(参考AOP) <interceptor-stack name="xaStack"> <interceptor-ref name="thisWillRunFirstInterceptor"/> <interceptor-ref name="thisWillRunNextInterceptor"/> <interceptor-ref name="followedByThisInterceptor"/> <interceptor-ref name="thisWillRunLastInterceptor"/> </interceptor-stack> 一些拦截器有可能会打断执行流程,因此拦截器的顺序也是很重要的 。 另, 实现了com.opensymphony.xwork2.interceptor.PreResultListener 的拦截器将在Action执行之后和Result返回之前调用。 thisWillRunFirstInterceptor thisWillRunNextInterceptor followedByThisInterceptor thisWillRunLastInterceptor MyAction1 MyAction2 (chain) MyPreResultListener MyResult (result) thisWillRunLastInterceptor followedByThisInterceptor thisWillRunNextInterceptor thisWillRunFirstInterceptor 自定义拦截器 自定义拦截器必须实现 com.opensymphony.xwork2.interceptor.Interceptor public interface Interceptor extends Serializable { void destroy(); void init(); String intercept(ActionInvocation invocation) throws Exception; } 在拦截器被实例化之后和 intercept方法被调用之前 执行init方法。 此方法用来初始化拦截器需要的资源。 拦截器的主体代码写在intercept中, 和action类似, intercept返回一个result, result被struts2用于将请求转发到另一个资源,调用ActionInvocation 中的invoke 方法以执行action (如果是最后一个拦截器)或调用另一个拦截器。 在result被调用之后方法才返回, 这种情况适合open-session-in-view模式。 如果你想在result被调用之前做一些事情,你必须实现PreResultListener。 拦截器必须是线程安全的 对于struts2, 每个请求都会实例化一个action, 所以action不需要线程安全。 但是, 拦截器会在请求之间共享,所以, 拦截器必须线程安全。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-09-04
一个小问题,要是我在每个action中都要使用同一个Intercepter,那我岂不是要在每个action中配置拦截器,所有怎样在struts.xml配置一个全局的Intercepter????
|
|
返回顶楼 | |
发表时间:2008-09-05
其实struts有个自己默认的Interceptor拦截器设置。这些基本设置一般都能够满足项目需求了。
具体的参看xwork.jar包中的xwork-default.xml文件。 |
|
返回顶楼 | |
发表时间:2008-09-05
引用 smallsnake 21 小时前
一个小问题,要是我在每个action中都要使用同一个Intercepter,那我岂不是要在每个action中配置拦截器,所有怎样在struts.xml配置一个全局的Intercepter???? 可以在package中设置默认的拦截器: <default-interceptor-ref name="normal" /> 之后,在action中会自动调用。 例: <package name="manage-project-default" extends="manage-default" namespace="/project"> <default-interceptor-ref name="normal" /> ... |
|
返回顶楼 | |
发表时间:2008-09-05
引用 popbao_haha 9 小时前
其实struts有个自己默认的Interceptor拦截器设置。这些基本设置一般都能够满足项目需求了。 具体的参看xwork.jar包中的xwork-default.xml文件。 关于拦截器的默认配置文件: xwork-2.0.4.jar : xwork-default.xml struts2-core-2.0.9 : struts-default.xml webwork-2.2.6 : webwork-default.xml |
|
返回顶楼 | |
发表时间:2009-02-05
拦截器会在请求之间共享,所以,
拦截器必须线程安全。 我想问下,拦截器是每个action一个实例,还是整个应用一个实例? 例如: 拦截器A, 在a这个action和b这个action上都有配置,那么,是A这个拦截器对于a和b都有单独的实例,还是a和b都是同一个实例(整个应用一个实例) |
|
返回顶楼 | |
发表时间:2009-02-06
当然是不同的实例了,每一个请求都有actioncontext 不同
|
|
返回顶楼 | |
发表时间:2009-02-06
拦截器应该是单例的吧。。。
|
|
返回顶楼 | |
发表时间:2009-02-06
kjj 写道 当然是不同的实例了,每一个请求都有actioncontext 不同
每个actioncontext是放在ThreadLocal里的,当然是每次都有。 而拦截器并不是。所以我才这样问的。 |
|
返回顶楼 | |
发表时间:2009-02-06
其实我看过struts2的源码,是整个应用中一个实例,但是我比较不解的是,如果是这样,那通过param设置的静态值不是有并发问题。
所以报着这个疑问来问这个问题。 |
|
返回顶楼 | |