在action执行之前或执行之后,拦截执行其他方法。一般用于权限、验证等功能.符合
AOP(面向切面编程、面向方法编程,在方法执行前\中\后先执行其他方法)规范.
<interceptor-ref name="timer"/>
该标签用于引用其他外部的拦截器。
<interceptor-stack name="defaultStack">
该标签用于将多个拦截器按照顺序组合在一起,取一个名字供action统一调用
1.拦截器配置方式,自定义配置:
<interceptors>
<interceptor name="名称" class="自定义拦截器类"/>
</interceptors>
自定义拦截器类必须实现Interceptor接口或继承该接口下的某个实现类
action标签中用<interceptor-ref name="要引用的拦截器名称"/>
2.拦截器执行的过程:
用户请求Action中某个方法(reg方法),被拦截器拦截,执行intercept方法,处理完毕
后,调用invoke方法,invoke方法会继续往下执行,如果还有拦截器,就继续调用后续拦截器,
当后续拦截器执行invoke方法时,如果没有其他拦截器,那就执行用户请求的reg方法,该方法
执行完毕后,会return字符串(return "success"),该字符串就会被传递最后的那个拦截器
中,该拦截器return后,就会把这个字符串继续往上一个拦截器中传递,一直传递到最开始的拦截器中,
return该字符串后,就寻找Action的result标签的name,从而跳转到对应的资源
reg.action------>拦截器1拦截完毕后,执行invoke()----->拦截器2拦截完毕后,执行invoke()
<----return "success"
<----拦截器1,return "success"
跳转到某个页面<---找到对应result的name
两种验证:
1.编码方式校验:
a.继承ActionSupport类,重写validate方法
当用户发送请求时,先执行action中属性对应的set方法,把页面的值赋给属性,再调用validate方法
代码做校验,逻辑验证不通过时,可将消息保存在FiledError(Map)对象中,框架会自行判断该Map中
是否为null,不为null时,就会跳转到input属性指向的页面资源,同时把该Map带到页面上,所以在
页面上可以使用<s:fielderror>标签打印集合中的所有消息
b.继承ActionSupport类,针对调用的Action具体方法启用校验,格式如下validateXxx,Xxx代表
方法名称,首字符大写. 意思是除了调用该方法才去执行校验,调用其他方法不执行校验功能。
2.配置方式校验:
a.上面1的方式不变,只是把重写validate方法去掉,做成配置文件
在action包下编写配置文件:
调任何方法都会调用校验:
Action的类名-validation.xml
针对具体方法前校验:
Action的类名-该Action中调用的方法名称-validation.xml
文件上传:
a.在表单form配置enctype="multipart/form-data" method="post"//必配的
b.action中写好上传的文件代码,如果上传出错(超出默认2M等等),就会寻找input属性对应的页面资源,
将错误信息带到该页面,页面上配置<s:fielderror/>可显示错误信息 //需导入标签库
如果控制到文件的大小、上传的后缀、类型等,需要配置fileupload拦截器,配置如下:
<interceptor-ref name="defaultStack">
<!--寻找defaultStack中fileUpload拦截器,设定最大上传的字节大小 -->
<param name="fileUpload.maximumSize">10485760</param>
<!--寻找defaultStack中fileUpload拦截器,设定允许的后缀 -->
<param name="fileUpload.allowedExtensions">.doc,.zip,.rar</param>
<!-- 寻找defaultStack中fileUpload拦截器,设定允许的文件类型
<param name="fileUpload.allowedTypes">application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,text/plain</param>
-->
</interceptor-ref>
上传过程中违反了上述配置,就会将struts2-core-xxx.jar包下struts-messages.properties文件中对应key的值输出在input属性指定的页面上。
key消息如下:
//下载出错
struts.messages.error.uploading=Error uploading: {0}
//文件字节数超出规定长度
struts.messages.error.file.too.large=File too large: {0} "{1}" "{2}" {3}
//文件内容不匹配
struts.messages.error.content.type.not.allowed=Content-Type not allowed: {0} "{1}" "{2}" {3}
//文件后缀不匹配
struts.messages.error.file.extension.not.allowed=File extension not allowed: {0} "{1}" "{2}" {3}
另外这些消息如果想改成自定义的话,需要在src下重新建立配置文件(例如test.properties),该配置中把上述key对应的value消息改成自定义
,再去struts.xml中配置<constant name="struts.custom.i18n.resources" value="test"/>,这时自定义配置就会
替代掉上述配置,从而打印自定义消息
struts2与servlet API 交互:
1.使用Action的三种方式
a.继承ActionSupport类
b.实现Action接口
c.不继承不实现任何接口或类
前两种好处是可以直接使用父类或接口中的变量或方法,不足是耦合度较高,最后一种
耦合度低,但需要通过其他方式获取某些对象,比喻request\session对象
2.页面控件的所有值可以在Action中通过封装成对象的方式封装值,但要注意页面
上控件name的取名方式(对象实例名称.属性)
3.在struts.xml中可以获取Action中属性的值,语法${变量}
4.Action中与Servlet API交互的几种方式
a.直接获取ActionContext中的对应的Map对象 ActionContext ac = ActionContext.getContext();
b.实现对应的接口,例如ServletRequestAware、ServletContextAware
c.实现对应的接口,例如RequestAware\SessionAware\ApplicationAware
除了b第二种方式是采用Servlet的原型API以外,其他两种都是用Struts中的Map实现