`

Struts2.0中ActionInvocation使用 (转)

    博客分类:
  • SSH
 
阅读更多

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 ,手动分离ActionResult的执行

本来前面的方法已经很好了,可是,可是啊,在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

  • 大小: 40.5 KB
分享到:
评论

相关推荐

    struts2.0源代码

    Struts2.0是Java Web开发中非常重要的一个框架,它是Apache软件基金会的Jakarta项目下的一个产品。这个框架主要用于构建MVC(Model-View-Controller)架构的应用程序,为开发者提供了一种更加灵活和强大的控制层解决...

    struts2.0 经典书籍 源码 标签学习合集

    Struts2.0是Java Web开发中的一款著名MVC框架,它基于Apache的Action和WebWork框架,提供了强大的控制层,使得开发者能够更方便地构建可维护、高性能的Web应用程序。这个压缩包文件包含了关于Struts2.0的经典书籍、...

    Struts2.0框架技术详解

    通过引入第三方验证框架(如Hibernate Validator),可以在Action类中使用注解来实现数据验证。 **示例代码**: ```java public class MyAction { @NotNull(message = "Username cannot be empty") private ...

    struts2.0源码 第2章

    Struts2.0是Java Web开发中非常重要的一个框架,由Apache软件基金会维护。这个框架在第二章的源码分析中,我们将会深入探讨其核心机制和设计模式,特别是李刚版本,它可能是某个特定的讲解或教程版本,强调了作者...

    Struts2.0 开发者突击 第3章

    Struts2.0是Java Web开发中一个非常重要的框架,它是Apache软件基金会的Jakarta项目下的一个开源产品,主要用于构建MVC(Model-View-Controller)架构的应用程序。本章节"Struts2.0开发者突击第3章"将深入探讨其核心...

    struts2.0资料续

    Struts2.0是Java Web开发中非常重要的一个框架,它是Apache软件基金会的Jakarta项目下的一个开源产品,主要用于构建MVC(Model-View-Controller)架构的应用程序。本资料包"struts2.0资料续"显然是针对已经对Struts2...

    Struts2.0拦截器总结

    ### Struts2.0拦截器详解 #### 一、拦截器概述 在Struts2框架中,拦截器(interceptor)是一种非常重要的机制,用于在执行Action前后进行一系列预处理或后处理的操作。拦截器可以用来执行如参数拦截、类型转换、输入...

    struts2.0详细配置文档.doc

    Struts2.0 是一个基于 MVC(Model-View-Controller)设计模式的开源JavaEE框架,用于构建企业级Web应用程序。它的出现是为了改进Struts1的不足,吸收了WebWork框架的优点,提供更加灵活和强大的功能。Struts2 的配置...

    struts 2.0自定义验证器

    在`struts.xml`配置文件中,为需要使用自定义验证器的Action配置相应的验证规则。你可以指定自定义验证器类,并通过`field`元素定义要验证的字段及其验证规则。 4. **使用ActionContext获取数据** 在验证方法中,...

    北大青鸟struts2.0培训基础教程

    在使用Struts2开发应用程序时,首先需要导入必要的JAR包,通常可以从Struts2的下载包中获取。然后,可以创建Action类,定义登录逻辑,并配置struts.xml文件以关联请求和Action。最后,利用Struts2的视图技术(如JSP...

    struts2附快速入门源码

    "struts2.0中文手册"详细阐述了Struts2的配置、插件、拦截器、动态方法调用等方面的知识。其中,配置文件(struts.xml)是整个框架的配置中心,包含了Action、Result、Interceptor的定义。动态方法调用允许开发者以...

    xwork2.0源代码,理解struts2

    这个压缩包包含了XWork 2.0 RC1版本的源代码,对于想要深入理解Struts2工作原理的开发者来说是一份宝贵的资源。 首先,我们需要知道XWork是如何与Struts2协同工作的。在Struts2中,Action是业务逻辑的载体,而XWork...

    struts2-core-2.0.11源码

    10. **注解支持(Annotations)**:从Struts2.1版本开始,框架引入了注解支持,允许开发者在Action类和方法上使用注解进行配置,这部分代码位于`org.apache.struts2.convention.annotation`包中。 在研究源码时,...

    Struts2拦截器登录验证实例

    - 当请求到达Action时,Struts2会按照定义好的拦截器链顺序逐个调用拦截器,每个拦截器都有机会处理请求,直到最后一个拦截器调用`ActionInvocation`的`invoke()`方法,这将执行实际的Action。 2. **创建自定义...

    浅谈Struts2拦截器的原理与实现.docx

    在Struts2应用中,拦截器需要在`struts.xml`配置文件中声明,以决定哪些Action或整个包需要使用哪些拦截器。例如: ```xml &lt;!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration...

    struts2 必要的 5个jar

    在Struts2中,Freemarker被用作默认的视图技术,允许开发者使用模板语言来设计用户界面,将数据模型与页面展示逻辑分离。开发者可以利用Freemarker的灵活性和表达力来创建复杂和可重用的视图模板。 3. **xwork-...

    Struts2的结构和编写过程笔记

    - Struts2.0内置了对Ajax的支持,简化了前端开发。 #### Struts2的架构 - **JSP**: 结合HTML、JavaScript、CSS和简单的Java语句以及标签,用于构建用户界面。 - **POJO**: 与表单数据对应的传输对象,即使没有...

    Struts2.1+Spring3.0+JPA1.0 .pdf

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"&gt; &lt;struts&gt; &lt;constant name="struts.devMode" value="true"/&gt; ...

    xwork2.0源码

    - **OGNL表达式解析**:了解OGNL的语法和特性,以及如何在Struts2中使用它。 总之,分析XWork2.0.7源码对于理解Struts2的工作原理至关重要。通过深入研究,开发者可以更好地掌握Web应用程序的开发技巧,提高开发...

    struts2相关

    例如,在 2.0 版本中,使用的是 `org.apache.struts2.dispatcher.FilterDispatcher`;而在更新的版本中,则推荐使用 `org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter`。 #### 三、Struts2...

Global site tag (gtag.js) - Google Analytics