`

《Struts 2 in Action》读书笔记——part 2——核心概念之拦截器

阅读更多

第四章    使用拦截器追加工作流

4.1 为什么要拦截请求
在尽量隔离WEB应用的程序关注点时,拦截器极大地提高了分离水平。特别是,拦截器消除了Action组件中的横切任务。


4.2 拦截器的工作原理
框架不直接调用Action的execute()方法,而是创建一个叫做ActionInvocation的对象,它封装了Action执行相关的所有处理细节。

public interface ActionInvocation extends Serializable {

    /**
     * Get the Action associated with this ActionInvocation.
     *
     * @return the Action
     */
    Object getAction();

    /**
     * Gets whether this ActionInvocation has executed before.
     * This will be set after the Action and the Result have executed.
     *
     * @return <tt>true</tt> if this ActionInvocation has executed before.
     */
    boolean isExecuted();

    /**
     * Gets the ActionContext associated with this ActionInvocation. The ActionProxy is
     * responsible for setting this ActionContext onto the ThreadLocal before invoking
     * the ActionInvocation and resetting the old ActionContext afterwards.
     *
     * @return the ActionContext.
     */
    ActionContext getInvocationContext();

    /**
     * Get the ActionProxy holding this ActionInvocation.
     *
     * @return the ActionProxy.
     */
    ActionProxy getProxy();

    /**
     * If the ActionInvocation has been executed before and the Result is an instance of {@link ActionChainResult}, this method
     * will walk down the chain of <code>ActionChainResult</code>s until it finds a non-chain result, which will be returned. If the
     * ActionInvocation's result has not been executed before, the Result instance will be created and populated with
     * the result params.
     *
     * @return the result.
     * @throws Exception can be thrown.
     */
    Result getResult() throws Exception;

    /**
     * Gets the result code returned from this ActionInvocation.
     *
     * @return the result code
     */
    String getResultCode();

    /**
     * Sets the result code, possibly overriding the one returned by the
     * action.
     * <p/>
     * The "intended" purpose of this method is to allow PreResultListeners to
     * override the result code returned by the Action.
     * <p/>
     * If this method is used before the Action executes, the Action's returned
     * result code will override what was set. However the Action could (if
     * specifically coded to do so) inspect the ActionInvocation to see that
     * someone "upstream" (e.g. an Interceptor) had suggested a value as the
     * result, and it could therefore return the same value itself.
     * <p/>
     * If this method is called between the Action execution and the Result
     * execution, then the value set here will override the result code the
     * action had returned.  Creating an Interceptor that implements
     * {@link PreResultListener} will give you this oportunity.
     * <p/>
     * If this method is called after the Result has been executed, it will
     * have the effect of raising an IllegalStateException.
     *
     * @param resultCode  the result code.
     * @throws IllegalStateException if called after the Result has been executed.
     * @see #isExecuted()
     */
    void setResultCode(String resultCode);

    /**
     * Gets the ValueStack associated with this ActionInvocation.
     *
     * @return the ValueStack
     */
    ValueStack getStack();

    /**
     * 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);

    /**
     * Invokes the next step in processing this ActionInvocation.
     * <p/>
     * If there are more Interceptors, this will call the next one. If Interceptors choose not to short-circuit
     * ActionInvocation processing and return their own return code, they will call invoke() to allow the next Interceptor
     * to execute. If there are no more Interceptors to be applied, the Action is executed.
     * If the {@link ActionProxy#getExecuteResult()} method returns <tt>true</tt>, the Result is also executed.
     *
     * @throws Exception can be thrown.
     * @return the return code.
     */
    String invoke() throws Exception;

    /**
     * Invokes only the Action (not Interceptors or Results).
     * <p/>
     * This is useful in rare situations where advanced usage with the interceptor/action/result workflow is
     * being manipulated for certain functionality.
     *
     * @return the return code.
     * @throws Exception can be thrown.
     */
    String invokeActionOnly() throws Exception;

    /**
     * Sets the action event listener to respond to key action events.
     *
     * @param listener the listener.
     */
    void setActionEventListener(ActionEventListener listener);

    void init(ActionProxy proxy) ;

}

 

当框架收到一个请求时,它首先决定这个URL映射到哪个Action。这个Action的一个实例会被加入到一个新创建的ActionInvocation实例中。接着,框架咨询声明性架构(通过应用程序的XML或者Java注解),以发现哪些拦截器应该触发,以及按什么顺序触发。除了这些核心元素,ActionInvocation还拥有对其他重要信息(例如Servlet请求对象和当前Action可用的结果组件的映射)的引用。


ActionInvocation公开了invoke()方法,框架通过调用这个方法开始Action的执行。当框架调用这个方法时,ActionInvocation通过执行拦截器栈中第一个拦截器开始这个调用过程。注意,invoke()方法并不总是映射到第一个拦截器,ActionInvocation负责跟踪执行过程到达的状态,并且通过调用拦截器的intercept()方法把控制权交给栈中合适的拦截器。重要的是,intercept()方法把ActionInvocation实例作为一个参数。

public String intercept(ActionInvocation invocation) throws Exception {
...
}

 

后续拦截器的继续执行,最终执行Action,这些都是通过递归调用ActionInvocation的invoke()方法实现。每次invoke()方法被调用时,ActionInvocation都会查询自身的状态,调用接下来的任何一个拦截器。



 
因此,在通常的执行中,调用过程向下通过所有拦截器,直到栈中再也没有拦截器时,触发Action。另外,ActionInvocation在内部管理处理状态,因此它总是直到自己现在处在栈的什么位置。


拦截器在触发时能做什么:

  1. 做一些预处理。在这个阶段拦截器可以用来准备、过滤、改变或者操作任何可以访问的重要数据。这些数据包括所有与当前请求相关的关键对象和数据,也包括Action。
  2. 通过调用invoke()方法将控制转移给后续的拦截器,直到Action。或者通过返回一个控制字符串中断执行。在这个阶段,如果拦截器决定请求不应该继续,他可以不调用ActionInvocation实例上的invoke()方法,而是直接返回一个控制字符串。通过这种方式可以停止后续的执行,并且决定哪个结果被呈现。
  3. 做一些后加工。在这个阶段,任何一个返回的拦截器可以修改可以访问的对象的数据作为后加工,但是此时结果已经确定了。

4.3  研究内建的Struts 2拦截器
4.3.1 工具拦截器

  • timer拦截器。记录执行花费的时间
  • logger拦截器。提供了一个简单的日志记录机制

4.3.2  数据转移拦截器

  • params拦截器(defaultStack)。params拦截器不知道这些数据最终会去哪里,它只是把数据转移到ValueStack上发现的第一个匹配的属性上。
  • static-params拦截器(defaultStack)。它也将参数转移到ValueStack公开的属性上,不同的是参数的来源。这个拦截器转移的参数定义在声明性架构的Action元素中。
  • autowiring拦截器。这个拦截器为使用Spring管理应用程序资源提供了一个集成点。
  • servlet-config拦截器(defaultStack)。该拦截器提供了一种将来源于Servlet API的各种对象注入到Action的简洁方法。这个拦截器通过将各种对象设置到Action必须实现的接口公开的设置方法的方式工作。每个接口包含一个方法——当前资源的设置方法。不同的接口用于获取与Servlet环境相关的不同对象。 

    ServletContextAware设置ServletContext

    ServletRequestAware设置HttpServletRequest

    ServletResponseAware设置HttpServletResponse

    ParameterAware设置Map类型的请求参数

    RequestAware设置Map类型的请求属性

    SessionAware设置Map类型的会话属性

    ApplicationAware设置Map类型的应用程序领域属性

    PrincipalAware设置Principal对象(安全相关)

  • fileUpload拦截器(defaultStack)。该拦截器将文件和元数据从多重请求转换为常规的请求参数。

4.3.3  工作流拦截器

  • workflow拦截器(defaultStack)
  • validation拦截器(defaultStack),提供了声明性的方式验证你的数据。
  • prepare拦截器(defaultStack),提供了一种向Action追加额外的工作流处理的通用入口点。
  • modelDriven拦截器(defaultStack)

4.3.4 其他拦截器

  • exception拦截器(defaultStack)。它出现在defaultStack中第一位,也应在在任何你创建的自定义拦截器栈中出现在第一位。当exception拦截器在后加工阶段处理时,它会捕获被抛出的任何异常,并且把结它映射到一个结果页面。在将控制转交给结果之前,exception拦截器会创建一个ExceptionHolder对象,并且把它放在ValueStack的最顶端。ExceptionHolder是一个异常的包装器,它把跟踪栈和异常作为JavaBean属性公开出来,可以在错误页面通过标签访问这些属性。
  • token拦截器和token-session拦截器。可以作为避免表单重复提交系统的一部分。
  • scoped-modelDriven拦截器(defaultStack)。这个拦截器为Action的模型对象提供跨请求的向导式的持久性。
  • execAndWait拦截器。当一个请求需要执行很长时间时,最好能给用户一些反馈。

4.4  声明拦截器
此时XML是声明拦截器的唯一选择。注解机制现在还不支持声明拦截器。
只要Action声明了自己的拦截器,它就失去了自动的默认值。


4.5  构建自定义拦截器
拦截器实例在Action之间共享。虽然每个请求都会创建动作的一个新实例,但是拦截器会重用。拦截器是无状态的,不要在拦截器中存储与当前正在处理的请求相关的数据。

 

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

相关推荐

    Struts拦截器案例——登陆

    Struts拦截器是Java Web开发中的一个重要概念,尤其在基于Struts2框架的应用中,它扮演着处理请求、验证输入、记录日志等关键角色。在这个"Struts拦截器案例——登陆"中,我们将深入探讨如何利用Struts拦截器实现...

    Struts2的拦截器——Struts2拦截器的基础知识.pptx

    拦截器是Struts2的核心组件之一,它基于AOP(面向切面编程)的概念,为框架提供了高度的灵活性和可扩展性。以下是关于Struts2拦截器的基础知识的详细说明: 1. **拦截器的定义与作用**: - 拦截器是Struts2框架中...

    Struts2实战(Struts2 In Action中文版)

    **Struts2实战——《Struts2 In Action中文版》** 《Struts2 In Action》是一本专为Java开发者设计的实战指南,旨在深入解析Struts2框架的使用与实践。Struts2作为一款强大的MVC(Model-View-Controller)框架,极...

    Struts 2实战 Struts 2 in action 的中文版

    根据提供的信息,我们可以推断出这是一本关于Struts 2框架的书籍——《Struts 2实战 Struts 2 in action 的中文版》。本书主要介绍了Struts 2框架的相关概念、工作原理以及实际应用案例等内容。接下来,我们将根据...

    Struts2+技术内幕——深入解析Struts2架构设计与实现原理

    首先,Struts2的核心在于它的拦截器(Interceptor)机制。拦截器是Struts2的一个强大特性,它们在Action调用前后执行,可以处理诸如验证、日志、事务管理等通用任务。通过灵活配置,开发者可以构建出满足各种需求的...

    Struts 2实战 struts2 in Action

    《Struts 2实战 Struts2 in Action》这本书不仅介绍了Struts 2的基本概念和技术细节,更重要的是,它通过丰富的实战案例帮助读者深入理解框架的工作原理,并掌握了如何高效地利用Struts 2来解决实际问题。...

    在struts1中使用拦截器——saif-0.1.jar

    在Struts1中,拦截器是框架的核心组件之一,它们提供了扩展功能和处理请求的能力,而无需修改Action类本身。本文将深入探讨在Struts1中如何使用拦截器,并以saif-0.1.jar为例,解释其在实际项目中的应用。 首先,...

    Struts2 in action中文版+配套源代码

    "Struts2 in Action" 是一本深入探讨Struts2框架的专业书籍,旨在帮助开发者掌握这一框架的核心概念和实践技巧。这本书的中文版不仅提供了理论知识,还附带有配套的源代码,方便读者进行实践操作,加深理解。 ...

    struts2学习笔记(完美总结)——转自OPEN经验库

    本文将深入探讨Struts2的核心概念,包括Action、Result、配置文件、OGNL与ValueStack、Tags以及项目中的关键实践。 **一、Action** Action是Struts2中处理业务逻辑的核心组件,它是实现了`...

    Struts2 in action(struts2实战)

    通过阅读《Struts2 in action》这本书,你可以深入学习Struts2的各个方面,包括最佳实践、高级特性和案例分析,从而在实际项目中更加熟练地运用这个框架。无论你是初学者还是经验丰富的开发者,这本书都将为你的Java...

    Struts2 in action中文版

    第二部分 核心概念:动作、拦截器和类型转换 第3章 使用Struts 2动作 36 3.1 Struts 2动作简介 36 3.2 打包动作 39 3.2.1 Struts 2公文包示例应用程序 39 3.2.2 组织你的包 39 3.2.3 使用struts-default包中的组件 ...

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

    总结,Struts2拦截器是其核心机制之一,它允许开发者以模块化的方式添加额外的功能,提高代码的可复用性和可维护性。通过自定义拦截器和合理配置,我们可以实现诸如日志记录、事务管理、权限验证等多种业务需求,...

    Struts2拦截器的实现原理(csdn)————程序.pdf

    在Struts2中,拦截器工作在Action和结果(Result)之间,形成一个拦截器栈,每个拦截器按照配置的顺序依次执行。 Struts2的拦截器执行流程如下: 1. **初始化拦截器栈**:当Struts2框架启动时,会根据配置文件...

    Struts2 技术内幕——深入解析Struts2架构设计与实现原理

    要深入学习和掌握Struts2,建议阅读官方文档,参与实际项目实践,也可以参考相关的技术书籍和教程,例如《Struts2技术内幕——深入解析Struts2架构设计与实现原理》等资源,来提升对Struts2框架的全面理解。

    struts2 拦截器

    ### 一、Struts2 拦截器概念 1. **拦截器是什么**:拦截器是一种动态拦截Action调用的对象,它可以理解为一个过滤器,它在Action被调用之前和之后执行特定的逻辑。Struts2的拦截器是基于Java的Servlet Filter机制...

    Struts2 in action 中文版

    MVC设计模式是Struts2的核心概念之一。模型(Model)负责处理数据和业务逻辑;视图(View)负责展示数据,即用户界面;控制器(Controller)则作为模型和视图之间的桥梁,处理用户请求并将请求分发给适当的模型组件...

    Struts2 in action

    2. **前端控制器拦截**:所有请求首先被Struts2的前端控制器(FilterDispatcher)拦截。 3. **查找并执行Action**:根据请求中的参数找到对应的Action并执行。 4. **返回结果**:Action执行完成后返回一个结果。 5. ...

Global site tag (gtag.js) - Google Analytics