Struts 2拦截器

来源:互联网 发布:mac os怎么切换输入法 编辑:程序博客网 时间:2024/06/06 09:42

学习内容

 拦截器工作原理

 Struts 2自带拦截器

 自定义拦截器

能力目标

 熟悉Struts 2拦截器工作原理

 熟练使用和配置拦截器

本章简介

上一章我们深入学习了Struts 2框架的配置,包括Action的配置、Result的配置等等,使我们对Struts 2框架有了更深的了解。Struts 2的核心包括Action、Result和拦截器。拦截器是Struts 2的一个重要特性,实际上Struts 2框架的核心功能都是由拦截器负责完成的。

拦截器(Interceptor)能动态拦截Action调用的对象。它提供了一种机制使开发者可以在一个Action执行之前或执行之后插入需要的代码,同时它也是提供了一种可以提取Action中可重用代码的方式。本章将重点学习Struts 2拦截器。 

核心技能部分

5.1 Struts 2的拦截器

在第五章学习Struts 2体系结构时已经提到了拦截器,它主要出现在Action执行之前或执行之后,大家可以先回顾一下。对于Web应用程序来说,有很多的业务都是通用的,例如对请求数据的封装、数据的校验、防止表单重复提交等。早期的MVC框架将这些业务功能都写死在核心控制器中了,这直接导致框架的灵活性和可扩展性严重下降。

Struts 2将它的核心功能放到拦截器中实现而不是集中在核心控制器里,并且每个拦截器完成一个业务功能,不同的拦截器还能自由组合,这使得开发人员能够更加高效、灵活的使用Struts 2框架进行开发。

拦截器是动态拦截Action调用的对象,拦截器的方法可以在Action执行之前或之后自动执行,从而将通用的操作动态地插入到Action执行的前后,这跟我们平时组装电脑很类似,业务功能变成了可插拔式,需要哪个功能就“插入”一个拦截器,不需要就“拔出”,非常有利于系统的解耦。

单一的拦截器还可以灵活的组合在一起构成拦截器栈。拦截器是一个类,通过在struts.xml中进行配置来发挥作用。

5.1.1 拦截器工作原理

拦截器围绕着Action和Result的执行而执行,如图5-1-1所示。Action被一系列的拦截器包裹,首先执行Action之前的拦截器,并按照顺序依次执行拦截器1、拦截器2、拦截器3……,在Action和Result执行过之后,拦截器会再一次执行,并按照相反的顺序依次执行,图5-1-2清晰的显示了这种顺序。在这一系列执行过程中,任何一个拦截器都可以直接返回,从而终止余下的拦截器的执行。

图5.1.1  拦截器工作原理


图5.1.2  Struts 2拦截器时序图 

5.1.2 Struts 2自带拦截器

Struts 2框架提供了一系列功能强大的拦截器,它们实现了框架的大部分功能,同时在实际开发中我们也可以灵活应用这些Struts 2自带的拦截器。打开Struts 2源文件中的struts-default.xml文件,如图5.1.3所示,Struts 2自带的拦截器就配置在这个文件里。

 

图5.1.3 Struts 2自带拦截器

单个拦截器由<interceptor>元素配置,name属性设置拦截器的逻辑名,class属性设置拦截器的实现类。

下面对Struts 2自带的拦截器进行简单介绍:

Ø checkbox:添加了对表单中checkbox自动处理的代码,将没有选中的checkbox的内容

设定为false,而HTML默认情况下不提交没有选中的checkbox。

 conversionError:将错误信息从ActionContext中添加到Action的属性字段中。

 createSession:自动创建HttpSession,用来为需要使用到HttpSession的拦截器服务。

 execAndWait:在后台执行Action,同时将用户带到一个中间的等待页面。

 exception:捕获异常并能根据异常类型映射到用户自定义的错误页面。

 fileUpload:提供文件上传功能。

 params:将请求中的参数设置到Action的属性上。

 scope:将Action状态存入session和application的简单方法。

 servletConfig:提供访问HttpServletRequest和HttpServletResponse的方法,以Map的方

式访问。

 token:防止表单重复提交。

 tokenSession:和token一样,不过双击的时候把请求的数据存储在session中。

 validation:执行数据校验。

 workflow:调用Action的validate方法,一旦有错误返回就终止执行流程。

上面列出了Struts 2常用的拦截器,在实际应用中,我们经常需要组合不同的拦截器形成一个拦截器栈,Struts 2框架在struts-default.xml中定义了一个默认的拦截器栈defaultStack,如图5.1.4所示,这个拦截器栈组合了多个拦截器,并且这些拦截器的顺序都是经过精心设计的,能满足大多数Web应用的需求。在struts.xml中,我们自定义的包(package)通常都要继承struts-default包,而此包指定了defaultStack拦截器栈为默认拦截器栈,所以如果用户的自定义包继承了struts-default包,也会自动将defaultStack做为默认拦截器。如果用户没有为Action指定拦截器,系统将会自动把defaultStack拦截器栈作用于此Action。

 

图5.1.4 defaultStack拦截器栈

5.2 配置拦截器

拦截器的使用分为三个步骤:

(1) 实现拦截器类

(2) 在struts.xml中定义拦截器或拦截器栈

(3) 为Action配置拦截器或拦截器栈

如果我们使用的是Struts 2自带的拦截器,那么只需要进行第三步即可;如果我们使用的是自己开发的拦截器,就需要进行以上三步。下面是配置语法。

<struts><package name ="admin" extends="struts-default"><!—定义拦截器 -- ><interceptors><interceptorname="拦截器1" class="拦截器的实现类" />... ...<interceptor-stack name="拦截器栈1"><interceptor-ref name="拦截器1"/><interceptor-ref name="拦截器2"/>... ...</interceptor-stack></interceptors><!—使用拦截器 -- ><action name="checkLogin" class="tmq.action.DefaultAction" ><result name="success">/success.jsp</result><result name="login">/login.jsp</result><interceptor-ref name="拦截器1" /><interceptor-ref name="拦截器栈1"/></action></package></struts>


所有的拦截器或拦截器栈都定义在<interceptors>元素内,单个拦截器由它的子元素<interceptor>s定义,name属性定义拦截器的逻辑名,class属性用来指定拦截器的实现类。

拦截器栈由<interceptor-stack>元素定义,并需要通过子元素<interceptor-ref>来引用已经定义好的拦截器作为栈元素,<interceptor-ref>的name属性用来设置想要引用的拦截器的逻辑名。

定义好拦截器或拦截器栈以后,需要在Action的配置中为<action>元素配置拦截器或拦截器栈,此时使用的也是<interceptor-ref>,name同样设置为想要引用的拦截器的逻辑名,这里可以直接使用Struts的自带的拦截器。

5.3 自定义拦截器

5.3.1 如何使用自定义的拦截器

虽然Struts 2提过了如此丰富的拦截器,但是在实际应用中,我们仍需要自己开发拦截器以满足经常变化的业务需求。

自定义的拦截器类通常需要实现com.opensymphony.xwork2.interceptor.lnterceptor 接口,该接口的源代码如下所示。

public interface Interceptor {void destroy();void init();String intercept (ActionInvocation invocation) throws Exception;}}


该接口定义了三个方法:

 init(),该方法执行于拦截器执行拦截之前,且每个拦截器只执行一次。因此,该方法的

主要用于打开某些资源。

 destroy(),该方法与init()方法对应。在拦截器实例被销毁之前,系统将回调此方法,销

毁在init()方法中打开的资源。

 intercept(Actionlnvocationinvocation),该方法是用户需要实现的拦截器动作,返回一个result配置字符串作为逻辑视图。该方法的ActionInvocation参数包含被拦截的Action的引用,可以通过调用该参数的invoke方法,将控制权转给下一个拦截器或者Action。详见表7-1-1所示。

表7-1-1 Actionlnvocation类的常用方法

方法

描述

Object getAction()

获得与拦截器关联的Action,注意进行强制类型转换。

String invoke()throws Exception

继续执行后面的拦截器或Action,可能抛出任何异常。

除此之外,Struts2还提供了一个com.opensymphony.xwork2.interceptor.Abstractlnterceptor类,该类提供了一个init方法和destroy方法的空实现。如果自定义的拦截器不需要申请资源,就无须实现这两个方法。所以,继承自Abstractlnterccptor类来实现自定义拦截器会更加简便。

示例5.1

考虑一般的WEB应用,基本都可分为前台和后台两部分,后台主要是对整个WEB应用进行管理,所以要使用后台必须先登录,后台部分可能包含了很多的Action和JSP视图,我们必须保证用户不能直接访问后台的每一个Action和JSP视图,或者说要想访问就必须先登录,这属于访问控制,这种情况非常适合使用拦截器来解决,接下来我们使用拦截器重构登录案例,把登录验证用拦截器来实现。

(1) 实现拦截器类

public class LoginInterceptor implements Interceptor {public void destroy() {}public void init() {}public String intercept(ActionInvocation ai) throws Exception {HttpSession session = ServletActionContext.getRequest().getSession();User user = (User)session.getAttribute("loginUser"); if(user!=null)return ai.invoke();   //登录成功则继续执行后面的拦截器或Actionelsereturn "error";}}(2) 实现Action。public class LoginAction extends ActionSupport{private String name;private String pwd;//省略getter和setter方法public String execute(){return SUCCESS;}}


由于我们把登录业务放在了拦截器中实现,所以Action中就无需编写业务实现代码了,直接在execute方法中返回了SUCCESS。

(3) 登录视图页面login.jsp

<body><form action="login.action" method="post"><table width="397" height="169" border="0" align="center"><tr><td colspan="2" align="center">管理员登录</td></tr><tr><td width="163" align="right">登录名称:</td><td width="218"><input name="name" type="text" class="txt"></td></tr><tr><td align="right">登录密码:</td><td><input name="pwd" type="password" class="txt"></td></tr><tr><td colspan="2" align="center"><input type="submit" value="提交"></td></tr></table></form></body>


(4) 在struts.xml配置文件中配置LoginAction的拦截器。

<struts><package name="admin" extends="struts-default"><interceptors><interceptor name="loginInter" class="com.zy.LoginInterceptor"/><interceptor-stack name="loginStack"><interceptor-ref name="defaultStack" /><interceptor-ref name="loginInter" /></interceptor-stack></interceptors><action name="login" class="com.zy.LoginAction"><result name="success" type="redirect">/index.jsp</result><result name="error" type="redirect">/login.jsp</result><interceptor-ref name="loginStack" /></action></package></struts>


在上述代码中,我们首先使用<interceptor>在配置文件中定义了自己开发的拦截器,然后把该拦截器和Struts 2默认的defaultStack组成了一个拦截器栈,最后为名字是“login”的action指定了这个拦截器栈。

如果其他的Action也需要进行登录访问控制,就只需要为该Action配置实现登录验证的拦截器即可。

5.3.2 默认拦截器

通常情况下,WEB应用的后台部分可能包含了很多的Action和JSP视图,为了实现访问控制,我们要给后台的每个Action都配置拦截器,虽然能够实现,但是过于繁琐,更好的解决方案就是给这些后台Action配置一个默认的拦截器(栈)。

默认拦截器(栈)定义在包(package)中,该包(package)中的所有Action都共享使用该默认拦截器(栈),每个包(package)中只能定义一个默认拦截器(栈)。

在struts.xml文件中使用<default-interceptor-ref>元素来配置默认拦截器(栈),它是包(package)的子元素,该元素的name属性值是一个已经定义好的某个拦截器(栈)的名字。参考代码如下所示。

<struts><package name ="admin" extends="struts-default"><interceptors><interceptor name="loginInter" class="com.zy.LoginInterceptor"/><interceptor-stack name="loginStack"><interceptor-ref name="defaultStack" /><interceptor-ref name="loginInter" /></interceptor-stack></interceptors>


<!-- 为此包配置一个默认拦截器或拦截器栈 -- >

<default-interceptor-ref  name="loginStack"/><!-- Action,可以有多个 -- ><action name="login" class="com.zy.LoginAction"><result name="success" type="redirect">/index.jsp</result><result name="error" type="redirect">/login.jsp</result></action><action>……</action>……</package></struts>

注意:

如果包中的某些Action没有显式的指定任何拦截器,则默认拦截器将会起作用。如果包中的某个Action显式指定了某个拦截器,则默认的拦截器将不会起作用,如果该Action还必须使用默认拦截器,那么就需要手动的配置该默认拦截器的引用。

5.4 深入拦截器

通过上面的学习,我们掌握了Struts 2中拦截器类的实现、拦截器的定义以及拦截器的使用,但是这些并不能完全满足实际开发的需求,我们还需要深入学习拦截器,包括拦截器方法过滤、拦截器的拦截顺序等知识。

5.4.1 拦截器方法过滤

在默认情况下,如果我们为某个Action指定了拦截器,那么这个拦截器就会拦截Action中的所有方法。但是有时候,实际需求并不希望拦截Action中所有的方法,而是只需要拦截其中的某些方法,这时就需要使用Struts 2提供的拦截器方法过滤功能。例如:在一个Action中我们实现了对商品的增、删、改、查等业务方法,管理员和普通用户都可以进行增、改、查操作,但是只有管理员可以进行删除操作,因此我们可以通过一个拦截器只拦截Action中的删除方法,在拦截时判断当前的用户是否为管理员。

为了实现拦截器方法过滤,Struts 2提供了一个MethodFilterInterceptor抽象类。这个类重写了AbstractInterceptor类中的intercept方法,但是提供了doIntercept(ActionInvocation invocation)的抽象方法。如果开发者要实现拦截器方法过滤,则应该继承MethodFiledIntercepor抽象类,并重写doIntercept(ActionInvocation invocation)方法。

示例5.2

下面我们通过一个示例来演示如何使用拦截器方法过滤,拦截器可以拦截Action中删除管理员的方法,不拦截添加和查询管理员的方法。

(1) 实现拦截器类,参考代码如下所示。

public class AdminInterceptor extends MethodFilterInterceptor {protected String doIntercept(ActionInvocation ai) throws Exception {System.out.println("拦截器起作用了");return ai.invoke();}}


此处只是为了演示拦截器方法过滤的使用,所以在doIntercept方法中仅仅进行了控制台输出。

(2) 实现Action,参考代码如下所示。

public class AdminAction {public String add(){System.out.println("添加管理员");return "success";}public String query(){System.out.println("查询管理员");return "success";}public String del(){System.out.println("删除管理员");return "success";}}


上述代码分别模拟实现了添加、查询和删除管理员的方法。本示例要求拦截器可以拦截删除管理员的方法,不拦截添加和查询管理员的方法。

(3) struts.xml文件的配置代码如下所示。

<struts><package name="admin" extends="struts-default"><interceptors><interceptor name="adminInter" class="com.zy.AdminInterceptor"/></interceptors><action name="admin_*" class="com.zy.AdminAction" method="{1}"><result name="success" type="redirect">/index.jsp</result><interceptor-ref name="adminInter"><param name="includeMethods">del</param><param name="excludeMethods">query</param></interceptor-ref></action></package></struts>

从上面的代码可以看出,在struts.xml文件中定义实现方法过滤的拦截器与普通拦截器是一样的,都是使用<interceptor>进行定义。不同的是,在为<action>元素指定拦截器时,方法过滤拦截器可以使用<param>元素设置拦截哪些方法,不拦截哪些方法。

<param>元素的name属性是必须的,主要有两个取值:

 includeMethods:设置需要拦截(过滤)的方法,只需把Action中的方法名罗列出来即可,多个方法之间用逗号隔开

 excludeMethods:设置不需要拦截(过滤)的方法,只需把Action中的方法名罗列出来即可,多个方法之间用逗号隔开

注意

如果一个方法既被指定在excludeMethods中,同时又被指定在includeMethods中,则此方法会被拦截,即includeMethods的优先级高于excludeMethods。

如果一个方法既没有被指定在excludeMethods中,同时又没有被指定在includeMethods中,则此方法不会被拦截。

接下来我们开始测试,直接通过URL访问Action并调用相应的方法。

 访问http://localhost:8080/Struts7-adv/admin_add.action,运行效果如图5.1.5所示。

 

图5.1.5 添加管理员

 访问http://localhost:8080/Struts7-adv/admin_query.action,运行效果如图5.1.6所示。

 

图5.1.6 查询管理员

 访问http://localhost:8080/Struts7-adv/admin_del.action,运行效果如图5.1.7所示。

 

图5.1.7 删除管理员

5.4.2 拦截顺序

前面学习拦截器工作原理时,我们介绍了拦截器的执行时序图,首先执行Action之前的拦截器,并按照顺序依次执行拦截器1、拦截器2、拦截器3 ……,在Action和Result执行过之后,拦截器会再一次执行,并按照相反的顺序依次执行,下面我们通过一个案例来演示拦截器的执行顺序。

示例5.3

public class SortInterceptor1 extends AbstractInterceptor{public String intercept(ActionInvocation ai) throws Exception {System.out.println("拦截器1开始执行...");String result=ai.invoke();System.out.println("拦截器1执行完毕...");return result;}}public class SortInterceptor2 extends AbstractInterceptor{public String intercept(ActionInvocation ai) throws Exception {System.out.println("拦截器2开始执行...");String result=ai.invoke();System.out.println("拦截器2执行完毕...");return result;}}public class SortInterceptor3 extends AbstractInterceptor{public String intercept(ActionInvocation ai) throws Exception {System.out.println("拦截器3开始执行...");String result=ai.invoke();System.out.println("拦截器3执行完毕...");return result;}}上述代码创建了三个拦截器类,代码比较简单,这里不再多述。下面是Action类的参考代码。public class SortAction extends ActionSupport {public String execute(){System.out.println("Action执行...");return "success";}}该Action只有一个execute方法,不再多述,重点看下面的struts.xml配置文件,参考代码如下所示。<struts><package name="sort" extends="struts-default"><interceptors><interceptor name="sortInter1" class="com.zy.SortInterceptor1"/><interceptor name="sortInter2" class="com.zy.SortInterceptor2"/><interceptor name="sortInter3" class="com.zy.SortInterceptor3"/></interceptors><action name="sort" class="com.zy.SortAction"><result name="success" type="redirect">/index.jsp</result><interceptor-ref name="sortInter1"/><interceptor-ref name="sortInter2"/><interceptor-ref name="sortInter3"/></action></package></struts>


在配置文件中,我们定义了三个拦截器并为名字是“sort”的action元素指定了这三个拦截器。运行效果如图5.1.8所示。

 

图5.1.8 执行顺序

在Action执行之前,三个拦截器按照配置的顺序依次执行;在Action执行之后;三个拦截器按照相反的顺序依次执行。

本章总结

拦截器是动态拦截Action调用的对象,拦截器的方法可以在Action执行之前或之后自动执行,从而将通用的操作动态地插入到Action执行的前后,这跟我们平时组装电脑很类似,业务功能变成了可插拔式,需要哪个功能就“插入”一个拦截器,不需要就“拔出”,非常有利于系统的解耦。

Ø 系统拦截器。在struts-default.xml中配置了一组拦截器,并组成了默认拦截器栈,自定义Action通过package的extends属性直接或者间接的继承到了拦截器的配置。

Ø 自定义拦截器。

(1)创建拦截器类,实现com.opensymphony.xwork2.interceptor.lnterceptor 接口。

(2)使用<interceptor>在配置文件中定义了自己开发的拦截器,然后把该拦截器和Struts 2默认的defaultStack组成了一个拦截器栈。

(3)在Action的配置中引用该拦截器栈。

Ø 默认拦截器。默认拦截器(栈)定义在包(package)中,该包(package)中的所有Action都共享使用该默认拦截器(栈),每个包(package)中只能定义一个默认拦截器(栈)。在struts.xml文件中使用<default-interceptor-ref>元素来配置默认拦截器(栈)。

Ø 拦截器方法过滤

(1)继承MethodFiledIntercepor抽象类,并重写doIntercept(ActionInvocation invocation方法。

(2)为<action>元素指定拦截器时,方法过滤拦截器可以使用<param>元素设置拦截哪些方法,不拦截哪些方法。

任务实训部分

1:计算器除0拦截器

训练技能点

 动态方法调用

 自定义拦截器

需求说明

在上一章的任务实训部分我们实现了一个简单的计算器,现在要求:当用户进行除法运

算时,如果除数为0则不进行运算并跳转到一个提示“除数不能为0”的页面,必须使

用拦截器实现。

实现步骤

(1) 创建Action类,参考代码如下所示。

public class CalculatorAction {private double num1;private double num2;private double result;public String jia(){result=num1+num2;return "result";}public String jian(){result=num1-num2;return "result";}public String cheng(){result=num1*num2;return "result";}public String chu(){result=num1/num2;return "result";}//省略getter和setter方法}

(2) 创建与Action对应的视图页面,参考代码如下所示。

<body><form name="frm" method="post"><table width="298" border="0" align="center"><tr><td colspan="2" align="center">简易计算器</td></tr><tr><td width="76" align="center">第一个数</td><td width="206"><input type="text" name="num1" value="${num1}"></td></tr><tr><td align="center">第二个数</td><td><input type="text" name="num2" value="${num2}"></td></tr><tr><td colspan="2" align="center"><input type="button"  value="+" onclick="submitForm('jia')"><input type="button"  value="-" onclick="submitForm('jian')"><input type="button"  value="*" onclick="submitForm('cheng')"><input type="button"  value="/" onclick="submitForm('chu')"></td></tr><tr><td align="center">结果</td><td><input type="text" name="result" readonly value="${result}"></td></tr></table></form></body><script>function submitForm(op){frm.action="cal_"+op+".action";frm.submit();}</script>(3) 创建除0拦截器,参考代码如下所示。public class CalculatorInterceptor extends AbstractInterceptor {public String intercept(ActionInvocation ai) throws Exception {CalculatorAction ca=(CalculatorAction)ai.getAction();if(ai.getProxy().getMethod().equals("chu")&&ca.getNum2()==0)return "error";elsereturn ai.invoke();}}


在拦截器类中需要解决的一个问题是:判断此次请求调用的是否是Action中的chu()方法。ActionInvocation类的getProxy()方法可以获得当前Action的代理对象,该对象的getMethod()方法可以获得当前请求调用的方法名。

(4) 下面是struts.xml文件的参考代码

<struts><constant name="struts.i18n.encoding" value="utf-8"></constant><package name="shangji" extends="struts-default"><interceptors><interceptor name="calInter" class="com.zy.cal.CalculatorInterceptor"/></interceptors><action name="cal_*" class="com.zy.cal.CalculatorAction" method="{1}"><interceptor-ref name="defaultStack"/><interceptor-ref name="calInter"/><result name="result" type="dispatcher">/calculator.jsp</result><result name="error" type="redirect">/error.html</result></action></package></struts>


我们为action指定了两个拦截器,一个是Struts 2默认的defaultStack拦截器栈,另一个是我们自定义的拦截器。运行效果如图5.2.1和图5.2.2所示,当我们进行除0运算时,页面跳转到了error.html。

 

图5.2.1 计算器

 

图5.2.2 提示

 2:脏字过滤

训练技能点

 自定义拦截器

需求说明

很多网站都有评论功能,即用户可以对商品、新闻等进行评论,但是个别用户发表的评论可能带有一些“脏字”,例如“妈的”等等。现在要求当用户发表的评论中带有“妈的”文字时不予执行并要求重新发表评论,必须使用拦截器实现。

实现步骤

(1) 创建Action类,参考代码如下所示。

public class WordAction {private String title;     //标题private String context;  //正文public String pub(){//省略将评论插入到数据库中的代码return "success";}//省略getter和setter方法}

(2) 创建与之对应的视图页面,参考代码如下所示。

<body><form  method="post" action="pub.action"><table border="0" align="center"><tr><td>标题:</td><td><input name="title" type="text" size="30"></td></tr><tr><td>正文:</td><td><textarea name="context" cols="28" rows="10"></textarea></td></tr><tr><td colspan="2" align="center"><input type="submit" value="提交"></td></tr></table></form></body>(3) 创建脏字过滤拦截器,参考代码如下所示。public class WordInterceptor extends AbstractInterceptor {public String intercept(ActionInvocation ai) throws Exception {WordAction wa=(WordAction)ai.getAction();if(wa.getTitle().indexOf("妈的")!=-1||wa.getContext().indexOf("妈的")!=-1)return "input";elsereturn ai.invoke();}}


(4) 下面是struts.xml文件的参考代码

<struts><constant name="struts.i18n.encoding" value="utf-8"></constant><package name="shangji" extends="struts-default"><interceptors><interceptor name="wordInter" class="com.zy.word.WordInterceptor"/></interceptors><action name="pub" class="com.zy.word.WordAction" method="pub"><interceptor-ref name="defaultStack"/><interceptor-ref name="wordInter"/><result name="success" type="redirect">/success.html</result><result name="input" type="redirect">/pub.html</result></action></package></struts>


运行效果如图5.2.3所示,当我们发表的评论中带有“妈的”文字时会重新回到发表评论的页面。

 

图5.2.3 脏字过滤

3:限时访问

训练技能点

 自定义拦截器

 全局结果

需求说明

很多商业网站或软件都需要经常性的进行数据备份或维护,假如现在某个网站从凌晨1点到凌晨4点要进行维护,这个时间段暂停服务,即所有对本网站的访问都将被重置到一个带有提示信息的网页,如图5.2.4所示,要求用拦截器实现。

实现步骤

public class TimeInterceptor extends AbstractInterceptor {public String intercept(ActionInvocation ai) throws Exception {Calendar cale=Calendar.getInstance();int curr=cale.get(Calendar.HOUR_OF_DAY);if(curr>1&&curr<3)return "tishi";elsereturn ai.invoke();}}


这里我们只给出拦截器类的参考代码,在intercept()方法中最重要的是获得当前的时间,这里使用Calendar类的相关方法获得当前的小时数。

 

图5.2.4 限时访问

 4:为管理员登录增加拦截器

训练技能点

 自定义拦截器

 默认拦截器

需求说明

在第五章我们实现了管理员登录以及对管理员的增删改查等操作,现在要求为登录、增加、删除、修改和查询管理员添加默认拦截器,管理员必须登录成功才能进行增删改查操作,没有登录直接返回到登录页面。

巩固练习

一、选择题

1. 以下关于拦截器的说法错误的是()。

A. 可以在Action执行前后做一些操作

B. Struts自带的拦截器用户无法使用

C. 拦截器是一个特殊的Action

D. 拦截器只在Action之前发挥作用

2.自定义拦截器中的invoke()代码表示()。

A. 不执行目标Action的方法,直接返回

B. 执行目标Action的方法,直接返回结果视图

C. 在自定义拦截器中,该代码是必需的

D. 在自定义拦截器中,该代码是可选的

3.开发自定义拦截器的步骤是()。

A. 在struts.xml文件中定义拦截器

B. 创建拦截器类

C. 在struts.xml文件中为action元素指定拦截器

D. 继承struts-default

4.下面()拦截器用来将请求中的参数设置到Action的属性上。

A. token

E. params

F. workflow

G. validation

5.下面关于<interceptor>元素说法错误的是()。

A. name属性指定拦截器的名称

H. name属性的值必须被某个Action所引用

I. 该元素是<package>的子元素

J. class属性指定拦截器的实现类

 二、上机练习

在实训任务4的基础上扩展功能,管理员admin是超级管理员,只有他登录的时候才

可以进行任何操作,其他管理员登录后只能进行查询操作,用拦截器实现。

原创粉丝点击