2.拦截器是struts2的一个重要特性。Struts2框架的大多数核心功能都是通过拦截器来实现的,像避免表单重复提交、类型转换、对象组装、验证、文件上传等,都是在拦截器的帮助下实现的。拦截器之所以称为“拦截器”,是因为它可以在Action执行之前和执行之后拦截调用。
表单的重复提交的操作:
若刷新表单页面, 再提交表单不算重复提交.
(1)在不刷新表单页面的前提下:
(2)多次点击提交按钮
(3)已经提交成功, 按 "回退" 之后, 再点击 "提交按钮".
(4)在控制器响应页面的形式为转发情况下,若已经提交成功, 然后点击 "刷新(F5)“
重复提交的缺点:
(1) 加重了服务器的负担
(2)可能导致错误操作.
3.利用了token和tokenSession拦截器避免表单重复提交;
(1)原理:
当进入表单页面时,在session中存放一个标志量;在表单页面中添加一个隐藏域的值,该值就是session中标质量的值;当用户提交表单时,隐藏域的值会一并提交到后台,此时会把该值和session中的值进行匹配,如果匹配上,证明是第一次提交,立刻将session中的值改变,如果不匹配,就不执行后续的逻辑。
(2)Struts 提供的 token 标签可以用来生成一个独一无二的标记. 这个标签必须嵌套在 form 标签的内部使用, 它将在表单里插入一个隐藏字段并把标记值(隐藏域的字段的值)保存在HttpSession 对象里.:<s:token></s:token>;
Token 标签必须与 Token 或 TokenSession 拦截器配合使用, 这两个拦截器都能对标记进行处理.
Token 拦截器在遇到重复提交情况时, 会返回 invalid.token 结果并加上一个 Action 错误. 这种错误默认的消息是: The form has already been processed or no token was supplied, please try again.
TokenSession 拦截器采取的做法只是阻断后续的提交, 用户将看到同样的响应,但实际上并没有重复提交;
具体实例:
表单域:
<body>
<s:form action="sessionAction" method="post">
<s:token></s:token>
<s:textfield name="name" label="name"></s:textfield>
<s:submit></s:submit>
</s:form>
<s:debug></s:debug>
</body>
Struts.xml配置:
使用token的配置:
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="sessionAction" class="com.handler.SessionAction"
method="submit1">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="token"></interceptor-ref>
<result>/success.jsp</result>
<result name="invalid.token">error.jsp</result> //发生重复提交后的跳转页面
</action>
</package>
</struts>
使用tokenSession的配置:
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="sessionAction" class="com.handler.SessionAction"
method="submit1">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="tokenSession"></interceptor-ref>
<result>/success.jsp</result>
</action>
</package>
</struts>
Action域:
package com.handler;
import com.opensymphony.xwork2.ActionSupport;
public class SessionAction extends ActionSupport{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String submit1() throws Exception{
Thread.sleep(2000);
System.out.println(name+"添加成功");
/*if(name!=null){
throw new Exception();
}*/
return SUCCESS;
}
}
运行结果:
首次提交:
提交成功后跳转至success.jsp页面:
刚重复点击提交后,页面跳转error.jsp
当时使用TokenSession拦截器:会正常跳转到成功界面,但实际并没有多提交;