`

struts2.0 中有关拦截器Interceptor相关知识

阅读更多

008 - 05 - 27

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。
分享到:
评论
2 楼 wtuddd001 2008-10-06  
                 
1 楼 wtuddd001 2008-10-06  
 

相关推荐

    struts2.0中文教程

    07 Struts 2的基石——拦截器(Interceptor) 08 在Struts 2中实现IoC 09 在Struts 2中实现文件上传 10 在Struts 2中实现CRUD 11 Struts 2中的OGNL 12 trus 2的新表单标志的使用 13 Struts 2与AJAX

    Struts 2.0系列(MAX)

    Struts 2.0系列(MAX),pdf格式,全...Struts 2的基石——拦截器(Interceptor) 在Struts 2中实现IoC 在Struts 2中实现文件上传 在Struts 2中实现CRUD Struts 2中的OGNL Strus 2的新表单标志的使用 Struts 2与AJAX

    struts2.0的特点

    Struts2.0采用了拦截器(Interceptor)机制,这是一种非常强大的特性,允许开发者在Action执行前后进行一系列操作,如参数填充、验证、事务控制等。拦截器的设计遵循AOP(Aspect Oriented Programming)思想,可以...

    Struts2.0学习Struts2.0文档

    接下来,开发者可以根据具体需求进一步深入学习Struts 2.0 的高级特性和最佳实践,例如拦截器(Interceptor)、国际化(i18n)和支持AJAX等功能。Struts 2.0 不仅是一个强大的Web开发工具,而且也是一个学习现代Web...

    struts 2.0 的拦截器

    Struts 2.0 是一个基于MVC设计模式的Java Web框架,它的核心功能之一是拦截器(Interceptor),这是实现业务逻辑控制和增强应用程序功能的重要组件。在Struts 2中,拦截器扮演着中间人的角色,它们在Action调用前后...

    Struts2.0中文教程

    Struts2.0通过拦截器(Interceptor)机制实现了动作(Action)的处理,大大提高了代码的可维护性和可复用性。 二、MVC模式 在Struts2.0中,Model代表业务逻辑,View负责展示,Controller进行协调。用户请求被控制器...

    Struts2.0中文教程权威版

    07 Struts 2的基石——拦截器(Interceptor) 08 在Struts 2中实现IoC 09 在Struts 2中实现文件上传 10 在Struts 2中实现CRUD 11 Struts 2中的OGNL 12 trus 2的新表单标志的使用 13 Struts 2与AJAX Struts2中用...

    Struts2.0的api

    Struts2.0是Java Web开发中的一个热门框架,它基于Model-View-Controller(MVC)设计模式,为开发者提供了构建动态Web应用程序的强大工具。API文档是理解任何框架核心功能的关键,对于Struts2.0也不例外。让我们深入...

    Struts2.0拦截器总结

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

    struts2.0拦截器完整

    下面我们将深入探讨Struts2.0拦截器的完整知识体系。 1. **拦截器的概念** 拦截器类似于AOP(面向切面编程)中的通知,它是在Action执行前或执行后进行拦截,并可以修改Action的执行流程。在Struts2中,拦截器是...

    三大框架中文文档中的struts2.0开发手册(程序员必看)

    2. **拦截器(Interceptor)**:拦截器是Struts2.0的一大特色,它可以实现通用的功能,如日志、权限检查等,无需在每个Action中重复编写。通过配置拦截器栈,可以灵活地控制请求的处理流程。 3. **OGNL(Object-...

    Struts2.0 Jar包

    4. **拦截器(Interceptor)**: 拦截器是Struts2的一大特色,它可以插入到Action调用链中,执行预处理或后处理任务,如日志记录、权限验证、性能统计等。通过组合不同的拦截器,可以实现复杂的业务逻辑。 5. **...

    Struts2.0大结合

    五、Struts2.0拦截器 拦截器是Struts2.0实现业务逻辑的重要手段,如ValidationInterceptor进行数据校验,ExceptionMappingInterceptor处理异常,LoginInterceptor实现登录控制等。拦截器可以自由组合,形成拦截器栈...

    Struts_2.0从入门到精通

    拦截器是Struts2.0框架中一个非常灵活且强大的特性,它可以在Action执行前后进行拦截,执行特定的逻辑,如权限检查、日志记录等。Struts2.0内置了多种拦截器,同时支持自定义拦截器,使得开发者可以根据应用需求定制...

    struts2.0入门案例

    Struts2.0是Java Web开发中一个非常重要的框架,它是Apache软件基金会的Jakarta项目下的一个开源产品,主要用于构建MVC(Model-View-Controller)模式的应用程序。本入门案例将带你逐步了解如何使用Struts2.0来创建...

Global site tag (gtag.js) - Google Analytics