Struts2拦截器工作原理

  拦截器围绕着 Action和 Result的执行而执行。 Struts2拦截器的工作方式如图10.2所示。从上图中可以看出, Struts2拦截器的实现原理和 Servlet Filter的实现原理差不多,以链式执行对真正要执行的方法( execute()进行拦截。首先执行 Action配置的拦截器,在 Action和 Result执行之后,拦截器再一次执行(与先前调用相反的顺序),在此链式的执行过程中,任何一个拦截器都可以直接返回,从而终止余下的拦截器、 Action及 Result的执行。

  当 Actioninvocation的moke(方法被调用时,开始执行 Action配置的第一个拦截器,拦截器做出相应处理后会再次调用 Actioninvocation的 invoke()方法, Actioninvocation对象负责跟踪执行过程的状态,并且把控制权交给合适的拦截器。 Actioninvocation通过调用拦截器的 Intercept()方法将控制权转交给拦截器。因此,拦截器的执行过程可以看作一个递归的过程,后续拦截器继续执行,直到最后一个拦截器, invoke()方法会执行 Action。

拦截器有一个三阶段的、有条件的执行周期,如下所示:
(1)做一些 Action执行前的预处理。拦截器可以准备、过滤、改变或者操作任何可以访问的数据,包括 Action。
(2)调用 Actioninvocation的 evoke()方法将控制权转交给后续的拦截器或者返回结果字符串终止执行。如果拦截器决定请求的处理不应该继续,可以不调用 invoke()方法,而是直接返回一个控制字符串。通过这种方式,可以停止后续的执行,并且决定将哪个结果呈现给客户端。
(3)做一些 Action执行后的处理。此时拦截器依然可以改变可以访问的对象和数据,只是此时框架已经选择了一个结果呈现给客户端了

自定义拦截器例子:

(1)自定义拦截器类

 package cn.test.interceptor;

 import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class MyTimeIntercepter extends AbstractInterceptor { private static final long serialVersionUID = 1L; @Override
public String intercept(ActionInvocation invocation) throws Exception {
// 1.执行Action之前的工作:获取开始执行时间
long startTime = System.currentTimeMillis();
System.out.println("执行Action之前的工作,开始时间:" + startTime);
// 2.执行后续拦截器或Action
String result = invocation.invoke();
// 1.执行Action之后的工作:计算并输出执行时间
long endTime = System.currentTimeMillis(); System.out.println("执行Action之后的工作,结束时间:" + endTime);
System.out.println("总共用时:" + (endTime - startTime));
return result;
} }
   mytimerinterceptor拦截器记录动作执行所花费的时间,代码很简单。 Intercept()方法是拦截器执行的入口方法,需要注意的是它接收 Actioninvocation的实例。
  当 Intercept()方法被调用时,拦截器开始记录开始时间(也就是进行预处理的工作),接着 mytimerinterceptor 拦截器调用 ActionInvocation实例的 invoke()方法,将控制权转交给剩余的拦截器和 Action,因为记录执行时间没有理由终止执行,所以 My T imer Interceptor拦截器总是调用 invoke()方法。
  在调用 invoke()方法后, My T imer Interceptor拦截器等待这个方法的返回值。虽然这个结果字符串告诉 My Timer Interceptor拦截器哪个结果会被呈现,但并未指出 Action是否执行(可能剩余的拦截器终止了执行操作)。无论 Action是否执行,当 invoke()方法返回时,就表明某个结果已经被呈现了(响应页面已经生成完毕)。
  获得结果字符串之后, My Timer Interceptor拦截器记录了执行的用时,在控制台进行了输出。此时拦截器可以使用结果字符串做一些操作,但是在这里不能停止或者改变响应。对于
My T imer Interceptor拦截器而言,它不关心结果,因此它不查看返回的结果字符串。
  MyTimer Interceptor拦截器执行到最后,返回了从 invoke()方法获得的结果字符串,从而使递归又回到了拦截器链,使前面的拦截器继续执行它们的后续处理工作。 
(2) struts.xml 中拦截器配置
 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="default" namespace="/" extends="struts-default">
<!-- 配置默认的行为 -->
<default-action-ref name="defaultAction"></default-action-ref>
<!-- 配置默认action -->
<action name="defaultAction">
<result type="redirect">/error.jsp</result>
</action>
</package> <!-- 拦截器配置 -->
<package name="intercepter" namespace="/" extends="struts-default">
<!-- interceptors元素中使用interceptor子元素定义拦截器 -->
<interceptors>
<!-- interceptor元素name属性:拦截器的名称,class:自定义拦截器类的全限定类名-->
<interceptor name="myTime" class="cn.test.interceptor.MyTimeIntercepter"></interceptor>
<interceptor-stack name="myTimeStack">
<interceptor-ref name="myTime"></interceptor-ref> <!-- 把自定义的拦截器设置为栈的顶部 -->
<interceptor-ref name="defaultStack"></interceptor-ref> <!--调用struts默认的拦截器-->
</interceptor-stack>
</interceptors> <!--浏览器输入http://localhost:8080/strutsstu4/index并访问,会触发拦截器的执行,计算拦截器执行的时间-->
<action name="index">
<result >/index.jsp</result>
<interceptor-ref name="myTimeStack"></interceptor-ref> <!-- 当访问index这个actio时,让myTimeStack这个拦截器栈去进行拦截 -->
</action>
</package> </struts>

(3)视图页面:

index.jsp
 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head> <body>
This is index page. <br>
</body>
</html>

error.jsp

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'success.jsp' starting page</title>
</head> <body>
This is error page. <br>
</body>
</html>

(4)部署并测试

浏览器输入http://localhost:8080/strutsstu4/index并访问,会触发拦截器的执行,控制台打印拦截器执行的时间,页面跳转到index.jsp,如下:

如果访问一个没有对应action的URL,比如   http://localhost:8080/strutsstu4/sss 则执行默认的action,替换调404报错页面

示例代码下载地址   https://github.com/liuch0228/Struts2SSH.git

Struts2基础-4 -struts拦截器的更多相关文章

  1. Struts2基础-4-2 -struts拦截器实现权限控制案例+ 模型驱动处理请求参数 + Action方法动态调用

    1.新建项目,添加jar包到WEB-INF目录下的lib文件夹,并添加到builde path里面 整体目录结构如下 2.新建web.xml,添加struts2核心过滤器,和默认首页 <?xml ...

  2. Struts2基础学习(五)—拦截器

    一.概述 1.初识拦截器      Interceptor 拦截器类似前面学过的过滤器,是可以在action执行前后执行的代码,是我们做Web开发经常用到的技术.比如:权限控制.日志等.我们也可以将多 ...

  3. struts 拦截器 Interceptor

         拦截器是AOP中的概念,它本身是一段代码,可以通过定义“织入点”,来指定拦截器的代码在“织入点”的前后执行,从而起到拦截的作用.正如上面 Struts2的Reference中讲述的,Stru ...

  4. (转)Struts 拦截器

    一.拦截器是怎么实现: 实际上它是用Java中的动态代理来实现的 二.拦截器在Struts2中的应用 对于Struts2框架而言,正是大量的内置拦截器完成了大部分操作.像params拦截器将http请 ...

  5. [置顶] 使用struts拦截器+注解实现网络安全要求中的日志审计功能

    J2EE项目中出于安全的角度考虑,用户行为审计日志功能必不可少,通过本demo可以实现如下功能: 1.项目中记录审计日志的方法. 2.struts拦截器的基本配置和使用方法. 3.struts拦截器中 ...

  6. 利用Struts拦截器限制上传图片的格式和大小

    在这之前 Struts的一个核心功能就是大量的拦截器,既然是框架,那么自然也就贴心地为我们准备好了各种常用的功能,比如这里即将讨论的如何限制上传图片的格式和大小.那么既然是使用Struts已经写好的拦 ...

  7. struts拦截器的知识

    如何使用struts2拦截器,或者自定义拦截器.特别注意,在使用拦截器的时候,在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈defaultStack,如下(这里我是引用了str ...

  8. 【struts2】预定义拦截器

    1)预定义拦截器 Struts2有默认的拦截器配置,也就是说,虽然我们没有主动去配置任何关于拦截器的东西,但是Struts2会使用默认引用的拦截器.由于Struts2的默认拦截器声明和引用都在这个St ...

  9. 使用struts2中默认的拦截器以及自定义拦截器

    转自:http://blog.sina.com.cn/s/blog_82f01d350101echs.html 如何使用struts2拦截器,或者自定义拦截器.特别注意,在使用拦截器的时候,在Acti ...

随机推荐

  1. gitlab+jenkins自动化打包APK

    前置条件: 环境搭建,jenkins需要的插件看这里: gitlab+jenkins自动化打包IOS 配置思路: step1: 搭建sdk,gradle运行环境,参照: CentOS7下安装安装and ...

  2. 解决Win7部分便笺的元数据已被损坏的方法

    Win7部分便笺的元数据已被损坏的方法 我们使用键盘上"Win+F"组合键搜索功能,直接找到"inkobj.dll"这个文件,一般会搜索出来好多,先随便选一个. ...

  3. Oracle 11g修改默认端口1521为其他值

    1.修改listener.ora 打开文件D:\app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN\listener.ora,修改PORT ...

  4. Python模块学习之xlrd、xlutils、openpyxl 读写/追加Excel文件

    Python操作Excel的四个工具包 xlrd: 对Excel进行读相关操作,注意只能操作 .xls xlwt: 对Excel进行写相关操作,注意只能操作 .xls,且只能创建一个全新的Excel然 ...

  5. maven基础--IDEA集成

    创建项目 构建项目 查找依赖 依赖范围 provided:已提供依赖范围.编译和测试有效,运行无效.如servlet-api,在项目运行时,tomcat等容器已经提供

  6. Chrome开启多线程下载

    Chrome多线程下载也和标签页预览一样属于Google测试中的功能,可通过在地址栏输入chrome://flags/,然后在搜索框中输入Parallel downloading,选择enabled, ...

  7. Map遍历方式

    entrySet 推荐 最常用,性能很好 示例: for (Map.Entry<Integer, Integer> entry : map.entrySet()) { System.out ...

  8. Codeforces 1000E We Need More Bosses (边双连通+最长链)

    <题目链接> 题目大意:给定一个$n$个节点$m$条边的无向图,问你对任意两点,最多有多少条特殊边,特殊边指删除这条边后,这两个点不能够到达. 解题分析: 特殊变其实就是指割边,题意就是问 ...

  9. 【学习总结】GirlsInAI ML-diary day-20-初识 Kaggle

    [学习总结]GirlsInAI ML-diary 总 原博github链接-day20 初识kaggle 1-注册一个账号(由于被谷歌收购,因此可能需要梯子) 2-Competition - 学会看一 ...

  10. XMPP即时通讯协议使用(六)——开发Openfire聊天记录插件

    转载地址:http://www.cnblogs.com/hoojo/archive/2013/03/29/openfire_plugin_chatlogs_plugin_.html 开发环境: Sys ...