11级_Java_曹建波 03.04 Struts2的拦截器&验证器
Struts2的拦截器
过滤器servlet过滤器
过滤器与拦截器的区别:
*相同点:都是起拦截作用
*不同点:
*作用范围:
*过滤器:使用范围是J2EE范畴,任何一个web工程都可以使用过滤器
*拦截器:使用范围是struts2范畴,离不开struts2框架的
*完成的功能:
*过滤器:拦截请求资源
*拦截器:完成其他所有功能
*执行顺序:
过滤器——>拦截器
http客户端-->web容器--web.xml文件--过滤器
--->struts.xml--->拦截器--->action--service--dao--数据库
常见的拦截器有哪些?
在哪里配置
struts-default.xml文件
packagename=”struts-default”
<interceptors>
<interceptorname="alias"class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
<interceptorname="autowiring"class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
<interceptorname="chain"class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
<interceptorname="conversionError"class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
<interceptorname="cookie"class="org.apache.struts2.interceptor.CookieInterceptor"/>
<interceptorname="clearSession"class="org.apache.struts2.interceptor.ClearSessionInterceptor"/>
<interceptorname="createSession"class="org.apache.struts2.interceptor.CreateSessionInterceptor"/>
<interceptorname="debugging"class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor"/>
<interceptorname="execAndWait"class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
<interceptorname="exception"class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
<interceptorname="fileUpload"class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
<interceptorname="i18n"class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
<interceptorname="logger"class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<interceptorname="modelDriven"class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
<interceptorname="scopedModelDriven"class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
<interceptorname="params"class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
<interceptorname="actionMappingParams"class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>
<interceptorname="prepare"class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
<interceptorname="staticParams"class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
<interceptorname="scope"class="org.apache.struts2.interceptor.ScopeInterceptor"/>
<interceptorname="servletConfig"class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
<interceptorname="timer"class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptorname="token"class="org.apache.struts2.interceptor.TokenInterceptor"/>
<interceptorname="tokenSession"class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
<interceptorname="validation"class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
<interceptorname="workflow"class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
<interceptorname="store"class="org.apache.struts2.interceptor.MessageStoreInterceptor"/>
<interceptorname="checkbox"class="org.apache.struts2.interceptor.CheckboxInterceptor"/>
<interceptorname="profiling"class="org.apache.struts2.interceptor.ProfilingActivationInterceptor"/>
<interceptorname="roles"class="org.apache.struts2.interceptor.RolesInterceptor"/>
<interceptorname="annotationWorkflow"class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor"/>
<interceptorname="multiselect"class="org.apache.struts2.interceptor.MultiselectInterceptor"/>
<!--Basicstack-->
<interceptor-stackname="basicStack">
<interceptor-refname="exception"/>
<interceptor-refname="servletConfig"/>
<interceptor-refname="prepare"/>
<interceptor-refname="checkbox"/>
<interceptor-refname="multiselect"/>
<interceptor-refname="actionMappingParams"/>
<interceptor-refname="params">
<paramname="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
</interceptor-ref>
<interceptor-refname="conversionError"/>
</interceptor-stack>
<!--Samplevalidationandworkflowstack-->
<interceptor-stackname="validationWorkflowStack">
<interceptor-refname="basicStack"/>
<interceptor-refname="validation"/>
<interceptor-refname="workflow"/>
</interceptor-stack>
<!--Samplefileuploadstack-->
<interceptor-stackname="fileUploadStack">
<interceptor-refname="fileUpload"/>
<interceptor-refname="basicStack"/>
</interceptor-stack>
<!--Samplemodel-drivenstack-->
<interceptor-stackname="modelDrivenStack">
<interceptor-refname="modelDriven"/>
<interceptor-refname="basicStack"/>
</interceptor-stack>
<!--Sampleactionchainingstack-->
<interceptor-stackname="chainStack">
<interceptor-refname="chain"/>
<interceptor-refname="basicStack"/>
</interceptor-stack>
<!--Samplei18nstack-->
<interceptor-stackname="i18nStack">
<interceptor-refname="i18n"/>
<interceptor-refname="basicStack"/>
</interceptor-stack>
<!--AnexampleoftheparamsPrepareParamstrick.Thisstack
isexactlythesameasthedefaultStack,exceptthatit
includesoneextrainterceptorbeforetheprepareinterceptor:
theparamsinterceptor.
Thisisusefulforwhenyouwishtoapplyparametersdirectly
toanobjectthatyouwishtoloadexternally(suchasaDAO
ordatabaseorservicelayer),butcan'tloadthatobject
untilatleasttheIDparameterhasbeenloaded.Byloading
theparameterstwice,youcanretrievetheobjectinthe
prepare()method,allowingthesecondparamsinterceptorto
applythevaluesontheobject.-->
<interceptor-stackname="paramsPrepareParamsStack">
<interceptor-refname="exception"/>
<interceptor-refname="alias"/>
<interceptor-refname="i18n"/>
<interceptor-refname="checkbox"/>
<interceptor-refname="multiselect"/>
<interceptor-refname="params">
<paramname="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
</interceptor-ref>
<interceptor-refname="servletConfig"/>
<interceptor-refname="prepare"/>
<interceptor-refname="chain"/>
<interceptor-refname="modelDriven"/>
<interceptor-refname="fileUpload"/>
<interceptor-refname="staticParams"/>
<interceptor-refname="actionMappingParams"/>
<interceptor-refname="params">
<paramname="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
</interceptor-ref>
<interceptor-refname="conversionError"/>
<interceptor-refname="validation">
<paramname="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-refname="workflow">
<paramname="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
</interceptor-stack>
<!--Acompletestackwithallthecommoninterceptorsinplace.
Generally,thisstackshouldbetheoneyouuse,thoughit
maydomorethanyouneed.Also,theorderingcanbe
switchedaround(ex:ifyouwishtohaveyourservlet-related
objectsappliedbeforeprepare()iscalled,you'dneedtomove
servletConfiginterceptorup.
Thisstackalsoexcludesfromthenormalvalidationandworkflow
themethodnamesinput,back,andcancel.Thesetypicallyare
associatedwithrequeststhatshouldnotbevalidated.
-->
<interceptor-stackname="defaultStack">
<interceptor-refname="exception"/>
<interceptor-refname="alias"/>
<interceptor-refname="servletConfig"/>
<interceptor-refname="i18n"/>
<interceptor-refname="prepare"/>
<interceptor-refname="chain"/>
<interceptor-refname="scopedModelDriven"/>
<interceptor-refname="modelDriven"/>
<interceptor-refname="fileUpload"/>
<interceptor-refname="checkbox"/>
<interceptor-refname="multiselect"/>
<interceptor-refname="staticParams"/>
<interceptor-refname="actionMappingParams"/>
<interceptor-refname="params">
<paramname="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
</interceptor-ref>
<interceptor-refname="conversionError"/>
<interceptor-refname="validation">
<paramname="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-refname="workflow">
<paramname="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-refname="debugging"/>
</interceptor-stack>
<!--ThecompleteStackishereforbackwardscompatibilityfor
applicationsthatstillrefertothedefaultStackbythe
oldname-->
<interceptor-stackname="completeStack">
<interceptor-refname="defaultStack"/>
</interceptor-stack>
<!--Sampleexecuteandwaitstack.
Note:execAndWaitshouldalwaysbethe*last*interceptor.-->
<interceptor-stackname="executeAndWaitStack">
<interceptor-refname="execAndWait">
<paramname="excludeMethods">input,back,cancel</param>
</interceptor-ref>
<interceptor-refname="defaultStack"/>
<interceptor-refname="execAndWait">
<paramname="excludeMethods">input,back,cancel</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
拦截器
拦截器栈-->就是拦截器的集合
默认使用的拦截器栈defualtStack
包含哪些拦截器:
拦截器都完成什么功能?
下面通过一个案例来理解struts2的拦截器自定义的拦截器
操作:
在action的一个方法中,要进行权限的控制。如果是admin用户登入,就执行该方法,如果不是admin用户登入,就不能执行该方法
假设你只有完成登陆之后才能完成其它的操作
1、在intercept方法中的参数invocation是执行action的上下文,可以从
这里得到正在访问的action、Ognl值栈、请求路径、方法名称、命名空间
等信息。以帮助程序员在拦截器中做相应的处理工作
invocation.invoke();
分析:
先执行拦截器再执行action
拦截器/****/UserAction_delete.action
invocation.invoke();
/****/UserAction_query.action
invocation.invoke();
判断用户是否存在的拦截器:
要自定义拦截器需要实现com.opensymphony.xwork2.interceptor.Interceptor接口:
publicclassPermissionInterceptorimplementsInterceptor{
privatestaticfinallongserialVersionUID=-5178310397732210602L;
publicvoiddestroy(){
}
publicvoidinit(){
}
publicStringintercept(ActionInvocationinvocation)throwsException{
System.out.println("进入拦截器");
if(session里存在用户){
Stringresult=invocation.invoke();
}else{
return“logon”;
}
//System.out.println("返回值:"+result);
//returnresult;
}
}
说明:
<packagename="****"namespace="/test"extends="struts-default">
<interceptors>
<interceptorname=“permission"class="cn.****.aop.PermissionInterceptor"/>
<interceptor-stackname="permissionStack">
<interceptor-refname="defaultStack"/>
<interceptor-refname="permission"/>
</interceptor-stack>
</interceptors>
<actionname="helloworld_*"class="cn.****.action.HelloWorldAction"method="{1}">
<resultname="success">/WEB-INF/page/hello.jsp</result>
<interceptor-refname="permissionStack"/>
</action>
</package>
因为struts2中如文件上传,数据验证,封装请求参数到action等功能都是由系统默认的defaultStack中的拦截器实现的,所以我们定义的拦截器需要引用系统默认的defaultStack,这样应用才可以使用struts2框架提供的众多功能。
如果希望包下的所有action都使用自定义的拦截器,可以通过<default-interceptor-refname=“permissionStack”/>把拦截器定义为默认拦截器。注意:每个包只能指定一个默认拦截器。另外,一旦我们为该包中的某个action显式指定了某个拦截器,则默认拦截器不会起作用。
怎么样获取作用域中复合对象的属性值:
在Action
提供次属性的get方法
在页面中:
<h4>欢迎${sessionScope.user.name}登陆后台管理</h4>
采用的是EL的写法:
<br/>
${user.name}//page---request--session--application<br/>
${user["name"]}:::${user["name"]}<br/>
${sessionScope['user'].name}::${sessionScope['user'].name}<br/>
${sessionScope.user["name"]}::${sessionScope.user["name"]}<br/>
<br/>
利用struts2标签取值:pagerequestsessionapplication
#作用域:
<br/>
<s:propertyvalue="#session['user'].name"/>
<br/>
<s:propertyvalue="#session.user.name"/>
<s:propertyvalue="#session.user['name']"/>
文件上传的时候,
进行过滤文件上传的类型
文件上传的大小
<actionname="FileAction_*"class="www.****.struts_upload_interceptor.action.FileAction"method="{1}">
<interceptor-refname="fileUpload">
<!--设置文件上传的类型:Tomcat/conf/web.xml文件就有文件的类型的名称-->
<paramname="allowedTypes">image/jpeg,image/pjpeg,application/octet-stream,application/x-zip-compressed</param>
<paramname="maximumSize">5242880</param>
</interceptor-ref>
<!--默认的拦截器栈-->
<interceptor-refname="defaultStack"/>
<resultname="success">/index.jsp</result>
</action>
这就是拦截器的使用案例一。
Struts2验证机制
服务器端:
1、对action中所有的方法都进行验证
手工编写代码:
@Override
publicvoidvalidate(){
System.out.println("--------"+this.name+"=");
if(("").equals(this.name)||this.name==null){
this.addFieldError("name","用户名不能为空");
}
}
如果验证方法处理完addFieldError中有错误信息,那么就不进行处理业务方法。
2、对action中指定的方法进行验证
手工编写:validateXxx()Xxx是方法的名称第一个字母大写。
publicvoidvalidateLogin(){
System.out.println("--------"+this.name+"=");
if(("").equals(this.name)||this.name==null){
this.addFieldError("name","用户名不能为空");
}
}
通过struts2
<s:fielderror/>打印错误的信息
客户端处理
Js脚本进行处理
基于XML配置方式实现
1、对action中所有的方法进行处理
要求验证文件必须和action在同一个包中
并且文件名必须ActionClassName-validation.xml.
介绍struts2里边验证器
在:xwork-core-2.3.8.jar包含com.opensymphony.xwork2.validator.validators这个包中有一个default.xml文件:内容如下:
使用方式:如下:
required必填校验器
<field-validatortype="required">
<message>性别不能为空!</message>
</field-validator>
requiredstring必填字符串校验器
<field-validatortype="requiredstring">
<paramname="trim">true</param>
<message>用户名不能为空!</message>
</field-validator>
stringlength:字符串长度校验器
<field-validatortype="stringlength">
<paramname="maxLength">10</param>
<paramname="minLength">2</param>
<paramname="trim">true</param>
<message><![CDATA[产品名称应在2-10个字符之间]]></message>
</field-validator>
email:邮件地址校验器
<field-validatortype="email">
<message>电子邮件地址无效</message>
</field-validator>
regex:正则表达式校验器
<field-validatortype="regex">
<paramname="expression"><![CDATA[^1[358]\d{9}$]]></param>
<message>手机号格式不正确!</message>
</field-validator>
int:整数校验器
<field-validatortype="int">
<paramname="min">1</param>
<paramname="max">150</param>
<message>年龄必须在1-150之间</message>
</field-validator>
字段OGNL表达式校验器
<fieldname="imagefile">
<field-validatortype="fieldexpression">
<paramname="expression"><![CDATA[imagefile.length()<=0]]></param>
<message>文件不能为空</message>
</field-validator>
</field>
2、对action中指定方法进行校验
采用ActionClassName-ActionName-validation.xml
即可。
注意事项:
当为某个action提供了ActionClassName-validation.xml和ActionClassName-ActionName-validation.xml两种规则的校验文件时,系统按下面顺序寻找校验文件:
1。AconClassName-validation.xml
2。ActionClassName-ActionName-validation.xml
系统寻找到第一个校验文件时还会继续搜索后面的校验文件,当搜索到所有校验文件时,会把校验文件里的所有校验规则汇总,然后全部应用于action方法的校验。如果两个校验文件中指定的校验规则冲突,则只使用后面文件中的校验规则。
当action继承了另一个action,父类action的校验文件会先被搜索到。
假设UserAction继承BaseAction:
<actionname="user"class="cn.****.action.UserAction"method="{1}">
</action>
访问上面action,系统先搜索父类的校验文件:BaseAction-validation.xml,BaseAction-user-validation.xml,接着搜索子类的校验文件:UserAction-validation.xml,UserAction-user-validation.xml。应用于上面action的校验规则为这四个文件的总和。