拦截器的使用 实现AOP

转自http://www.cnblogs.com/fmricky/archive/2010/05/24/1742514.html

1、什么是拦截器(Interceptor)

拦截器是动态拦截Action调用的对象。它提供了一种机制,使开发者可以定义一段代码,在Action执行之前或之后被调用执行,也可以在一个Action执行前阻止其执行,同时也可以提取Action中可重用部分的方式。通俗一点说,拦截器是一个实现了一定功能的类,它以一种可插拔的方式被定义在某个Action执行的之前或之后,用来完成特定的功能。

2、拦截器的结构

先来看下拦截器的声明周期

图中,我们可以发现,Struts2的Interceptor一层一层,把Action包裹在最里面。这样的结构,大概有以下一些特点:

  1. 整个结构就如同一个堆栈,除了Action以外,堆栈中的其他元素是Interceptor
  2. Action位于堆栈的底部。由于堆栈"先进后出"的特性,如果我们试图把Action拿出来执行,我们必须首先把位于Action上端的Interceptor拿出来执行。这样,整个执行就形成了一个递归调用
  3. 每个位于堆栈中的Interceptor,除了需要完成它自身的逻辑,还需要完成一个特殊的执行职责。这个执行职责有3种选择:
  • 中止整个执行,直接返回一个字符串作为resultCode
  • 通过递归调用负责调用堆栈中下一个Interceptor的执行
  • 如果在堆栈内已经不存在任何的Interceptor,调用Action

3、如何使用拦截器

1、Struts 2内置拦截器的介绍

2、部署拦截器

为了能够正常使用拦截器,首先我们必须在struts.xml中正确部署拦截器。具体的做法为在<interceptor></interceptor>标签对内使用<interceptor/>标签引入具体拦截器,需要指定拦截器的名称和类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="wwfy" extends="struts-default">
        <interceptors>
            <interceptor name="拦截器名称1" class="拦截器类1" />
            <interceptor name="拦截器名称2" class="拦截器类2" />
            ………………………………………………………………………………………………………………………………………………
            <interceptor name="拦截器名称N" class="拦截器类N" />
        </interceptors>
         
        <!--省略Action配置信息-->
    </package>
</struts>

3、为Action应用添加拦截器配置

部署好拦截器之后,我们就可以利用拦截器为指定的Action应用添加功能了。具体的做法是在<action></action>标签对内使用<interceptor-ref/>标签引入所需的拦截器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="wwfy" extends="struts-default">
        <!--省略拦截器配置信息-->
         
        <action name="Action名" class="Action类">
            <!--省略Action结果配置信息-->
            <interceptor-ref name="defaultStack"/>
            <interceptor-ref name="拦截器名1"/>
            <interceptor-ref name="拦截器名2"/>
            ……………………………………………………………………………………………………
            <interceptor-ref name="拦截器名N"/>
        </action>
    </package>
</struts>

当我们单独为某个Action单独配置拦截器的时候,系统默认的拦截器将会失效。此时为了Action仍然能够顺利执行,我们一般要通过<interceptor-ref name="defaultStack"/>手动引入defaultStack。

4、拦截器参数设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="wwfy" extends="struts-default">
        <interceptors>
            <interceptor name="拦截器名称" class="拦截器类" >
                <param name="参数名">参数值</param>
            </interceptor>
        </interceptors>
         
        <action name="Action名" class="Action类">
            <!--省略Action结果配置信息-->
            <interceptor-ref name="拦截器名">
                <param name="参数名">参数值</param>
            </interceptor-ref>
        </action>    
    </package>
</struts>

4、如何使用拦截器栈

1、部署拦截器栈

一个拦截器栈可以包括一个或者多个拦截器,也可以包括其他拦截器栈。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="wwfy" extends="struts-default">
        <interceptors>
            <interceptor name="拦截器名称1" class="拦截器类1" />
            <interceptor name="拦截器名称2" class="拦截器类2" />
            ………………………………………………………………………………………………………………………………………………
            <interceptor name="拦截器名称N" class="拦截器类N" />
             
            <interceptor-stack name="拦截器栈1">
                <interceptor-ref name="拦截器名称1"/>
                <interceptor-ref name="拦截器名称2"/>
                <interceptor-ref name="拦截器名称N"/>
            </interceptor-stack>
             
            <interceptor-stack name="拦截器栈2">
                <interceptor-ref name="拦截器栈1"/>
                <interceptor-ref name="拦截器名称3"/>
            </interceptor-stack>
        </interceptors>  
    </package>
</struts>

2、为Action应用添加拦截器栈配置

这部分和拦截器的配置一样,可通过<interceptor-ref/>标签引入

5、如何自定义拦截器

自定义拦截器有2种实现方式,一种是实现Interceptor接口,另一种是继承AbstractInterceptor类

1、实现Interceptor接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package wwfy.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
@SuppressWarnings("serial")
public class CustomInterceptor1 implements Interceptor {
    public void destroy() {
        // TODO Auto-generated method stub
    }
    public void init() {
        // TODO Auto-generated method stub
    }
    public String intercept(ActionInvocation invocation) throws Exception {
        System.out.println("--------拦截器开始----------");
        String result = invocation.invoke();
        System.out.println("--------拦截器结束----------");
        return result;
    }
}

2、继承AbstractInterceptor类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package wwfy.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
@SuppressWarnings("serial")
public class CustomInterceptor2 extends AbstractInterceptor {
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        System.out.println("--------拦截器开始----------");
        String result = invocation.invoke();
        System.out.println("--------拦截器结束----------");
        return result;
    }
}

3、invocation.invoke()的作用

在这个实现类中,实际上已经实现了最简单的拦截器的雏形。或许大家对这样的代码还比较陌生,这没有关系。我在这里需要指出的是一个很重要的方法invocation.invoke()。这是ActionInvocation中的方法,而ActionInvocation是Action调度者,所以这个方法具备以下2层含义:

  1. 如果拦截器堆栈中还有其他的Interceptor,那么invocation.invoke()将调用堆栈中下一个Interceptor的执行。
  2. 如果拦截器堆栈中只有Action了,那么invocation.invoke()将调用Action执行。

所以,我们可以发现,invocation.invoke()这个方法其实是整个拦截器框架的实现核心。基于这样的实现机制,我们还可以得到下面2个非常重要的推论:

  1. 如果在拦截器中,我们不使用invocation.invoke()来完成堆栈中下一个元素的调用,而是直接返回一个字符串作为执行结果,那么整个执行将被中止。
  2. 我们可以以invocation.invoke()为界,将拦截器中的代码分成2个部分,在invocation.invoke()之前的代码,将会在Action之前被依次执行,而在invocation.invoke()之后的代码,将会在Action之后被逆序执行。

由此,我们就可以通过invocation.invoke()作为Action代码真正的拦截点,从而实现AOP。

4、拦截器的执行顺序

定义中有这样一个拦截器栈

1
2
3
4
5
6
<interceptor-stack name="xaStack">  
  <interceptor-ref name="thisWillRunFirstInterceptor"/>  
  <interceptor-ref name="thisWillRunNextInterceptor"/>  
  <interceptor-ref name="followedByThisInterceptor"/>  
  <interceptor-ref name="thisWillRunLastInterceptor"/>  
</interceptor-stack>

整个拦截器栈的执行顺序为

转载于:https://www.cnblogs.com/wwicked/articles/4455467.html

struts2中拦截器的使用相关推荐

  1. struts2中拦截器与过滤器

    一.过滤器 Servlet过滤器是在 java Servlet 2.3 中定义的,它能够对Servlet容器中的请求和响应对象,进行检查和修改. 过滤器可以过滤所有的请求 过滤器:是在javaweb中 ...

  2. struts2中拦截器和过滤器的比较

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

  3. Struts2之拦截器篇

    拦截器是Struts2框架的核心和基础,Struts2绝大多数功能都是通过拦截器来完成的,当StrutsPrepareAndExecuteFilter拦截到用户请求后,大量拦截器会对该请求进行处理,然 ...

  4. struts2自定义拦截器并配置拦截器使其生效

    首先编写一个struts2的拦截器,要继承 MethodFilterInterceptor 并获取其中的方法 package star.july.d_interceptor;import com.op ...

  5. (转)Struts2的拦截器

    http://blog.csdn.net/yerenyuan_pku/article/details/68648101 Struts2的拦截器 拦截器的概述 拦截器,在AOP(Aspect-Orien ...

  6. Struts2 自定义拦截器

    所属栏目:AbstractInterceptor 如果要编写自定义拦截器,那么可以只用实现com.opensymphony.xwork2.interceptor.Interceptor这个接口即可. ...

  7. Struts2【拦截器】就是这么简单

    2019独角兽企业重金招聘Python工程师标准>>> 什么是拦截器 拦截器Interceptor.....拦截器是Struts的概念,它与过滤器是类似的...可以近似于看作是过滤器 ...

  8. 关于Spring中拦截器的使用

    关于Spring中拦截器的使用 1 拦截器的概述 1 拦截器说明及应用场景 2 Spring中的拦截器 HandlerInterceptor 3 流程说明 2 简单使用案例 1 准备环境 1 准备文件 ...

  9. struts2 18拦截器详解(五)

    I18nInterceptor 该拦截器处理defaultStack第四的位置,是用来方便国际化的,如果说我们的一个Web项目要支持国际化的话,通常的做法是给定一个下拉框列出所支持的语言,当用户选择了 ...

最新文章

  1. mysql 单选字段_mysql字段类型
  2. go标准库的学习-crypto/sha1
  3. 全面理解Javascript闭包和闭包的几种写法及用途【转】
  4. ISA Server 2006 安全保障指南
  5. 【数据分析】关于学习SQL的五个常见问题?
  6. Oracle中的Raw类型解释
  7. node.js Stream Buffer FsPromise
  8. 高手经验:一个新手的verilog学习经验
  9. QtDesigner如何添加工具栏toolBar
  10. Mac 链接达梦数据库 DmJdbcDriver18.jar下载
  11. java dagger2_Dagger2用法整理
  12. 稀疏光流python_《稀》字意思读音、组词解释及笔画数 - 新华字典 - 911查询
  13. linux测试上行带宽,linux服务器上传下载带宽测试
  14. BlueCoat SG设备对非标准HTTPS应用访问提示不可信任发行者证书问题解决
  15. 大学学计算机需要英语,大学学什么才能不被计算机淘汰
  16. python 语音处理工具包AudioSegment的基本使用
  17. 关于WPF的资源引用问题
  18. 多个图片合并为一个压缩包下载
  19. 清华大学提出APDrawingGAN:人脸照片秒变艺术肖像画,已被CVPR 2019录取
  20. 【Matlab生物电信号】生物电信号仿真【含GUI源码 684期】

热门文章

  1. springsession 实现session 共享
  2. Bash shell的内建命令:type
  3. ORA-28056:Writing audit records to Windows Even...
  4. PowerTip of the Day-How Much RAM Do You Have?
  5. 使用Prometheus+Grafana 监控MySQL/MONGODB
  6. mysqldumper 与 Innobackupex的备份和恢复操作实验过程
  7. oracle trace文件解读
  8. Android开发中java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx}: java.lang.NullPoi
  9. Linux下mp3文件的乱码问题
  10. Android.text.TextUtils类