一、拦截器概述

  拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前进行拦截,然后在之前或之后加入某些操作。拦截器是AOP的一种实现策略。

  在Webwork的中文文档的解释为:拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。

  谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。

二、拦截器的实现原理

  大部分时候,拦截器方法都是通过代理的方式来调用的。Struts2的拦截器实现相对简单。当请求到达Struts 2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器。事实上,我们之所以能够如此灵活地使用拦截器,完全归功于“动态代理”的使用。动态代理是代理对象根据客户的需求做出不同的处理。对于客户来说,只要知道一个代理对象就行了。那Struts2中,拦截器是如何通过动态代理被调用的呢? 当Action请求到来的时候,会由系统的代理生成一个Action的代理对象,由这个代理对象调用Action的execute()或指定的方法,并在 struts.xml中查找与该Action对应的拦截器。如果有对应的拦截器,就在Action的方法执行前(后)调用这些拦截器;如果没有对应的拦截 器则执行Action的方法。其中系统对于拦截器的调用,是通过ActionInvocation来实现的。

  Struts2拦截器是可插拔的,拦截器是AOP的一种实现。Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。

三、自定义拦截器

3.1 实现Interceptor接口

public class MyInterceptor implements Interceptor {

    @Override
// 初始化方法
public void init() {
} @Override
// 拦截方法
public String intercept(ActionInvocation arg0) throws Exception {
return null;
} @Override
// 销毁方法
public void destroy() {
}
}

  Interceptor接口提供了三个方法,其具体介绍如下

  • void init():该方法在拦截器被创建后会立即调用,它在拦截器的生命周期内只被调用一次,可以在该方法中对相关资源进行必要的初始化。
  • void destroy():该方法与init方法相对应,在拦截器实例被销毁之前,将调用该方法来释放和拦截器相关的资源。它在拦截器的生命周期内也只被调用一次。
  • String interceptor(ActionInvocation invocation):该方法是拦截器的核心方法,用来添加真正执行拦截工作的代码,实现具体的拦截操作。它返回一个字符串作为逻辑视图,系统根据返回的字符串跳转到对应的视图资源。每拦截一个动作请求, 该方法就会被调用一次。该方法的ActionInvocation参数包含了被拦截的Action的引用,可以通过该参数的invoke()方法,将控制权转给下一个拦截器或者转给Action的execute()方法。

3.2 继承AbstractInterceptor

// 帮我们空实现了init和destory方法,如果我们不需要实现这两个方法,就可以只实现intercept方法
public class MyInterceptor extends AbstractInterceptor{ @Override
public String intercept(ActionInvocation arg0) throws Exception {
return null;
}
}

  抽象类AbstractInterceptor已经实现了Interceptor接口的所有方法,一般情况下,只需继承AbstractInterceptor类,实现interceptor()方法就可以创建自定义拦截器。
  只有当自定义的拦截器需要打开系统资源时,才需要覆盖AbstractInterceptor类的init()方法和destroy()方法。与实现Interceptor接口相比,继承AbstractInterceptor类的方法更为简单

3.3 继承MethodFilterInterceptor

// 功能:定制拦截器拦截的方法
// 定制哪些方法需要拦截,哪些方法不需要拦截
public class MyInterceptor extends MethodFilterInterceptor{ @Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
// 前处理
System.out.println("MyInterceptor的前处理");
// 放行
String result = invocation.invoke();
// 后处理
System.out.println("MyInterceptor的后处理");
return result;
// 不放行,直接跳转到一个结果页面(不执行后续的拦截器以及Action,直接交给Result处理结果.进行页面跳转)
// return "success";
} }

  MethodFilterInterceptor是AbstractInterceptor的子类,该类中提供了两个属性,可以告知拦截器对哪些方法进行拦截或者对哪些方法排除。这种方法在开发中最常用

  

四、配置拦截器

<package name="interceptor" namespace="/" extends="struts-default">
<interceptors>
<!-- 1.注册拦截器 -->
<interceptor name="myInterceptor" class="cn.itcast.interceptor.MyInterceptor"></interceptor>
<!-- 2.注册拦截器栈 -->
<interceptor-stack name="myStack">
<!-- 引入自定义拦截器(建议放在20个拦截器之前) -->
<interceptor-ref name="myInterceptor">
<!-- 指定哪些方法不拦截
<param name="excludeMethods">add,delete</param> -->
<!-- 指定哪些方法要拦截 -->
<param name="includeMethods">add,delete</param>
</interceptor-ref>
<!-- 引入默认的拦截器栈(20个) -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 3.指定包中的默认拦截器栈 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref> <action name="Demo1Action_*" class="cn.itcast.action.Demo1Action" method="{1}">
<result name="success" type="dispatcher">/index.jsp</result>
</action>
</package>

struts2学习笔记(六)—— 拦截器的更多相关文章

  1. Struts2学习笔记(拦截器配置添加)

    一.拦截器工作原理: 根据Struts2的工作原理图,拦截器在action执行前进行顺序调用,之后执行Action并返回结果字符串,再逆序调用拦截器.(结构类似递归方式...)大部分时候,拦截器方法都 ...

  2. Struts2 学习笔记18 拦截器原理分析

    我们来进行一下拦截器的原理分析,从Struts2的源代码开始,然后我们手动创建一个项目进行模拟.(源代码需要下载然后添加好才能看到)我们可以用Debug来读源码. 从doFilter开始执行,流程如图 ...

  3. Struts2学习笔记五 拦截器

    拦截器,在AOP中用于在某个方法或字段被访问之前,进行拦截,然后在之前或之后加入某些操作.拦截是AOP的一种实现策略. Struts2中,拦截器是动态拦截Action调用的对象.它提供了一种机制可以使 ...

  4. SpringMVC 学习笔记(六)拦截器

    5.1.处理器拦截器简介 Spring Web MVC的处理器拦截器(如无特殊说明,下文所说的拦截器即处理器拦截器) 类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理. ...

  5. Struts2学习笔记(六)——Action处理请求参数

    在struts2框架中关于Action处理请求参数有两种方案(三个方式),表单属性的名称应该和在Action类中定义的成员属性或者在JavaBean中定义的成员属性名称一样: 1.属性驱动 1)直接在 ...

  6. struts2学习(6)自定义拦截器-登录验证拦截器

    需求:对登录进行验证,用户名cy 密码123456才能登录进去:  登录进去后,将用户存在session中: 其他链接要来访问(除了登录链接),首先验证是否登录,对这个进行拦截: com.cy.mod ...

  7. SpringMVC学习笔记:拦截器和过滤器

    首先说明一下二者的区别: 1. 拦截器基于java的反射机制,而过滤器是基于函数回调 2. 拦截器不依赖于servlet容器,过滤器依赖servlet容器 3. 拦截器只能对action请求起作用,而 ...

  8. SpringMVC学习笔记九:拦截器及拦截器的简单实用

    SpringMVC中的interceptor拦截器是非常重要的,它的主要作用就是拦截指定的用户请求,并进行相应的预处理和后处理. 拦截时间点在"处理器映射器根据用户提交的请求映射出所要执行的 ...

  9. struts2学习笔记--拦截器(Interceptor)和登录权限验证Demo

    理解 Interceptor拦截器类似于我们学过的过滤器,是可以在action执行前后执行的代码.是我们做web开发是经常使用的技术,比如权限控制,日志.我们也可以把多个interceptor连在一起 ...

  10. struts2学习笔记(5)---自己定义拦截器

    什么是拦截器? struts2中拦截器分为Struts2定义好的拦截器和自己定义的拦截器. 其作用是在一个Action运行之前进行拦截,在Action运行之后又增加某些操作. 实现原理 当请求一个Ac ...

随机推荐

  1. easylogging++学习记录(二):流式日志

    easylogging++日志库流式日志的写入,依赖于el::base::Writer类的析构,以debug日志为例:具体代码如下: #define LOG(LEVEL) CLOG(LEVEL, EL ...

  2. errant-transactions

    https://www.percona.com/blog/2015/12/02/gtid-failover-with-mysqlslavetrx-fix-errant-transactions/ 使用 ...

  3. 八数码问题——A*大法好

    [描述] 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示. 空格周围的棋子可以移到空格中. 要求解的问题是:给出一种初始布局(初始状态)和目标布局( ...

  4. laravel中的文件上传到本地+七牛云上传

    首先在filesystems.php 配置好上传的文件的目录起名为upload 在Storage/目录下面 目录下面的app/upload 如果没有这个文件会自动创建 这里的名字upload名字是跟控 ...

  5. Topic modeling【经典模型】

    http://www.cs.princeton.edu/~blei/topicmodeling.html Topic models are a suite of algorithms that unc ...

  6. Extend volumn in ubuntu 14.04

    运行环境: ubuntu 14.04, VMware12.5.7 1. VMware上点击 虚拟机->设置->硬盘(SCSI)->扩展选项,设置自己希望的ubuntu磁盘运行空间大小 ...

  7. 基于 EntityFramework 的数据库主从读写分离架构(2)- 改进配置和添加事务支持

        回到目录,完整代码请查看(https://github.com/cjw0511/NDF.Infrastructure)中的目录:      src\ NDF.Data.EntityFramew ...

  8. 复习扩展方法 涉及委托,这里我使用自定义委托类型 public delegate bb MyFunc<in T,out bb> (T arg)

    using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Text; ...

  9. VS code docker 调试 asp.net core

    前言 .net core的诞生就是为了解决跨平台的事情的,所以.net core app运行在linux.macOS.docker上也不是什么新鲜事了. 相信已经有不少.net core的项目已经部署 ...

  10. SVN常见问题及解决方式(一)

    1.每天早上上班要update SVN,每天下班要commit SVN.2.查看是谁动了我的代码,右键 tortoise 后查看 log 日志.3.文件被别人删除,在空白处右击,show log,可以 ...