第六节:Struts2-拦截器

来源:互联网 发布:淘宝6.0官网下载安装 编辑:程序博客网 时间:2024/06/06 04:47

一。介绍拦截器

1.理解DRY规则:在软件开发领域,现在有一条非常重要的规则:Don't Repeat yoursIf,就是所谓的DRY规则,意思就是不要书写重复的代码。

2.Struts2的拦截器机制与动态代理机制相同。动态代理介绍参考:http://blog.csdn.net/a85820069/article/details/17418887

二。拦截器定义配置

1.在struts.xml中配置拦截器

说明:<interceptor>标签用于定义拦截器。

说明:<param>标签用于为拦截器的属性设定初始值。

注意:在struts.xml文件中定义标签的出现顺序有要求,interceptors标签必须定义在action标签之前。如果顺序错乱将会提示如下错误信息:

The content of element type "package" must match "(result-types?,interceptors?,default-interceptor-ref?,default-action-ref?,default-class-ref?,global-results?,global-exception-mappings?,action*)"

<!-- 定义拦截器 --><interceptors><interceptor name="simple" class="intercepter.SimpleInterceptor"><param name="name">小拦截器(定义位置A)</param></interceptor></interceptors>
2.在struts.xml中配置拦截器栈

在拦截器栈中可以包含拦截器也可以包含其他拦截器栈

<interceptor-stack name="拦截器栈名"><interceptor-ref name="拦截器一"></interceptor-ref><interceptor-ref name="拦截器二"></interceptor-ref><interceptor-ref name="拦截器栈一"></interceptor-ref></interceptor-stack>

在拦截器栈中拦截器可以重复,重复的拦截器一样会顺序执行多次。

三。拦截器应用配置

1.包与拦截器的关系:

在struts-default.xml文件中有如下配置:

<default-interceptor-ref name="defaultStack"/>
实现了为struts-default包及其子包中所有action均使用defaultStack作为默认的拦截器栈。

2.action与拦截器的关系

在action定义中配置使用拦截器

说明:<interceptor-ref>标签用于引入拦截器。

说明:<param>标签用于为拦截器的属性设定初始值。

<action name="Login" class="action.LoginAction"><interceptor-ref name="拦截器(栈)名称"><param name="参数名">参数值</param></interceptor-ref><interceptor-ref name="拦截器(栈)名称"><param name="参数名">参数值</param></interceptor-ref><result name="input">/Login.jsp</result><result name="success" >/welcome.jsp</result><result name="error" >/error.jsp</result></action>

注意:

param是否支持动态赋值?比如${属性名.属性名}

action指定了拦截器栈(abc)后,将会执行abc拦截规则,与默认指定的defaultStack规则无关。要考虑好是否真的不需要使用defaultStack拦截器栈中的拦截器规则。

在action中可以配置重复的拦截器或拦截器栈,重复的拦截器一样会顺序执行多次。

四。拦截器的属性初始值的设定

可以在定义时进行设定,也可在action中设定。action中的值会覆盖掉在定义时的值。

五。拦截器的执行顺序

拦截器包含“在目标方法之前执行的方法”以及“在目标方法执行之后执行的方法”

假设拦截器栈定义如下

<拦截器栈一>

拦截器一

拦截器二

拦截器三

拦截器栈二

<拦截器栈一/>

<拦截器栈二>

拦截器一

拦截器四

拦截器五

<拦截器栈二/>

则执行顺序为

拦截器栈一.拦截器一.之前执行的方法

拦截器栈一.拦截器二.之前执行的方法

拦截器栈一.拦截器三.之前执行的方法

拦截器栈二.拦截器一.之前执行的方法

拦截器栈二.拦截器四.之前执行的方法

拦截器栈二.拦截器五.之前执行的方法

目标方法

拦截器栈二.拦截器五.之后执行的方法

拦截器栈二.拦截器四.之后执行的方法

拦截器栈二.拦截器一.之后执行的方法

拦截器栈一.拦截器三.之后执行的方法

拦截器栈一.拦截器二.之后执行的方法

拦截器栈一.拦截器一.之后执行的方法

六。介绍与拦截器相关的标签

<interceptors.../>元素:该元素用于定义拦截器,所有的拦截器和拦截器栈都在该元素下定义。该元素包含<interceptor.../>和<interceptor-stack.../>子元素,分别用于定义拦截器和拦截器栈。

<interceptor.../>元素:该元素用于定义拦截器,定义拦截器时只需指定两个属性:name和class,分别指定拦截器名称和实现类。

<interceptor-stack.../>元素:该元素用于dingyi8拦截器引用,该元素中包含多个<interceptor-ref.../>元素,用于将多个拦截器或者拦截器栈组合成一个新的拦截器栈。

<interceptor-ref.../>元素:该元素引用一个拦截器或者拦截器栈,该元素只需指定一个name属性,该属性值为一个已经定义的拦截和拦截器栈。该元素可以作为<interceptor-stack.../>和<action.../>元素的子元素使用。

<param.../>元素:该元素用于为拦截器指定参数,可以作为<interceptor.../>和<interceptor-ref.../>元素的子元素使用。

七。编写自定义拦截器

方式一:自定义拦截器应实现:com.opensymphony.xwork2.interceptor.Interceptor接口,该接口包含如下定义

//销毁该拦截器之前的回调方法

void destroy();

//初始化该拦截器的回调方法

void init();

//拦截器实现拦截的逻辑方法

String intercept(ActionInvocation invocation) throws Exception;

方法说明:

init:在该拦截器被初始化之后,在该拦截器执行拦截之前,系统将回调该方法。对于每个拦截器而言,该init()方法只执行一次。因此,该方法的方法体主要用于打开一些一次性资源,例如数据库资源等。

destroy:该方法与init()方法对应,在拦截器实例被销毁之前,系统将回调该拦截器的destroy方法,该方法用于毁掉在init()方法里打开的资源。

intercept:该方法是用户需要实现的拦截器动作。就像Action的execute方法一样,intercept方法会返回一个字符串作为逻辑视图。如果该方法直接返回了一个字符串,系统将会跳转到该逻辑视图对应的实际视图资源,不会调用被拦截的Action。该方法的ActionInvocation参数包含了被拦截的Action的引用,可以通过调用该参数的invoke方法,将控制权转给下一个拦截器,或者转给Action的execute方法。

方式二:继承AbstractInterceptor类,该类提供了一个init()和destroy方法的空实现,如果我们实现的拦截器不需要申请资源,则可以无需实现这两个方法。

编写action代码

package intercepter;import java.util.Date;import action.FileDownAction;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.AbstractInterceptor;public class SimpleInterceptor extends AbstractInterceptor{//简单拦截器的名字(由配置文件提供)private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String intercept(ActionInvocation actionInvocation) throws Exception {//获取被拦截的Action实例FileDownAction action = (FileDownAction)actionInvocation.getAction();//打印System.out.println(name+"拦截器的动作---------------" +"开始执行下载Action的时间为:" + new Date());//取得开始执行Action的时间long start = System.currentTimeMillis();//执行该拦截器的后一个拦截器,或者执行执行Action的execute方法String returnStr = actionInvocation.invoke();System.out.println(name+"拦截器的动作------------------" +"执行完下载Action的时间为:" + new Date());//取得执行完的时间long end = System.currentTimeMillis();System.out.println(name+"拦截器的动作-----------------" +"执行完该Action的时间为" + (end - start) + "毫秒");return returnStr;}}

编写struts.xml文件:

说明:对Action没有要求,任何实现的Action均可,所以不对action进行代码说明。

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"><struts><package name="loginAction" namespace="/x" extends="struts-default"><!-- 定义拦截器 --><interceptors><interceptor name="simple" class="intercepter.SimpleInterceptor"><param name="name">小拦截器(定义位置A)</param></interceptor></interceptors><action name="MydownFile" class="action.FileDownAction"><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="simple"><param name="name">小拦截器(定义位置B)</param></interceptor-ref><!-- 动态配置下载文件路径 --><param name="inputPath">\down\1.gif</param><result name="success" type="stream"><!-- 指定下载文件的文件类型 --><param name="contentType">image/gif</param><!-- 指定下载文件的文件位置 --><param name="inputName">targetFile</param><param name="contentDisposition">attachment;filename="中文名可以不?.gif"</param><!-- 指定下载文件的缓冲大小 --><param name="bufferSize">4096</param></result></action></package></struts>

运行后输出的结果:

说明:根据以下输出说明拦截器生效了。

说明:根据name输出的 "小拦截器(定义位置B)"说明action中为拦截器设定的参数生效了。

小拦截器(定义位置B)拦截器的动作---------------开始执行下载Action的时间为:Wed Jan 22 02:34:55 CST 2014小拦截器(定义位置B)拦截器的动作------------------执行完下载Action的时间为:Wed Jan 22 02:34:57 CST 2014小拦截器(定义位置B)拦截器的动作-----------------执行完该Action的时间为1911毫秒

方式三:带方法过滤的拦截器

为了实现方法过滤的特性,Struts2提供了一个MethodFilterInterceptor类,该类是AbstractInterceptor类的子类,如果用户需要自己实现拦截器支持方法过滤特性,则应该继承MethodFilterInterceptor。

MethodFilterInterceptor类重写了 AbstractInterceptor类的intercept(ActionInvocation invocation)方法,但提供了一个doInterccept(ActionInvocation invocation)抽象方法需要用户编写。

MethodFilterInterceptor方法中,额外增加了如下两个方法:

public void setExcludeMethods(String excludeMethods);排除需要过滤的方法——设置方法“黑名单”,所有在excludeMethods字符串中列出的方法都不会被拦截。

public void setIncludeMethods(String includeMethods);设置需要过滤的方法——设置方法“白名单”,所有在includeMethods字符串中列出的方法都会被拦截。

注意:如果一个方法同时在excludeMethods和includeMethods中列出,则该方法会被拦截。

在配置文件中使用param标签为excludeMethods和includeMethods参数赋值。


八。拦截结果的监听器

在拦截器中可以手动为拦截器注入一个由PreResultListener接口的实现类对象。在拦截器中返回结果字符串后调用该对象的beforeResult(ActionInvocation invocation,String resultCode)方法。此方法在拦截器之后执行的方法之前执行。

注意:不要在beforeResult方法中调用invocation对象的invoke方法,如果调用了将会再次执行Action处理,Action处理之后紧跟的是BeforResult方法——这是一个死循环。


九。覆盖拦截器中特定拦截器的参数

如何为拦截器栈中某一个拦截器设定参数值,参照如下配置

<interceptor-ref name="defaultStack"><param name="i18n.name">GBK</param></interceptor-ref>
<拦截器名称>.<参数名>


十。Struts2内建拦截器介绍

alias:实现在不同请求中相似参数别名的转换。

autowiring:这是个自动装配的拦截器,主要用于当Struts2和Spring整合时,Struts2可以使用自动装配的方式来访问Spring容器中的Bean。

chain:构建一个Action链,使当前Action可以访问前一个Action的属性,一般和<result type="chain".../>一起使用。

conversionError:这是一个负责处理类型转换错误的拦截器,它负责将类型转换错误从ActionContext中取出,并转换成Action的FieldError错误。

createSession:该拦截器负责创建一个HttpSession对象,主要用于那些需要有HttpSession对象才能正常工作的拦截器中。

debuggingg:当使用Struts2的开发模式时,这个拦截器会提供更多的调试信息。

execAndWait:这个拦截器负责处理异常,它将异常映射为结果。

exception:这个拦截器负责处理异常,它将异常映射为结果。

fileupload:这个拦截器主要用于文件上传,它负责解析表单中文件域的内容。

il8n:这是支持国际化的拦截器,它负责把所选的语言、区域放入用户Session中。

logger:这是一个负责日志记录的拦截器,主要是输出Action的名字。

model-driven:这是一个用于模型驱动的拦截器,当某个Action类实现了ModelDriven接口时,它负责把getModel()方法的结果堆入ValueStack中。

scoped-model-driven:如果一个Action实现了一个ScopedModelDriven接口,该拦截器负责从指定生存范围中找出指定的Model,并将通过setModel方法将该Model传给Action实例。

params:这是最基本的一个拦截器,它负责解析HTTP请求中的参数,并将参数值设置成Action对应的属性值。

prepare:如果action实现了Preparable接口,将会调用该拦截器的prepare()方法。

static-params:这个拦截器负责将xml中<action>标签下<param>标签中的参数传入action。

scope:这是范围转换拦截器,它可以将Action状态信息保存到HttpSession范围,或者保存到ServletContext范围内。

servlet-config:如果某个Action需要直接访问Servlet API,就是通过这个拦截器实现的。

roles:这是一个JAAS(Java Authentication and Authorization Service,Java授权和认证服务)拦截器,只有当浏览者取得合适的授权后,才可以调用被该拦截器拦截的Action。

timer:这个拦截器负责输出Action的执行时间,这个拦截器在分析该Action的性能瓶颈时比较有用。

token:这个拦截器主要用于阻止重复提交,它检查传到Action中的token,从而防止多次提交。

token-session :这个拦截器的作用与前一个基本类似,只是它把token保存在HttpSession中。

validation:通过执行在xxxAction-validation.xml中定义的校验器,从而完成数据校验。

workflow:这个拦截器负责调用Action类中的validate方法,如果校验失败,则返回input的逻辑视图。















如果拦截器配置中引用了未知的拦截器名则启动时错误信息如下:

严重: Dispatcher initialization failedUnable to load configuration. - interceptor-ref - file:/G:/apache-tomcat-6.0.13/webapps/struts2HelloWorld/WEB-INF/classes/struts.xml:12:34at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:70)at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:446)at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:490)at org.apache.struts2.dispatcher.FilterDispatcher.init(FilterDispatcher.java:193)at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:275)at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:397)at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:108)at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3693)at org.apache.catalina.core.StandardContext.start(StandardContext.java:4340)at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:920)at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:883)at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1138)at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)at org.apache.catalina.core.StandardService.start(StandardService.java:516)at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)at org.apache.catalina.startup.Catalina.start(Catalina.java:566)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.lang.reflect.Method.invoke(Unknown Source)at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)Caused by: Unable to find interceptor class referenced by ref-name 拦截器名称 - interceptor-ref - file:/G:/apache-tomcat-6.0.13/webapps/struts2HelloWorld/WEB-INF/classes/struts.xml:12:34at com.opensymphony.xwork2.config.providers.InterceptorBuilder.constructInterceptorReference(InterceptorBuilder.java:63)at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.lookupInterceptorReference(XmlConfigurationProvider.java:1110)at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.buildInterceptorList(XmlConfigurationProvider.java:626)at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addAction(XmlConfigurationProvider.java:440)at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addPackage(XmlConfigurationProvider.java:552)at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadPackages(XmlConfigurationProvider.java:292)at org.apache.struts2.config.StrutsXmlConfigurationProvider.loadPackages(StrutsXmlConfigurationProvider.java:112)at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:250)at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:67)... 30 more2014-1-22 2:33:05 org.apache.catalina.core.StandardContext filterStart严重: Exception starting filter struts2Unable to load configuration. - interceptor-ref - file:/G:/apache-tomcat-6.0.13/webapps/struts2HelloWorld/WEB-INF/classes/struts.xml:12:34at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:502)at org.apache.struts2.dispatcher.FilterDispatcher.init(FilterDispatcher.java:193)at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:275)at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:397)at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:108)at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3693)at org.apache.catalina.core.StandardContext.start(StandardContext.java:4340)at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:920)at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:883)at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1138)at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)at org.apache.catalina.core.StandardService.start(StandardService.java:516)at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)at org.apache.catalina.startup.Catalina.start(Catalina.java:566)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.lang.reflect.Method.invoke(Unknown Source)at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)Caused by: Unable to load configuration. - interceptor-ref - file:/G:/apache-tomcat-6.0.13/webapps/struts2HelloWorld/WEB-INF/classes/struts.xml:12:34at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:70)at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:446)at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:490)... 28 moreCaused by: Unable to find interceptor class referenced by ref-name 拦截器名称 - interceptor-ref - file:/G:/apache-tomcat-6.0.13/webapps/struts2HelloWorld/WEB-INF/classes/struts.xml:12:34at com.opensymphony.xwork2.config.providers.InterceptorBuilder.constructInterceptorReference(InterceptorBuilder.java:63)at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.lookupInterceptorReference(XmlConfigurationProvider.java:1110)at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.buildInterceptorList(XmlConfigurationProvider.java:626)at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addAction(XmlConfigurationProvider.java:440)at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addPackage(XmlConfigurationProvider.java:552)at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadPackages(XmlConfigurationProvider.java:292)at org.apache.struts2.config.StrutsXmlConfigurationProvider.loadPackages(StrutsXmlConfigurationProvider.java:112)at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:250)at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:67)... 30 more2014-1-22 2:33:05 org.apache.catalina.core.StandardContext start严重: Error filterStart2014-1-22 2:33:05 org.apache.catalina.core.StandardContext start严重: Context [/struts2HelloWorld] startup failed due to previous errors










0 0
原创粉丝点击