`
zscomehuyue
  • 浏览: 411941 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

webwork拦截器interceptor 之 ActionInvocation 意义

阅读更多
webwork拦截器interceptor 之 ActionInvocation 意义
“将Web页面中的输入元素封装为一个(请求)数据对象”,这个对象就是ActionInvocation类型.
        对于Xwork 而言,前端的Webwork 组件为其提供的是一个Map 类型的数据结构。而Action面向的却是Model对象所提供的数据结构。在何时、何处对这两种不同的数据结构进行转换?
        写一个辅助类完成这样的工作,并在每次Action 调用之前由框架代码调用他完成转换工作。
Xwork 通过Interceptor 实现了这一步骤,从而我们可以根据需要,灵活的配置所需的Interceptor。从而为Action提供可扩展的预处理、后处理过程。

          ActionInvocation 是Xworks 中Action 调度的核心。而对Interceptor 的调度,也正是由ActionInvocation负责。
         ActionInvocation 是一个接口, 而DefaultActionInvocation 则是Webwork 对ActionInvocation的默认实现。

      Interceptor 的调度流程大致如下:

      1. ActionInvocation初始化时,根据配置,加载Action相关的所有Interceptor。

      参见ActionInvocation.init方法中相关代码:
Java代码

   1. private void init() throws Exception ...{ 
   2. …… 
   3. List interceptorList = new 
   4. ArrayList(proxy.getConfig().getInterceptors()); 
   5. interceptors = interceptorList.iterator(); 
   6. } 

private void init() throws Exception ...{
……
List interceptorList = new
ArrayList(proxy.getConfig().getInterceptors());
interceptors = interceptorList.iterator();




2. 通过ActionInvocation.invoke方法调用Action实现时,执行Interceptor:
       下面是DefaultActionInvocation中Action调度代码:

Java代码

   1. public String invoke() throws Exception ...{ 
   2.     if (executed) 
   3.         throw new IllegalStateException("Action has already executed"); 
   4.     if (interceptors.hasNext()) ...{ 
   5.         Interceptor interceptor = (Interceptor) interceptors.next(); 
   6.         resultCode = interceptor.intercept(this); 
   7.     } else 
   8.         resultCode = invokeAction(getAction(), proxy.getConfig()); 
   9.     if (!executed) ...{ 
  10.         if (preResultListeners != null) ...{ 
  11.         Iterator iterator = preResultListeners.iterator(); 
  12.         while (iterator.hasNext()) ...{ 
  13.             PreResultListener listener 
  14.             = (PreResultListener) iterator.next(); 
  15.             listener.beforeResult(this, resultCode); 
  16.         } 
  17.         } 
  18.         if (proxy.getExecuteResult()) 
  19.         executeResult(); 
  20.         executed = true; 
  21.     } 
  22.     return resultCode; 
  23.     } 

public String invoke() throws Exception ...{
    if (executed)
        throw new IllegalStateException("Action has already executed");
    if (interceptors.hasNext()) ...{
        Interceptor interceptor = (Interceptor) interceptors.next();
        resultCode = interceptor.intercept(this);
    } else
        resultCode = invokeAction(getAction(), proxy.getConfig());
    if (!executed) ...{
        if (preResultListeners != null) ...{
        Iterator iterator = preResultListeners.iterator();
        while (iterator.hasNext()) ...{
            PreResultListener listener
            = (PreResultListener) iterator.next();
            listener.beforeResult(this, resultCode);
        }
        }
        if (proxy.getExecuteResult())
        executeResult();
        executed = true;
    }
    return resultCode;
    }




所有的拦截器都必须实现Interceptor 接口。

      public interface Interceptor {
         void destroy();
         void init();
         String intercept(ActionInvocation invocation) throws Exception;
     }
     在Interceptor 实现中,抽象实现AroundInterceptor得到了最广泛的应用(扩展),它增加了预处理(before)和后处理(after)方法的定义。

     AroundInterceptor.java:
Java代码

   1. public abstract class AroundInterceptor implements Interceptor 
   2. ...{ 
   3.     protected Log log = LogFactory.getLog(this.getClass()); 
   4.      
   5.     public void destroy() ...{ 
   6.     } 
   7.      
   8.     public void init() ...{ 
   9.     } 
  10.      
  11.     public String intercept(ActionInvocation invocation) throws Exception ...{ 
  12.     String result = null; 
  13.     before(invocation); 
  14.     result = invocation.invoke(); 
  15.     after(invocation, result); 
  16.     return result; 
  17.     } 
  18.      
  19.     protected abstract void after 
  20.     (ActionInvocation actioninvocation, String string) throws Exception; 
  21.      
  22.     protected abstract void before(ActionInvocation actioninvocation) 
  23.     throws Exception; 
  24. } 

public abstract class AroundInterceptor implements Interceptor
...{
    protected Log log = LogFactory.getLog(this.getClass());
   
    public void destroy() ...{
    }
   
    public void init() ...{
    }
   
    public String intercept(ActionInvocation invocation) throws Exception ...{
    String result = null;
    before(invocation);
    result = invocation.invoke();
    after(invocation, result);
    return result;
    }
   
    protected abstract void after
    (ActionInvocation actioninvocation, String string) throws Exception;
   
    protected abstract void before(ActionInvocation actioninvocation)
    throws Exception;
}



AroundInterceptor.invoke 方法中,调用了参数invocation的invoke 方法。

最后,结合最常用的ParametersInterceptor,看看Xwork 是如何通过Interceptor,将Webwork传入的Map类型数据结构,转换为Action所需的Java 模型对象。

   ParametersInterceptor.java:
Java代码

   1. public class ParametersInterceptor extends AroundInterceptor ...{ 
   2. protected void after(ActionInvocation dispatcher, String result) 
   3. throws Exception ...{ 
   4. } 
   5. protected void before(ActionInvocation invocation) throws Exception 
   6. ...{ 
   7. if (!(invocation.getAction() instanceof NoParameters)) ...{ 
   8. final Map parameters = 
   9. ActionContext.getContext().getParameters(); ⑴ 
  10. if (log.isDebugEnabled()) ...{ 
  11. log.debug("Setting params " + parameters); 
  12. } 
  13. ActionContext invocationContext = 
  14. invocation.getInvocationContext(); 
  15. try ...{ 
  16. invocationContext.put( 
  17. InstantiatingNullHandler.CREATE_NULL_OBJECTS, 
  18. Boolean.TRUE); 
  19. invocationContext.put( 
  20. XWorkMethodAccessor.DENY_METHOD_EXECUTION, 
  21. Boolean.TRUE); 
  22. invocationContext.put( 
  23. XWorkConverter.REPORT_CONVERSION_ERRORS, 
  24. Boolean.TRUE); 
  25. if (parameters != null) ...{ 
  26. final OgnlValueStack stack = 
  27. ActionContext.getContext().getValueStack(); ⑵ 
  28. for (Iterator iterator =parameters.entrySet().iterator(); 
  29. iterator.hasNext(); 
  30. ) ...{ 
  31. Map.Entry entry = (Map.Entry) iterator.next(); 
  32. stack.setValue( ⑷ 
  33. entry.getKey().toString(), 
  34. entry.getValue()); 
  35. } 
  36. } 
  37. } finally ...{ 
  38. invocationContext.put( 
  39. InstantiatingNullHandler.CREATE_NULL_OBJECTS, 
  40. Boolean.FALSE); 
  41. invocationContext.put( 
  42. XWorkMethodAccessor.DENY_METHOD_EXECUTION, 
  43. Boolean.FALSE); 
  44. invocationContext.put( 
  45. XWorkConverter.REPORT_CONVERSION_ERRORS, 
  46. Boolean.FALSE); 
  47. } 
  48. } 
  49. } 
  50. } 

public class ParametersInterceptor extends AroundInterceptor ...{
protected void after(ActionInvocation dispatcher, String result)
throws Exception ...{
}
protected void before(ActionInvocation invocation) throws Exception
...{
if (!(invocation.getAction() instanceof NoParameters)) ...{
final Map parameters =
ActionContext.getContext().getParameters(); ⑴
if (log.isDebugEnabled()) ...{
log.debug("Setting params " + parameters);
}
ActionContext invocationContext =
invocation.getInvocationContext();
try ...{
invocationContext.put(
InstantiatingNullHandler.CREATE_NULL_OBJECTS,
Boolean.TRUE);
invocationContext.put(
XWorkMethodAccessor.DENY_METHOD_EXECUTION,
Boolean.TRUE);
invocationContext.put(
XWorkConverter.REPORT_CONVERSION_ERRORS,
Boolean.TRUE);
if (parameters != null) ...{
final OgnlValueStack stack =
ActionContext.getContext().getValueStack(); ⑵
for (Iterator iterator =parameters.entrySet().iterator();
iterator.hasNext();
) ...{
Map.Entry entry = (Map.Entry) iterator.next();
stack.setValue( ⑷
entry.getKey().toString(),
entry.getValue());
}
}
} finally ...{
invocationContext.put(
InstantiatingNullHandler.CREATE_NULL_OBJECTS,
Boolean.FALSE);
invocationContext.put(
XWorkMethodAccessor.DENY_METHOD_EXECUTION,
Boolean.FALSE);
invocationContext.put(
XWorkConverter.REPORT_CONVERSION_ERRORS,
Boolean.FALSE);
}
}
}
}



ParametersInterceptor 扩展了抽象类AroundInterceptor。并在其预处理方法(before)中实现了数据的转换。
数据转换的过程并不复杂:
⑴ 首先由ActionContext获得Map型的参数集parameters。
⑵ 由ActionContext获得值栈(OgnlValueStack)。
⑶ 遍历parameters中的各项数据。
⑷ 通过OgnlValueStack,根据数据的键值,为Model 对象填充属性数据。
OgnlValueStack 是http://www.ognl.org4提供的一套可读写对象属性的类库

上面的代码中并没有发现将Model对象入栈的部分,是由于ActionInvocation在初始化的时候已经预先完成了压栈工作,如DefaultActionInvocation.init方法中代码所示:

private void init() throws Exception {
Map contextMap = createContextMap();
createAction();
if (pushAction) {
stack.push(action);      //压栈
}
……
}

旁白:Servlet 2.3规范中引入的Filter 算是拦截器的一个典型实现,它在Servlet执行之前被触发,对输入参数进行处理之后,再将工作流程传递给对应的Servlet。
分享到:
评论

相关推荐

    webwork拦截器,验证,以及帮助文档

    本篇将详细介绍WebWork中的核心概念——拦截器(Interceptor)以及验证(Validation)机制,并结合提供的帮助文档进行学习指导。 首先,我们来理解WebWork的拦截器机制。在WebWork中,拦截器是处理请求的关键组件,...

    J2EE(Struts_拦截器)

    接口中有三个方法:`void init()`用于初始化,`String intercept(ActionInvocation invocation) throws Exception`是拦截器的主要工作方法,`void destroy()`则在拦截器不再使用时调用。 ### 4. 配置拦截器 在...

    xwork源代码(webwork源代码,xwork source,)

    `ActionInvocation`接口及其实现类则表示动作的执行链,它可以支持拦截器的介入,提供事务管理、权限控制等功能。 2. **模型-视图-控制器模式** MVC模式在XWork中得到了充分的体现。`Action`类代表了模型层,处理...

    Webwork2-Guide.rar_webwork2

    3. ActionInvocation负责调用Action的方法,并可以插入拦截器链进行预处理。 4. Action执行业务逻辑,将结果存储在ValueStack中。 5. 结果处理器(Result)根据Action返回的结果类型,决定如何展示给用户,如转发到...

    浅析webwork

    WebWork引入了拦截器(Interceptor)的概念,它在动作执行前后执行自定义逻辑。拦截器可以用于事务管理、权限检查、日志记录等多种用途,极大地增强了框架的灵活性和扩展性。 ### 5. 动态方法调用 WebWork支持动态...

    webwork 学习 培训 ppt

    而ActionInvocation则表示Action的执行状态,它包含了Action实例以及所有Interceptor(拦截器)。拦截器允许开发者在Action执行前后插入自定义逻辑,实现了面向切面的编程(AOP),提高了代码的复用性和解耦性。 ...

    Struts2配置详解

    - **拦截器(Interceptor)**:拦截器实现了`com.opensymphony.xwork.interceptor.Interceptor`接口,它们在Action执行前后进行方法的织入通知。拦截器可以实现诸如防止表单重复提交等功能。 - **Action执行**:通过...

    详解Webwork中Action 调用的方法

    - 在`invoke`过程中,ActionInvocation会根据Action配置的拦截器链(Interceptor Chain)执行拦截器,这些拦截器可以用来做权限检查、日志记录等预处理或后处理工作。 - 最后,Action的执行结果会被转换成对应的...

    webwork培训教程

    ActionInvocation则表示Action的执行状态,它持有着Action实例和一系列Interceptor(拦截器)。拦截器是AOP(面向切面编程)的一种实现,允许在Action执行前后插入自定义的逻辑,提高了代码的可复用性和解耦性。 ...

    webwork培训资料

    ActionInvocation则表示Action执行的状态,它包含了Action实例和一系列Interceptor(拦截器)。拦截器是AOP(面向切面编程)的一种实现,允许在Action执行前后插入自定义逻辑,从而实现了解耦和模块化的设计。 在...

    S2SH面试题专家总结

    - 拦截器(Interceptor):位于中间层,执行Action执行前后的一些通用功能。 - Action:位于最后端,作为业务控制器,由开发者编写,实现业务逻辑、操作数据库并返回结果视图。 4. Struts2包的默认拦截器设置 ...

    webwork通解

    WebWork支持拦截器(Interceptor)、类型安全的参数绑定、强大的表单处理以及AOP(面向切面编程)特性,从而提高了开发效率和代码质量。 **WebWork安装 - HelloWorld** 安装WebWork通常包括以下几个步骤: 1. 获取...

    struts2工作原理

    它的核心是基于WebWork框架,提供了丰富的功能和灵活性,包括强大的动作映射、拦截器机制、强大的视图组件以及灵活的配置选项。 **Struts2工作原理** 1. **请求处理流程** 当一个HTTP请求到达服务器时,它首先...

    webwork学习笔记(全)

    以上只是WebWork教程的部分内容,完整的学习笔记涵盖了更多高级主题,如Interceptor(拦截器)、Validation(验证)、I18N(国际化)、AOP支持以及与其他开源项目的集成,如G-Roller-WW和Spring等。通过深入学习和...

    Struts.2权威指南--基于WebWork核心的MVC开发.0001.pdf

    Struts.2采用了更为灵活的拦截器(Interceptor)机制来处理请求,支持多种视图技术(如JSP、Velocity、FreeMarker等),并提供了丰富的插件生态系统,使得开发者可以轻松地扩展框架功能。同时,Struts.2与WebWork...

    struts2.0详细配置文档.doc

    4. **拦截器(Interceptor)**:拦截器是Struts2的核心组件之一,它们实现了`com.opensymphony.xwork.interceptor.Interceptor`接口。在请求到达Action之前,拦截器会按照配置顺序执行,进行方法前的织入通知。在响应...

    Xwork2 源码阅读.pdf(附源码)

    通过源码阅读,我们可以了解ActionInvocation如何根据配置的拦截器顺序逐个执行,并如何在每个拦截器中注入业务逻辑。 Webwork是Struts2的前身,它的许多设计理念和机制被继承到了Struts2中。Webwork的核心概念包括...

    Struts2 基础知识

    拦截器是Struts2的核心特性之一,它允许开发者在Action执行前后插入自定义逻辑。拦截器按照栈的顺序依次执行,可以用于登录验证、日志记录、性能监控等多种场景。例如,`Interceptor_Simulation`可能就是模拟了一个...

Global site tag (gtag.js) - Google Analytics