java 拦截器ajax_(转)拦截器深入实践 - JAVA XML JAVASCRIPT AJAX CSS - BlogJava

Interceptor的定义

我们来看一下Interceptor的接口的定义:

Java代码 icon_copy.gif

publicinterfaceInterceptorextendsSerializable {

/**

* Called to let an interceptor clean up any resources it has allocated.

*/

voiddestroy();

/**

* Called after an interceptor is created, but before any requests are processed using

* {@link #intercept(com.opensymphony.xwork2.ActionInvocation) intercept} , giving

* the Interceptor a chance to initialize any needed resources.

*/

voidinit();

/**

* Allows the Interceptor to do some processing on the request before and/or after the rest of the processing of the

* request by the {@link ActionInvocation} or to short-circuit the processing and just return a String return code.

*

* @return the return code, either returned from {@link ActionInvocation#invoke()}, or from the interceptor itself.

* @throws Exception any system-level error, as defined in {@link com.opensymphony.xwork2.Action#execute()}.

*/

String intercept(ActionInvocation invocation)throwsException;

}

public interface Interceptor extends Serializable {

/**

* Called to let an interceptor clean up any resources it has allocated.

*/

void destroy();

/**

* Called after an interceptor is created, but before any requests are processed using

* {@link #intercept(com.opensymphony.xwork2.ActionInvocation) intercept} , giving

* the Interceptor a chance to initialize any needed resources.

*/

void init();

/**

* Allows the Interceptor to do some processing on the request before and/or after the rest of the processing of the

* request by the {@link ActionInvocation} or to short-circuit the processing and just return a String return code.

*

* @return the return code, either returned from {@link ActionInvocation#invoke()}, or from the interceptor itself.

* @throws Exception any system-level error, as defined in {@link com.opensymphony.xwork2.Action#execute()}.

*/

String intercept(ActionInvocation invocation) throws Exception;

}

Interceptor的接口定义没有什么特别的地方,除了init和destory方法以外,intercept方法是实现整个拦截器机制的核心方法。而它所依赖的参数ActionInvocation则是我们之前章节中曾经提到过的著名的Action调度者。

我们再来看看一个典型的Interceptor的抽象实现类:

Java代码 icon_copy.gif

publicabstractclassAroundInterceptorextendsAbstractInterceptor {

/* (non-Javadoc)

* @see com.opensymphony.xwork2.interceptor.AbstractInterceptor#intercept(com.opensymphony.xwork2.ActionInvocation)

*/

@Override

publicString intercept(ActionInvocation invocation)throwsException {

String result =null;

before(invocation);

// 调用下一个拦截器,如果拦截器不存在,则执行Action

result = invocation.invoke();

after(invocation, result);

returnresult;

}

publicabstractvoidbefore(ActionInvocation invocation)throwsException;

publicabstractvoidafter(ActionInvocation invocation, String resultCode)throwsException;

}

public abstract class AroundInterceptor extends AbstractInterceptor {

/* (non-Javadoc)

* @see com.opensymphony.xwork2.interceptor.AbstractInterceptor#intercept(com.opensymphony.xwork2.ActionInvocation)

*/

@Override

public String intercept(ActionInvocation invocation) throws Exception {

String result = null;

before(invocation);

// 调用下一个拦截器,如果拦截器不存在,则执行Action

result = invocation.invoke();

after(invocation, result);

return result;

}

public abstract void before(ActionInvocation invocation) throws Exception;

public abstract void after(ActionInvocation invocation, String resultCode) throws Exception;

}

在这个实现类中,实际上已经实现了最简单的拦截器的雏形。或许大家对这样的代码还比较陌生,这没有关系。我在这里需要指出的是一个很重要的方法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。

Interceptor拦截类型

从上面的分析,我们知道,整个拦截器的核心部分是invocation.invoke()这个函数的调用位置。事实上,我们也正式根据这句代码的调用位置,来进行拦截类型的区分的。在Struts2中,Interceptor的拦截类型,分成以下三类:

1. before

before拦截,是指在拦截器中定义的代码,它们存在于invocation.invoke()代码执行之前。这些代码,将依照拦截器定义的顺序,顺序执行。

2. after

after拦截,是指在拦截器中定义的代码,它们存在于invocation.invoke()代码执行之后。这些代码,将一招拦截器定义的顺序,逆序执行。

3. PreResultListener

有的时候,before拦截和after拦截对我们来说是不够的,因为我们需要在Action执行完之后,但是还没有回到视图层之前,做一些事情。Struts2同样支持这样的拦截,这种拦截方式,是通过在拦截器中注册一个PreResultListener的接口来实现的。

Java代码 icon_copy.gif

publicinterfacePreResultListener {

/**

* This callback method will be called after the Action execution and before the Result execution.

*

* @param invocation

* @param resultCode

*/

voidbeforeResult(ActionInvocation invocation, String resultCode);

}

public interface PreResultListener {

/**

* This callback method will be called after the Action execution and before the Result execution.

*

* @param invocation

* @param resultCode

*/

void beforeResult(ActionInvocation invocation, String resultCode);

}

在这里,我们看到,Struts2能够支持如此多的拦截类型,与其本身的数据结构和整体设计有很大的关系。正如我在之前的文章中所提到的:

downpour 写道

因为Action是一个普通的Java类,而不是一个Servlet类,完全脱离于Web容器,所以我们就能够更加方便地对Control层进行合理的层次设计,从而抽象出许多公共的逻辑,并将这些逻辑脱离出Action对象本身。

我们可以看到,Struts2对于整个执行的划分,从Interceptor到Action一直到Result,每一层都职责明确。不仅如此,Struts2还为每一个层次之前都设立了恰如其分的插入点。使得整个Action层的扩展性得到了史无前例的提升。

Interceptor执行顺序

Interceptor的执行顺序或许是我们在整个过程中最最关心的部分。根据上面所提到的概念,我们实际上已经能够大致明白了Interceptor的执行机理。我们来看看Struts2的Reference对Interceptor执行顺序的一个形象的例子。

如果我们有一个interceptor-stack的定义如下:

Xml代码 icon_copy.gif

那么,整个执行的顺序大概像这样:

23045c94-b72a-3c04-9c6c-06ad4392d743.gif

在这里,我稍微改了一下Struts2的Reference中的执行顺序示例,使得整个执行顺序更加能够被理解。我们可以看到,递归调用保证了各种各样的拦截类型的执行能够井井有条。

请注意在这里,每个拦截器中的代码的执行顺序,在Action之前,拦截器的执行顺序与堆栈中定义的一致;而在Action和Result之后,拦截器的执行顺序与堆栈中定义的顺序相反。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/529678.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java判断有没有修改,java字节码判断对象应用是否被修改

原创1 背景在学习并发的时候看到了ConcurrentLinkedQueue队列的源码,刚开始的时候是看网上的帖子,然后就到IDE里边看源码,发现offer()方法在1.7版的时候有过修改。楼主的问题不是整个方法,而是其中的一截代码“(t ! (t tail))”&…

php接口 含义,php晋级必备:一文读懂php接口特点和使用!

PHP接口与类是什么关系?前面提到了php中抽象类和抽象方法,今天给大家谈谈php中接口技术。在PHP中每个类只能继承一个父类,如果声明的新类继承了抽象类实现了以后,这个新类就不能有其它的父类了。但是在实际中需要继承多个类实现功…

php获取不重复的随机数字,php如何生成不重复的随机数字

【摘要】PHP即“超文本预处理器”,是一种通用开源脚本语言。PHP是在服务器端执行的脚本语言,与C语言类似,是常用的网站编程语言。PHP独特的语法混合了C、Java、Perl以及 PHP 自创的语法。下面是php如何生成不重复的随机数字,让我们…

php header什么意思,php header是什么意思

header函数在PHP中是发送一些头部信息的, 我们可以直接使用它来做301跳转等,下面我来总结关于header函数用法与一些常用见问题解决方法。发送一个原始 HTTP 标头[Http Header]到客户端。标头 (header) 是服务器以 HTTP 协义传 HTML 资料到浏览器前所送出的字串&…

matlab dct稀疏系数,Matlab DCT详解

转自:http://blog.csdn.net/ahafg/article/details/48808443DCT变换DCT又称离散余弦变换,是一种块变换方式,只使用余弦函数来表达信号,与傅里叶变换紧密相关。常用于图像数据的压缩,通过将图像分成大小相等(一般为8*8)…

matlab验潮站,验潮站的作用是什么

验潮站的作用是什么?验潮站的建成投入使用,可实时观测沿海潮汐等观测要素,为潮汐预报、赤潮的发生、风暴潮预警报、海啸预警及海平面变化提供基础数据保障以及预测,同时为科学开发海洋提供有力的支持,为海洋经济健康发展保驾护航…

php收购,php中文网收购全国用户量最大的phpstudy集成开发环境揭秘

phpstudy介绍2008年第一个版本诞生,至今已有9年,该程序包集成最新的ApachePHPMySQLphpMyAdminZendOptimizer,一次性安装,无须配置即可使用,是非常方便、好用的PHP调试环境.该程序不仅包括PHP调试环境,还包括了开发工具、开发手册等.总之学习PHP只需一个包…

oracle lob值是什么,关于Oracle数据库LOB大字段总结

概述在ORACLE数据库中,DBA_OBJECTS视图中OBJECT_TYPE为LOB的对象是什么东西呢?其实OBJECT_TYPE为LOB就是大对象(LOB),它指那些用来存储大量数据的数据库字段。Oracle 11gR2 文档:http://download.oracle.com/docs/cd/E11882_01/Ap…

Oracle19C的dbhome,Windows server 安装Oracle19c (WINDOWS.X64_193000_db_home.zip) 过程碰到的问题总结...

Oracle19c的下载地址:链接: https://pan.baidu.com/s/1snqyViOAoeffAztPes_Tvw提取码: 9kb6Oracle19c的安装过程:解压缩安装包:解压结果 以管理员方式运行setup开始安装 一直默认走到安装完成即可创建用户cmd执行sqlplus命令,输入…

oracle数据库配置管理,Oracle配置管理

一、连接Oracle1、Oracle建立连接的过程无论是通过sqlplus命令连接还是第三方工具远程连接到Oracle,都需要建立客户端与服务端之间的连接。Oracle Net Service组件就是为了用于建立连接的,这个组件在安装Oracle时已经安装。1)在服务器端有一个listener监…

linux内核 默认路由表,[Linux] linux路由表-Go语言中文社区

路由表用于决定数据包从哪个网口发出,其主要判断依据是目标IP地址Linux路由表其实有2个主要概念:按顺序走路由策略,在路由策略对应的路由表中匹配规则路由策略(rule)路由表(table)查看所有的路由策略,32766那个策略最有用,对应的main路由表也是默认展示的…

linux添加源地址ping,实战经验:Linux Source NAT在Ping场景下的应用

原标题:实战经验:Linux Source NAT在Ping场景下的应用有时候,有这样的一种需求:需要修改IP数据包中的源地址,比如,从某一个主机发送Ping包到另一个主机,需要修改源地址为另一个源(通常&#xff…

Linux升级glibc版本汉字乱码,Linux CentOS6升级glibc库过程

CentOS6升级glibc库过程hadoop无法加载native库,可能原因是 glibc库版本过低,需要升级。第一:安装以下软件yum -y install zlib zlib-devel gcc gcc-c libtool openssl openssl-devel automake autoconf libtool pcre*第二、查看系统glibc版本…

linux图形界面 革命,Windows 95带来的革命

CDECDE1993年6月-在“公用桌面环境“是与Sun,惠普,IBM和合资Unix系统实验室。CDE,通用桌面环境(CommonDesktopEnvironment)的缩写。CDE是一种运行于UNIX,基于Motif部件工具箱开发的商业桌面环境。惠普的OpenVMS采用CDE作为标准的桌…

real time linux pdf,【整理】ubuntu real time Linux

ubuntu real timeUbuntu不支持实时可参考看看如何才能支持想要自己编译实时内核的话参考去:下载:The Real Time Preempt Patch然后自己编译即可。对于实时系统所支持的功能和特性以及平台,详见这里提供了 已编译好的实时的Debian相关内容或参…

苹方字体 for linux,苹果苹方字体

苹果苹方字体是一款很实用的字体软件,苹果苹方字体是为中国苹果用户打造的全新字体,共有六种字重,使用方便,能够满足用户在阅读时不同的字体需求,并且苹果苹方字体还可以在安卓、Linux 等其他平台和设备上使用&#xf…

c语言龙贝格积分法实验报告,数值作业:龙贝格算法计算积分C语言实现

数值作业:龙贝格算法计算积分C语言实现数值作业:龙贝格算法计算积分C语言实现根据Romberg算法计算定积分,和变步长的Simpson算法的输入都一样.算法基本分析:输入a,b(积分上下限),n为积分区间等分数,eps为计算精度,我这…

w ndows7文档加密取消,win7文件夹怎么加密?windows7文件加密方法

win7文件夹怎么加密?电脑文件隐私问题一直都是很多用户的关注重点,尤其是自己电脑经常被他人使用的朋友。也许使用第三方软件为文件夹加密比较方便,但如果能够不借助“外力”完成这一任务就更加完美。下面,我们就一起来看看windows7文件加密…

小世界网络模型代码 c 语言,新的小世界网络模型实现文本特征的提取方法与流程...

本发明涉及语义网络技术领域,具体涉及新的小世界网络模型实现文本特征的提取方法。背景技术:目前常用的文本特征提取方法,包括词频-反文档频率方法—TF-IDF、信息增益方法、互信息等方法;TF-IDF的简单结构并不能有效地反映词汇或短…

米4用linux刷机救转,小米4变砖之后如何刷机自救?大神教你小米4线刷救砖方法...

三:使用miflash工具刷机的步骤本工具适用于小米,华为,联想等手机品牌高通版本,不只是小米专用,教程仅供参考,看完一遍后再刷机。第一步:刷机工具安装1.下载小米手机刷机工具MiPhone2015731&…