Struts2的拦截器Struts2的拦截器
可执行方法的类。拦截器(Interceptor)是Struts 2的一种类,它可以动态拦截Action的它提供了一种机制使开发者可以在一个Action执行之前或执行之后插入需要的代码,比如可以在Action执行前阻止其执行,也可以在Action执行后做一些相应的工作。
拦截器是Struts2框架的基石,框架许多功能的完成都是构建在拦截器的基础之上的,比如
类型转换、文件上传与下载的文件类型限制、国际化等。并且Struts2还提供了大量数据校验、
的内置拦截器,这些拦截器完成了框架的大部分任务。
这...
Struts2的拦截器
可执行
的类。拦截器(Interceptor)是Struts 2的一种类,它可以动态拦截Action的它提供了一种机制使开发者可以在一个Action执行之前或执行之后插入需要的代码,比如可以在Action执行前阻止其执行,也可以在Action执行后做一些相应的工作。
拦截器是Struts2框架的基石,框架许多功能的完成都是构建在拦截器的基础之上的,比如
类型转换、文件上传与下载的文件类型限制、国际化等。并且Struts2还提供了大量数据校验、
的内置拦截器,这些拦截器完成了框架的大部分任务。
这里重点介绍拦截器的配置与使用,以及自定义拦截器的实现。
一、理解拦截器
拦截是AOP(面向切面编程)的一种实现策略,在AOP中,某个方法或字段被访问,可以被拦截,然后在其之前或者之后加入某些操作。
Struts2的拦截器体系正是应用了AOP的
暂学,它可以动态拦截Action的某些可执行方,并提供了一种机制,使开发者可以定义在一个Action的可执行方法被行前、后的执行代码。 法
在Struts2中还有一个概念叫拦截器链(常被称为拦截器栈),拦截器栈就是将多个拦截器按一定的顺序联结成一条链,在使用拦截器链时,拦截器链中的拦截器就会按定义的顺序一一被调用。
二、拦截器的工作原理
当请求到达Struts的FilterDispatcher时,Struts会查找配置文件struts.xml,并根据其配置的拦截器对象,将这些对象串成一个列表(1ist),最后逐个调用列表中的拦截器,如图所示。
每一个Action请求都包装在一系列的拦截器内部。拦截器可以在Action执行之前做准备操作,也可以在Action执行之后做回收操作。
1
三、拦截器的意义
要理解拦截器的意义,就不得不先讲DRY规则。
在软件开发领域,有一条规则:Don't Repeat Yourself,这就是DRY规则,它的意思是“不要书写重复的代码”。
在软件开发阶段,往往由于前期的设计不合理,或者缺乏预见性,可能会导致多个地方需要使用相同的代码。
通过拦截器策略就可以很好地解决这个问题,因为它可以在配置文件中指定需要的拦截器,让拦截器的方法在目标方法执行之前,或之后自动执行,这样就完成了通用操作的动态插入。
如果Action需要哪种功能,只需要在配置文件struts.xml中指定引用该拦截器就可以了。
Struts2中定义了许多内置拦截器,它们的功能是大多数Action都需要的,所以在Struts2中就将其配置成为了默认拦截器。
Struts2中内置的拦截器可以帮助完成70%的拦截任务,必要时开发者可以定义自己的拦截器,并在配置文件struts.xml中指定引用自定义的拦截器。
2
四、使用拦截器
, 首先编写拦截器类(或者,利用Struts内置的拦截器)
, 在struts.xml中配置拦截器
五、编写自定义的拦截器
Struts2中定义了一个拦截器接口“Interceptor”,该接口定义如下:
public interface Interceptor extends Serializable
{
void init(); //可选,在拦截器方法intercept()执行之前执行,用于初始化资源
String intercept(ActionInvocation invocation) throws Exception; //必选,是拦截器的核心方法
void destroy(); //可选,在拦截器方法intercept()执行之后执行,用于销毁资源 }
Struts2用一个抽象类实现了这个接口,抽象类是:“AbstractInterceptor”
开发者自定义的拦截器继承这个抽象类即可。
init()方法和destroy()方法,大多数情况下是不需要的。
例【interceptor_leave】部分代码
对于留言板应用程序,主页面上有两个链接,一个是链接到登陆页面,另一个是链接到查看留言,在查看留言页面可以点击“我要留言”打开留言页面;但是,用户必须已经登录,才可提交留言;如果没有登录,提交留言就被拒绝,并且自动转向登录页面。
实现原理是:对提交留言的Action配置拦截器,在执行Action之前先检查用户是否登录。
利用session来做,用户登录后,由登录Action负责把用户名放入session中。拦截器从session中取用户名,如果取出是空值,则拦截;否则,放行。
以下是有关拦截“提交”的拦截器代码:
1、编写一个拦截器类
package com.interceptor;
import java.util.Map;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class LeaveInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation ai) throws Exception
{
3
ActionContext ac = ai.getInvocationContext();
Map
session = (Map)ac.getSession();
String userName = (String)session.get("uesrname");
if((userName != null) && (userName.length() > 0))
{
return ai.invoke(); //放行,把执行控制权转交给LeaveAction
}
else
{
ac.put("sorry", "您还没有登录,请先登录~"); //否则,不放行,保存一条信息,以便在
jsp上显示 login.
return Action.LOGIN; //替被它拦截的Action返回LOGIN
}
}
}
2、struts.xml文件,配置拦截器(包括:定义拦截器、引用拦截器)
//定义要使用的拦截器
//为包配置默认拦截器栈
//登录Action
look.action //直接调用另一个Action
regist.jsp
fail.jsp
//注册Action
registSuccess.jsp
registerror.jsp
4
//查看留言Action
show.jsp
fail.jsp
//提交留言Action
look.action
fail.jsp
login.jsp //被拦截时,返回"login"
//引用系统的拦截器栈
Action //引用上面定义的拦截器,拦截本
六、配置拦截器的语法
首先将某些操作写在拦截器的核心方法中,然后在struts.xml配置文件中为需要这些操作的Action配置已经存在的拦截器,配置包括:“定义”和“引用”。
1(定义拦截器
引入了拦截器机制后,实现了对Action通用操作的可插拔式管理,这样的管理基于struts.xml文件来配置实现。
在struts(xml配置文件中定义一个拦截器的代码如下:
2(定义带参数的拦截器
如果还需要向拦截器传递参数,则需要在元素中加入元素, 配置代码如下:
参数值1<,param>
参数值2<,param>
„„
5
<,interceptors>
3(定义拦截器栈
将多个拦截器合并在一起组成一个拦截器栈(拦截器链),当一个拦截器栈被应用到一个
,必须先执行完拦截器堆栈中的每一个拦截器后,才进入Action的执行。 Action的时
定义拦截器栈可以使用元素,拦截器栈是由多个拦截器组成的。
定义拦截器栈的语法形式如下:
„„„„
<,interceptor-stack>
拦截器栈2中除了包含拦截器4与拦截器5,还包含了拦截器栈1,而拦截器栈1中又包含
有3个拦截器,所以,拦截器栈2共包含有5个拦截器。
4(定义带参数的拦截器栈
系统为开发者提供了两个机会来为拦截器指定参数。
?定义拦截器时指定参数值:这种参数值为拦截器参数的默认值。
?使用拦截器时指定参数:这种参数是在使用该拦截器时动态分配的参数值。
下面是在配置拦截器栈时为拦截器指定参数,语法如下。
参数值1<,param>
„„„„更多拦截器
<,interceptor-stack>
也可以针对一个拦截器堆栈统一指定所有的参数:
参数值1<,param>
success.jsp<,result>
login.jsp<,result>
七、为包(package)配置默认的拦截器
以前在struts.xml文件中配置一个包时,没有为包中的Action指定任何拦截器,则系统默
认拦截器将会起作用。
通常情况下定义包时都会有如下的形式。
7
当继承了struts-default包时,也就继承了它的默认拦截器栈:defaultStack,如果在包中没有为Action指定拦截器时,则defaultStack将会默认地去拦截 Action。
一旦为包中的某个Action指定了某个拦截器,则默认的拦器栈将不会起作用。如果该包中的Action都还需要使用默认拦截器,就要手动配置默认拦截器栈。
在元素,需要指定一个name属性,该name属性值必须是一个已经存在的拦截器(栈)的名字,表明了它是此包的默认拦截器(栈)。
配置文件中包的默认拦截器配置代码片段如下:
!定义一个拦截器
((> !定义一个拦截器栈
„„
<,package>
<,struts>
一个包中只能配置一个默认拦截器。
如果需要把多个拦截器都配置为默认拦截器,可以把这些拦截器定义为一个拦截器栈,然后把这个栈配置为默认拦截器就可以达到目的。
为包(package)配置默认的拦截器(带参数的)
与在Action中使用普通拦截器一样,在配置默认拦截器时也可以为其指定参数,
在元素中使用子元素。
下面是在配置默认拦截器时为拦截器指定参数的示例:
8
<,interceptors>
参数值2<,param>
„„
<,default-interceptor-ref>
„„
八、一下与拦截器相关的配置元素。
?元素:用来定义拦截器。所有的拦截器与拦截器栈都在此元素下定义。可以包含两个子元素,与。
?元素:用来定义拦截器,需要指定两个属性:name指定拦截器的名字, class指定拦截器的类。
?元素:用来定义拦截器栈。
?元素:用来引用其他拦截器或拦截器栈,它可以作为元素、元素的子元素。
?元素:用来为拦截器指定参数,它可以做元素与元素的子元素。
九、Struts2的内置拦截器
Struts 2(0框架的大部工作,都是通过内建拦截器来实现的,比如解析请求参数、参数类型转换、将请求参数值赋值给Action的属性、数据校验等。
Struts 2(0框架中提供了大量的内建拦截器,这些拦截器都是以key-value键值对的形式配置在 struts-default.xml文件中,文件位置:
源文件位置:struts-2.0.14\src\core\src\main\resources\ struts-default.xml
包路径位置:struts2-core-2.0.14.jar\struts-default.xml
代码如下(需要使用时再查阅):
9
10
name指定了拦截器的名字,class指定了该拦截器的实现类。
如果开发者定义的 package继承了Struts 2(0框架的默认包,即:
则可以自由引用struts-default.xml中的拦截器。
下面是对上述内置拦截器的简要介绍:
Alias:在不同请求之间将请求参数在不同名字间转换,但请求的不变。
Chain:让前一个Action的属性可以被后一个Action访问,现在和chain类型的
result()结合使用。
conversionError:将错误从ActionContext中添加到Action的属性字段中。
11
Cookie:使用配置的name与value来指定cookies。
createSession:自动地创建HttpSession,用来为需要使用到HttpSession的拦截器服务。
debugging:提供不同的调试用的页面,来展现内部的数据状况。
,同时将用户带到一个中间的等待页面。 execAndWait:在后台执行Action
exceptio:将异常定位到一个页面。
fileUpload:提供文件上传功能。
i18n:记录用户选择的locale。
logger:输出Action的名字。
modelDriven:如果一个类实现了ModelDriven,将getModel得到的结果放在Value Stack中。
scopedModelDrive:如果一个Action实现了ScopedModelDriven,则这个拦截器会从相应的Scope中取出model调用Action的setModel方法,将其放入Action内部。
params:将请求中的参数设置到Action中去。
prepare:如果Acton实现了preparable,则该拦截器调用Action类的prepare方法。
staticParams:从struts(xml文件中将中的中的内容设置到对应的Action中。
scope:将Action状态存入session和application的简单方法中。
servletConfig:提供访问HttpServletRequest和HttpServletResponse的方法,以Map的方式访问。
time:输出Action执行的时间。
token:通过Token来避免重复提交。
tokenSession:和Token Interceptor一样,不过双击的时候把请求的数据存储在Session中。
validation:使用action-validation(xml文件中定义的内容校验提交的数据。
workflow:调用Action的validate方法,一旦有错误返回,重新定位到INPUT页面。
store:存储或者访问实现ValidationAware接口的Action类出现的消息、错误、字段错误等。
checkbox:添加了checkbox自动处理代码,将没有选中的checkbox的内容设定为false,而html默认情况下不提交没有选中的checkbox。
profiling:通过参数激活profde。
roles:确定用户是否具有JAAS指定的Role,否则不予执行。
Struts 2利用这些拦截器组合了一系列的拦截器栈,也在struts-default.xml文件中:
12
13
input,back,cancel
input,back,cancel
dojo\..*
14
input,back,cancel,browse
input,back,cancel,browse
input,back,cancel
input,back,cancel
上面的配置代码配置了Struts 2(0应用所需要的大部分拦截器栈,很多时候,我们只需要
使用系统的拦截器栈defaultStack即可,因为用户自定义的包继承了struts-default包,而此
包又指定了 defaultStack拦截器栈为默认拦截器栈,系统将自动会把defaultStack拦截器作用
于Action。
十、一个使用内置记时拦截器(timer)的例子
timer是Struts 2(0的一个内置拦截器,可以输出Action的执行时间,所以也可以称它为
耗时拦截器。下面我们就使用这个拦截器来观察Action的执行时间,这也是检测系统瓶颈的一个
重要方法。
创建一个Action,此Action什么也没有做,只是让线程休眠一段时间来模拟程序运行消耗
的时间,代码如下。
15
Action:
package tmp;
import com.opensymphony.xwork2.ActionSupport; public class TimerAction extends ActionSupport {
public String execute()
{
try
{
Thread.sleep(5000);
}
catch(Exception e)
{
e.printStackTrace();
}
return SUCCESS;
}
}
Struts.xml文件:
success.jsp
//使用内置拦截器,上面不需要定义
index.jsp:
<%@page language="java" pageEncoding="UTF-8"%>
16
<%@ taglib prefix="s" uri="/struts-tags"%>
Struts 2.0内置拦截器Timer的作用
Success.jsp
<%@page language="java" pageEncoding="UTF-8"%> <%@taglib prefix="s" uri="/struts-tags"%>
Action程序已经返回.
当返回页面出现在浏览器中时,表明Action执行已经结束,拦截器timer会在控制台输出计时时间,就是Action执行的时间,第一次用的时间最长,因为Action要执行一些初始化,第二次及以后时间会短些。
17
本文档为【Struts2的拦截器】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。