标签:struts2 interceptor 拦截器在struts2中的缺省应用与配置 拦截器的工作流程 自定义拦截器
一.Struts2有一核心技术是拦截器,英文名为Interceptor。拦截器本来是WebWork框架中一个很好的支持国际化、校验、类型转换的工具。现在WebWork和Struts合并成Struts2之后,理所当然也成为Struts2的一部分。
1.拦截器本身也是一个普通的Java对象,它的功能是动态拦截Action调用,在Action执行前后执行拦截器本身提供的各种各样的Web项目需求。当然也可以阻止Action的执行,同时也可以提取Action中可以复用的部分。
2.在Struts2中还有个拦截器栈的概念,其实它就是拦截器的一个集合。它把多个拦截器集合起来,按照在栈中配置的顺序执行,特别是针对Action可以拦截相应的方法或者字段。
二.拦截器在Struts2中的缺省应用与配置:
1.在Web项目中,客户先在视图界面提交一个HTTP请求,在Struts2的ServletDispatcher接收请求,Struts2会查找struts.xml配置文件。根据struts.xml配置文件中定义的拦截器配置,会去调用拦截器。如果配置了拦截器栈,则根据拦截器在拦截器栈中的前后顺序,一一进行调用。而Struts2自带的源代码中也提供了缺省的拦截器配置。
(1).在我们下载的Struts2的包里中,解压后struts-2.3.20文件夹底下,在src文件夹中包含了Struts2的所有底层实现源代码,我们可到自己安装的Struts2的文件路径下找到src\core\src\main\resources\中,其中有个名为struts-default.xml文件。它是Struts2自定义的配置文件,其中有关拦截器的配置代码便是拦截器在Struts2中的缺省应用。
如果要在MyEclipse工具中查看,可以打开Struts2项目中的Web App Libraries下的 struts2-core-2.3.20.jar下的struts-default.xml文件。
(2).接下来附上struts-default.xml文件中有关拦截器的配置代码,如下:
<interceptors> <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/> <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/> <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/> <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/> <interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/> <interceptor name="cookieProvider" class="org.apache.struts2.interceptor.CookieProviderInterceptor"/> <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" /> <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" /> <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" /> <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/> <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/> <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/> <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/> <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/> <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/> <interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/> <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/> <interceptor name="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/> <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/> <interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/> <interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/> <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/> <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/> <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/> <interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/> <interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/> <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/> <interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" /> <interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" /> <interceptor name="datetime" class="org.apache.struts2.interceptor.DateTextFieldInterceptor" /> <interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" /> <interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" /> <interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" /> <interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" /> <interceptor name="deprecation" class="org.apache.struts2.interceptor.DeprecationInterceptor" /> <!-- Basic stack --> <interceptor-stack name="basicStack"> <interceptor-ref name="exception"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="prepare"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="datetime"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">^action:.*,^method:.*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="deprecation"/> </interceptor-stack> <!-- Sample validation and workflow stack --> <interceptor-stack name="validationWorkflowStack"> <interceptor-ref name="basicStack"/> <interceptor-ref name="validation"/> <interceptor-ref name="workflow"/> </interceptor-stack> <!-- Sample file upload stack --> <interceptor-stack name="fileUploadStack"> <interceptor-ref name="fileUpload"/> <interceptor-ref name="basicStack"/> </interceptor-stack> <!-- Sample model-driven stack --> <interceptor-stack name="modelDrivenStack"> <interceptor-ref name="modelDriven"/> <interceptor-ref name="basicStack"/> </interceptor-stack> <!-- Sample action chaining stack --> <interceptor-stack name="chainStack"> <interceptor-ref name="chain"/> <interceptor-ref name="basicStack"/> </interceptor-stack> <!-- Sample i18n stack --> <interceptor-stack name="i18nStack"> <interceptor-ref name="i18n"/> <interceptor-ref name="basicStack"/> </interceptor-stack> <!-- An example of the paramsPrepareParams trick. This stack is exactly the same as the defaultStack, except that it includes one extra interceptor before the prepare interceptor: the params interceptor. This is useful for when you wish to apply parameters directly to an object that you wish to load externally (such as a DAO or database or service layer), but can't load that object until at least the ID parameter has been loaded. By loading the parameters twice, you can retrieve the object in the prepare() method, allowing the second params interceptor to apply the values on the object. --> <interceptor-stack name="paramsPrepareParamsStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="i18n"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="datetime"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="params"> <param name="excludeParams">^action:.*,^method:.*</param> </interceptor-ref> <interceptor-ref name="servletConfig"/> <interceptor-ref name="prepare"/> <interceptor-ref name="chain"/> <interceptor-ref name="modelDriven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">^action:.*,^method:.*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> </interceptor-stack> <!-- A complete stack with all the common interceptors in place. Generally, this stack should be the one you use, though it may do more than you need. Also, the ordering can be switched around (ex: if you wish to have your servlet-related objects applied before prepare() is called, you'd need to move servletConfig interceptor up. This stack also excludes from the normal validation and workflow the method names input, back, and cancel. These typically are associated with requests that should not be validated. --> <interceptor-stack name="defaultStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="i18n"/> <interceptor-ref name="prepare"/> <interceptor-ref name="chain"/> <interceptor-ref name="scopedModelDriven"/> <interceptor-ref name="modelDriven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="datetime"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">^action:.*,^method:.*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="debugging"/> <interceptor-ref name="deprecation"/> </interceptor-stack> <!-- The completeStack is here for backwards compatibility for applications that still refer to the defaultStack by the old name --> <interceptor-stack name="completeStack"> <interceptor-ref name="defaultStack"/> </interceptor-stack> <!-- Sample execute and wait stack. Note: execAndWait should always be the *last* interceptor. --> <interceptor-stack name="executeAndWaitStack"> <interceptor-ref name="execAndWait"> <param name="excludeMethods">input,back,cancel</param> </interceptor-ref> <interceptor-ref name="defaultStack"/> <interceptor-ref name="execAndWait"> <param name="excludeMethods">input,back,cancel</param> </interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="defaultStack"/> <default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
(3).接下来来解释上图中的struts-default.xml文件的代码:
— 在xml配置文件中配置拦截器和拦截器栈都是以“<interceptors>”开头,以“</interceptors>”结尾。
— 配置拦截器的格式如上面代码所示以“<interceptor/>”格式显示,其中有两个属性:name是拦截器的名字,另一个class是对应的类路径,因为前面说过拦截器也是一个普通的Java对象。
— 拦截器栈的格式是以“<interceptor-stack>”开头,以“</interceptor-stack>”结尾。其中属性name是拦截器栈的名字。在“<interceptor-stack>”和“</interceptor-stack>”之间可以设置拦截器。如struts-default.xml文件中的代码所示格式为“<interceptor-ref/>”,其中name属性也是拦截器名字。如果系统运行拦截器栈,都是按照拦截器栈中定义的拦截器先后顺序执行拦截器。
注:1.请大家仔细查看那个基础栈的配置,即basicStack这个栈,其中配置的拦截器都是在struts-default.xml文件中定义的拦截器。在struts-default.xml文件中的defaultStack栈里的拦截器配置是我们经常用的。
注:2.拦截器栈中不单单可以配置拦截器,它甚至还可以配置拦截器栈。比如在struts-default.xml文件代码中的“validationWorkflowStack”拦截器栈中就配置了“basicStack”拦截器栈。这样的话,配置的子拦截器栈中的拦截器也会被执行。这就类似于父集合和子集合的概念。
(4).针对struts-default.xml文件中各个拦截器配置一一做介绍,因为如果使用Struts2在Web项目开发中,这些拦截器默认缺省的会被执行的。因此,了解一下Struts2底层的拦截器到底实现什么功能对开发人员来说是很有帮助的。
2.下面对Struts2中底层的拦截器进行介绍,即了解一下对struts-default.xml文件中的拦截器:
1.alias:对于HTTP请求包含的参数设置别名。
2.autowiring:将某些JavaBean实例自动绑定到其他Bean对应的属性中。有点类似Spring的自动绑定。
3.chain:在Web项目开发中,以前使用Struts开发时候经常碰到两个Action互相传递参数或属性的情况。该拦截器就是让前一个Action的参数可以在现有Action中使用。
4.conversionError:从ActionContext中将转换类型时候发生的错误添加到Action的值域错误中,在校验时候经常被使用到来显示类型转换错误的信息。
5.cookie:从Struts2.0.7版本开始,可以把cookie注入Action中可设置的名字或值中。
6.createSession:自动创建一个HTTP的Session,尤其是对需要HTTP的Session的拦截器特别有用,如下面要介绍的TokenInterceptor。
7.debugging:用来对在视图间传递的数据进行调试。
8.execAndWait:不显式执行Action,在视图上显示给用户的是一个正在等待的页面,但是Action其实是在背后正在执行着的。该拦截器尤其是在进度条开发的时候特别有用。
9.exception:将异常和Action返回的result相映射。
10.fileUpload:支持文件上传功能的拦截器。
11.i18n:支持国际化的拦截器。
12.logger:拥有日志功能的拦截器。
13.modelDriven:Action执行该拦截器的时候,可以将getModel方法得到的result值放入值栈中。
14.scopedModelDriven:执行该拦截器时,它可以从一个scope范围检索和存储model值,通过调用setModel方法去设置model值。
15.params:将HTTP请求中包含的参数值设置到Action中。
16.prepare:假如Action继承了Preparable接口,则会调用prepare方法。
17.staticParams:对于在struts.xml文件中Action中设置的参数设置到对应的Action中。
18.scope:在session或者application范围中设置Action的状态。
19.servletConfig:该拦截器提供访问包含HttpServletResquest和HttpServletResponse对象的Map的方法。
20.timer:输出Action的执行时间。
21.token:避免重复提交的校验拦截器。
22.tokenSession:和token拦截器类似,但它还能存储提交的数据到Session里。
23.validation:运行在action-validation.xml文件中定义的校验规则。其中action-validation.xml是对一个Action类的校验。
24.workflow:在Action中调用validate校验方法。如果Action有错误则返回到input视图。
25.store:执行校验功能时,该拦截器提供存储和检索Action的所有错误和正确信息的功能。
26.checkbox:视图中如果有checkbox存在的情况,该拦截器自动将unchecked的checkbox当作一个参数(通常值为false)记录下来。这样可以用一个隐藏的表单值来记录所有未提交的checkbox,而且缺省unchecked的checkbox值是布尔类型的,如果视图中checkbox的值设置的不是布尔类型,它就会被覆盖成布尔类型的值。
27.profiling:通过参数来激活或不激活分析检测功能,前提是Web项目是在开发者模式下。(涉及到调试和性能检验时使用)
28.roles:进行权限配置的拦截器,如果登录用户拥有相应权限才去执行某一特定的Action。
package com.action; import com.opensymphony.xwork2.ActionSupport; public class TimerInterceptorAction extends ActionSupport { public String execute() throws Exception{ Thread.sleep(5000);//让线程睡眠5000毫秒,即睡眠5秒 return SUCCESS; } }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant> <constant name="struts.devMode" value="true"></constant> <package name="default" namespace="/" extends="struts-default"> <action name="timeTest" class="com.action.TimerInterceptorAction"> <interceptor-ref name="timer"/> <result>/index.jsp</result> </action> </package> </struts>
<interceptors> <interceptor name="replace" class="com.gk.interceptor.MyInterceptor"></interceptor> <interceptor name="replace1" class="com.gk.interceptor.MyInterceptor1"></interceptor> </interceptors>
<action name="public" class="com.gk.action.PublicAction"> <result name="success">/success.jsp</result> <result name="login">/success.jsp</result> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="replace"></interceptor-ref> <interceptor-ref name="replace1"></interceptor-ref> </action>
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'news.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <center> 发表评论 <s:form action="public" namespace="/" method="post"> <s:textfield name="title" label="标题"/> <s:textarea name="content" cols="30" rows="5" label="内容"/> <s:submit value="评论"></s:submit> </s:form> </center> </body> </html>
package com.gk.action; import com.opensymphony.xwork2.ActionSupport; public class PublicAction extends ActionSupport { private String title; private String content; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String execute(){ return SUCCESS; } }
package com.gk.interceptor; import com.gk.action.PublicAction; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class MyInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { PublicAction action=(PublicAction) invocation.getAction();//取得Action的实例 String content=action.getContent();//获得action中的content内容,即news.jsp文件表单里的输入的内容 //如果输入的内容包含叼字的话 if(content.contains("叼")){ content=content.replaceAll("叼", "*");//把内容里所有有叼字的全部替换为*号 action.setContent(content);//在重新设置内容 return invocation.invoke();//返回拦截后结果码 }else{ return action.LOGIN;//如果没有叼字,返回结果码 } } }
package com.gk.interceptor; import com.gk.action.PublicAction; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class MyInterceptor1 extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { PublicAction action=(PublicAction) invocation.getAction();//取得Action的实例 String title=action.getTitle();//获得action中的title内容,即news.jsp页面的表单里的输入标题 //如果输入的标题有死字的 if(title.contains("死")){ title=title.replaceAll("死", "*");//把死字全部替换为* action.setTitle(title);//再重新设置标题内容 return invocation.invoke();//返回拦截后结果码 } return action.LOGIN;//如果没有死字,返回结果码 } }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant> <constant name="struts.devMode" value="true"></constant> <package name="interceptor" namespace="/" extends="struts-default"> <interceptors> <interceptor name="replace" class="com.gk.interceptor.MyInterceptor"></interceptor> <interceptor name="replace1" class="com.gk.interceptor.MyInterceptor1"></interceptor> </interceptors> <action name="public" class="com.gk.action.PublicAction"> <result name="success">/success.jsp</result> <result name="login">/success.jsp</result> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="replace"></interceptor-ref> <interceptor-ref name="replace1"></interceptor-ref> </action> </package> </struts>注:这里要注意要在action里必须加上 <interceptor-ref name="defaultStack"></interceptor-ref> 这行代码,否则会报错。
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'success.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> 标题为:<s:property value="title"/><br/> 评论内容为:<s:property value="content"/> </body> </html>
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:struts2 interceptor 拦截器在struts2中的缺省应用与配置 拦截器的工作流程 自定义拦截器
原文地址:http://blog.csdn.net/u012561176/article/details/46894937