`

struts2的拦截器 和actionInvocation解释(转载)

 
阅读更多

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()代码执行之后。这些代码,将一招拦截器定义的顺序,逆序执行

 

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:

Java代码 复制代码 收藏代码
  1.   
  2. void addPreResultListener(PreResultListener listener);  

void addPreResultListener(PreResultListener listener);

 

因此,让拦截器实现这个接口,就可以自然实现Action执行after事件了。

 

 

方法二,实现自己的 ActionInvocation ,手动分离Action和Result的执行

本来前面的方法已经很好了,可是,可是啊,在addPreResultListener里的异常,不会被Struts的框架捕获,而且,addPreResultListener接口不能传递自己的上下文参数,难道动用ThreadLocal传参?

 

研究了一下XWork的ActionInvocation 接口默认实现类DefaultActionInvocation,写了一个包装类,将Action的执行和Result的生成完全分开,或许有人用的着,放上来,见附件(ActionInvocationWrapper),如有不妥之处请告知。

 

exeucteAction是执行Action,executeResult是执行Resul

分享到:
评论

相关推荐

    Struts2拦截器及其用法详细说明

    在Struts2中,拦截器(Interceptors)扮演着核心角色,增强了框架的功能和灵活性。这篇文章将深入探讨Struts2拦截器的概念、工作原理以及如何在实际应用中使用它们。 **一、什么是Struts2拦截器** 拦截器是基于AOP...

    Struts2拦截器源程序

    分析这个文件或目录可以帮助我们更深入地理解Struts2拦截器的内部工作机制,包括它如何与ActionInvocation交互,以及如何处理请求和响应。 总结来说,Struts2拦截器是框架的核心部分,它们提供了一种灵活的方式,以...

    struts2拦截器的使用方法

    ### Struts2拦截器的使用方法 #### 一、Struts2拦截器概述 Struts2框架中的拦截器(Interceptor)是一种重要的机制,用于在Action执行前后进行一系列处理,比如参数验证、数据预处理等。它能够帮助开发者更加灵活...

    struts2拦截器应用小例子

    这个"struts2拦截器应用小例子"可能包含了一个简单的拦截器实现,展示了如何在实际项目中集成和使用。通过这个例子,你可以学习到如何创建、注册拦截器,以及如何在Struts2框架中构建拦截器栈,从而更灵活地管理应用...

    Struts2拦截器源码

    Struts2是一个强大的MVC(模型...通过理解和研究Struts2的拦截器源码,我们可以更好地利用这个强大工具,提高应用的可扩展性和灵活性。同时,这也为我们提供了对Struts2框架内部运作的深入了解,有助于优化和调试代码。

    Struts2 拦截器 和 Java 中的动态代理

    在Struts2中,ActionInvocation接口代表了Action的执行过程,它可以被视为一个简单的调用栈,每个拦截器都是栈上的一个元素。当调用`invoke()`方法时,会按顺序执行这些拦截器,直到到达Action。这个设计模式与Java...

    struts2拦截器实现拦截不文明字迹

    Struts2是一个强大的MVC(模型...总结起来,通过使用Struts2拦截器,我们可以高效地实现对不文明字迹的拦截,提高应用的安全性和用户体验。同时,结合合理的配置和自定义验证,我们可以构建出健壮且灵活的Web应用程序。

    使用struts2拦截器对登陆权限验证

    结合使用Struts2拦截器和Servlet Filter,我们可以构建出强大的权限验证机制。拦截器适用于Action级别的控制,而Filter则可以全局拦截所有请求,两者相辅相成,确保只有已登录用户才能访问受保护的资源。 在提供的`...

    struts2拦截器和验证框架(适合初学者-经藏版)

    通过以上详细介绍,我们了解了Struts2中的拦截器和验证框架的基本概念、如何创建自定义拦截器以及如何配置拦截器和使用验证功能。这些知识点对于初学者来说非常重要,能够帮助他们更好地理解和使用Struts2框架。

    struts2拦截器国际化

    在Struts2中,拦截器(Interceptor)是实现业务逻辑控制和增强功能的重要机制,而国际化(Internationalization,简称i18n)则能帮助我们构建支持多语言的Web应用。下面将详细解释这两个知识点以及它们如何在Struts2...

    创建自己struts2拦截器

    Struts2是一个强大的MVC框架,它通过使用拦截器(Interceptor)来实现业务逻辑与表现层的解耦,提供了一种灵活的扩展机制。在Struts2中,拦截器是AOP(面向切面编程)的一种实现,它可以监控、修改或增强方法调用的...

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

    Struts2 拦截器是Struts2框架的核心组件之一,它允许开发者在Action执行前后插入自定义的处理逻辑,实现对请求的预处理和后处理,从而增强应用程序的功能和控制流程。以下是对Struts2拦截器原理与实现的详细解析: ...

    struts2 拦截器实现登录控制

    总的来说,Struts2的拦截器机制为开发者提供了强大的功能,使得应用程序能够更好地管理复杂的业务流程和控制逻辑,同时保持代码的清晰和模块化。通过理解并熟练运用拦截器,我们可以构建更健壮、更安全的Web应用。

    Struts2 拦截器过滤方法(二十八)

    在"Struts2 拦截器过滤方法(二十八)"的博文中,可能更具体地讲解了一些高级用法,如条件判断拦截、组合拦截器、拦截器的堆栈管理和自定义参数传递等。 对于项目中的源码部分(src目录),可能包含了自定义拦截器...

    struts2 拦截器的使用(继承抽象拦截器)

    1. `intercept(ActionInvocation invocation)`: 这是拦截器的主要方法,它被Struts2框架调用来执行拦截逻辑。`ActionInvocation`对象包含了当前Action执行的所有信息,如Action上下文、Action实例、方法名等。你需要...

    Struts拦截器及token拦截器防止重复提交例子源码

    其中,init和destroy方法会在程序开始和结束时各执行一遍,不管使用了该拦截器与否,只要在struts.xml中声明了该Struts2拦截器就会被执行。 intercept方法就是拦截的主体了,每次拦截器生效时都会执行其中的逻辑。

    struts2拦截器时序图

    例如,在Struts2的struts.xml配置文件中,可以这样定义拦截器和拦截器链: ```xml &lt;package name="default" extends="struts-default"&gt; &lt;!-- 其他拦截器配置 --&gt; 其他拦截器"/&gt; &lt;!-- 其他配置 --&gt; ...

    struts2.X 拦截器源码

    Struts2.X 拦截器是Apache Struts框架的核心组件之一,它是基于拦截器模式实现的,使得开发者能够方便地扩展和定制应用程序的行为。在Struts2中,拦截器扮演着中间件的角色,它在Action执行前后进行处理,可以进行如...

    Struts 2 过滤器和拦截器的区别

    通过对Struts 2框架中过滤器和拦截器的核心区别以及具体应用场景的分析,我们可以看到,虽然两者都能实现类似的功能(如权限验证),但它们的工作方式和技术基础存在明显差异。选择合适的技术方案取决于实际项目的...

    运用struts2技术的拦截器实现的页面检测和用户注册

    在Struts2中,拦截器扮演着至关重要的角色,它们允许我们在动作执行前后插入自定义逻辑,提升代码的可复用性和模块化。本篇文章将深入探讨如何使用Struts2的拦截器技术来实现页面检测和用户注册功能。 首先,我们...

Global site tag (gtag.js) - Google Analytics