Interceptor说明
Interceptor的接口定义没有什么特别的地方,除了init和destory方法以外,intercept方法是实现整个拦截器机制的核心方法。而它所依赖的参数ActionInvocation则是我们之前章节中曾经提到过的著名的Action调度者。
我在这里需要指出的是一个很重要的方法invocation.invoke()。这是ActionInvocation中的方法,而ActionInvocation是Action调度者,所以这个方法具备以下2层含义(详细看DefaultActionInvocation源代码):
1. 如果拦截器堆栈中还有其他的Interceptor,那么invocation.invoke()将调用堆栈中下一个Interceptor的执行。
2. 如果拦截器堆栈中只有Action了,那么invocation.invoke()将调用Action执行。
3.
DefaultActionInvocation部分源代码:
if (interceptors.hasNext()) { final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next(); UtilTimerStack.profile("interceptor: "+interceptor.getName(), new UtilTimerStack.ProfilingBlock<String>() { public String doProfiling() throws Exception { resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);//递归调用拦截器 return null; } }); } else { resultCode = invokeActionOnly(); }
每个拦截器中的代码的执行顺序,在Action之前,拦截器的执行顺序与堆栈中定义的一致;而在Action和Result之后,拦截器的执行顺序与堆栈中定义的顺序相反。
Interceptor拦截类型
从上面的分析,我们知道,整个拦截器的核心部分是invocation.invoke()这个函数的调用位置。事实上,我们也正式根据这句代码的调用位置,来进行拦截类型的区分的。在Struts2中,Interceptor的拦截类型,分成以下三类:
1. before
before拦截,是指在拦截器中定义的代码,它们存在于invocation.invoke()代码执行之前。这些代码,将依照拦截器定义的顺序,顺序执行。
2. after
after拦截,是指在拦截器中定义的代码,它们存在于invocation.invoke()代码执行之后。这些代码,将依照拦截器定义的顺序,逆序执行。
3、 PreResultListener
有的时候,before拦截和after拦截对我们来说是不够的,因为我们需要在Action执行完之后,但是还没有回到视图层之前,做一些事情。Struts2同样支持这样的拦截,这种拦截方式,是通过在拦截器中注册一个PreResultListener的接口来实现的。
如:在拦截器中使用如下代码,其中MyPreResultListener实现了PreResultListener 接口并在beforeResult方法中做了一些事情然后在拦截器类中加入action.addPreResultListener(new MyPreResultListener());
从源码中,我们可以看到,我们之前提到的Struts2的Action层的4个不同的层次,在这个方法中都有体现,他们分别是:拦截器(Interceptor)、Action、PreResultListener和Result。在这个方法中,保证了这些层次的有序调用和执行。
问题
使用Struts2作为web框架,知道它的拦截器(Interceptor)机制,类似与Filter和Spring的AOP,于是实现了一个为Action增加自定义前置(before)动作和后置动作(after)的拦截器(曰:WInterceptor),不过用一段时间发现,在WInterceptor的after中,对Action对象的属性修改在页面看不到,对请求对象的属性设置也无效。为什么在调用了Action之后(invokeAction())之后,request就不能使用了呢,拦截器不能改变Action的Result么?
问题的关键在于,在调用actionInvocation.invoke()的之后,不仅执行类Action,也执行类Result。因而,等退回到拦截器的调用代码时,Result已经生成,View已经确定,这时你再修改模型(Action的属性)或请求对象的属性,对视图不会有任何影响。
解决办法:
方法一:使用现成的PreResultListener监听器事件
搞清楚原因,卷起袖子干吧,只要让WInterpretor的after事件,放在Result的生成之前就行了。
看看XWork的拦截器接口注入的actionInvocation,其实就提供增加Result执行的前置监听事件-PreResultListener:
/** * Register a {@link PreResultListener} to be notified after the Action is executed and * before the Result is executed. * <p/> * The ActionInvocation implementation must guarantee that listeners will be called in * the order in which they are registered. * <p/> * Listener registration and execution does not need to be thread-safe. * * @param listener the listener to add. */ void addPreResultListener(PreResultListener listener);
因此,让拦截器实现这个接口,就可以自然实现Action执行after事件了。
方法二,实现自己的 ActionInvocation ,手动分离Action和Result的执行
本来前面的方法已经很好了,可是,可是啊,在addPreResultListener里的异常,不会被Struts的框架捕获,而且,addPreResultListener接口不能传递自己的上下文参数,难道动用ThreadLocal传参?
研究了一下XWork的ActionInvocation 接口默认实现类DefaultActionInvocation, 写了一个包装类,将Action的执行和Result的生成完全分开,或许有人用的着,放上来,见附件(ActionInvocationWrapper),如有不妥之处请告知。
exeucteAction是执行Action,executeResult是执行Result
转载地址:http://www.cnblogs.com/leBeauty/archive/2012/09/27/2705932.html
相关推荐
Struts2.0是Java Web开发中非常重要的一个框架,它是Apache软件基金会的Jakarta项目下的一个产品。这个框架主要用于构建MVC(Model-View-Controller)架构的应用程序,为开发者提供了一种更加灵活和强大的控制层解决...
Struts2.0是Java Web开发中的一款著名MVC框架,它基于Apache的Action和WebWork框架,提供了强大的控制层,使得开发者能够更方便地构建可维护、高性能的Web应用程序。这个压缩包文件包含了关于Struts2.0的经典书籍、...
通过引入第三方验证框架(如Hibernate Validator),可以在Action类中使用注解来实现数据验证。 **示例代码**: ```java public class MyAction { @NotNull(message = "Username cannot be empty") private ...
Struts2.0是Java Web开发中非常重要的一个框架,由Apache软件基金会维护。这个框架在第二章的源码分析中,我们将会深入探讨其核心机制和设计模式,特别是李刚版本,它可能是某个特定的讲解或教程版本,强调了作者...
Struts2.0是Java Web开发中一个非常重要的框架,它是Apache软件基金会的Jakarta项目下的一个开源产品,主要用于构建MVC(Model-View-Controller)架构的应用程序。本章节"Struts2.0开发者突击第3章"将深入探讨其核心...
Struts2.0是Java Web开发中非常重要的一个框架,它是Apache软件基金会的Jakarta项目下的一个开源产品,主要用于构建MVC(Model-View-Controller)架构的应用程序。本资料包"struts2.0资料续"显然是针对已经对Struts2...
### Struts2.0拦截器详解 #### 一、拦截器概述 在Struts2框架中,拦截器(interceptor)是一种非常重要的机制,用于在执行Action前后进行一系列预处理或后处理的操作。拦截器可以用来执行如参数拦截、类型转换、输入...
Struts2.0 是一个基于 MVC(Model-View-Controller)设计模式的开源JavaEE框架,用于构建企业级Web应用程序。它的出现是为了改进Struts1的不足,吸收了WebWork框架的优点,提供更加灵活和强大的功能。Struts2 的配置...
在`struts.xml`配置文件中,为需要使用自定义验证器的Action配置相应的验证规则。你可以指定自定义验证器类,并通过`field`元素定义要验证的字段及其验证规则。 4. **使用ActionContext获取数据** 在验证方法中,...
在使用Struts2开发应用程序时,首先需要导入必要的JAR包,通常可以从Struts2的下载包中获取。然后,可以创建Action类,定义登录逻辑,并配置struts.xml文件以关联请求和Action。最后,利用Struts2的视图技术(如JSP...
"struts2.0中文手册"详细阐述了Struts2的配置、插件、拦截器、动态方法调用等方面的知识。其中,配置文件(struts.xml)是整个框架的配置中心,包含了Action、Result、Interceptor的定义。动态方法调用允许开发者以...
这个压缩包包含了XWork 2.0 RC1版本的源代码,对于想要深入理解Struts2工作原理的开发者来说是一份宝贵的资源。 首先,我们需要知道XWork是如何与Struts2协同工作的。在Struts2中,Action是业务逻辑的载体,而XWork...
10. **注解支持(Annotations)**:从Struts2.1版本开始,框架引入了注解支持,允许开发者在Action类和方法上使用注解进行配置,这部分代码位于`org.apache.struts2.convention.annotation`包中。 在研究源码时,...
- 当请求到达Action时,Struts2会按照定义好的拦截器链顺序逐个调用拦截器,每个拦截器都有机会处理请求,直到最后一个拦截器调用`ActionInvocation`的`invoke()`方法,这将执行实际的Action。 2. **创建自定义...
在Struts2应用中,拦截器需要在`struts.xml`配置文件中声明,以决定哪些Action或整个包需要使用哪些拦截器。例如: ```xml <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration...
在Struts2中,Freemarker被用作默认的视图技术,允许开发者使用模板语言来设计用户界面,将数据模型与页面展示逻辑分离。开发者可以利用Freemarker的灵活性和表达力来创建复杂和可重用的视图模板。 3. **xwork-...
- Struts2.0内置了对Ajax的支持,简化了前端开发。 #### Struts2的架构 - **JSP**: 结合HTML、JavaScript、CSS和简单的Java语句以及标签,用于构建用户界面。 - **POJO**: 与表单数据对应的传输对象,即使没有...
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.devMode" value="true"/> ...
- **OGNL表达式解析**:了解OGNL的语法和特性,以及如何在Struts2中使用它。 总之,分析XWork2.0.7源码对于理解Struts2的工作原理至关重要。通过深入研究,开发者可以更好地掌握Web应用程序的开发技巧,提高开发...
例如,在 2.0 版本中,使用的是 `org.apache.struts2.dispatcher.FilterDispatcher`;而在更新的版本中,则推荐使用 `org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter`。 #### 三、Struts2...