最近完成了阻止struts2重复提交的功能
1.作用:经常的一个表单提交需要一定时间,在等待时间内,服务器正在处理请求,而用户可能会不断点击提交按钮,造成一个订单面的重复提交
2.如何模拟重复提交:一个表单,点击提交按钮后,刷新,会提示:(见附件)
也就是再次提交当前页面。
3.使用技术:struts2的token标签
简介:jsp页面读取到<s:token/> 标签时,会在session中设置一个struts.token值,同时将此值在.jsp页面翻译做:(表单中增加两个隐藏字段,struts.token值随机生成)
如我们jsp页面写<s:token name=”mytoken”/>
那么翻译做:
<input type="hidden" value=" mytoken " name="struts.token.name">
<input type="hidden" value="FKZCDK5XC881W05MLVK0JQJP04M0KZC2" name=" mytoken ">
如果写作<s:token/>
则翻译做:
<input type="hidden" value="struts.token" name="struts.token.name">
<input type="hidden" value="FKZCDK5XC881W05MLVK0JQJP04M0KZC2" name="struts.token">
接着~
提交表单到我们指定的Action时先会先经过token拦截器, token拦截器会从form表单中获取token值, 再从session中获取token值(注:我们可以在action中设置mytoken属性,String类型的,加get、set方法,提交表单的时候就会像表单其他属性一样set值进去,取值出来;同时,我们可以取得httpsession,从里面getAttribute(“mytoken”)出来), 比较两个值是否相同, 不相同, 直接返回 invalid.token(invalid.token应配置成重复提交表单的提示信息页面)相同,remove掉session里的 struts.token值(防止被重复使用), 继续正常流程
例如,我们进入a.jsp,那么里面就默认有token的隐藏域了,session里也有token值了。我们第一次点击提交,在进入action之前会进去到token拦截器里,token取出页面和session里的token比对,相同的则提交表单。不同的,根据我们设置,比如返回页面,显示提示信息(<s: actionerror/>),跳到错误页面,进入等待页面等。这个看我们struts.xml的配置了。
说一句:无论那种处理,使用struts2的token来阻止重复提交修改的就俩地:
一、form表单加<s:token/>(如果是错误信息显示<s: actionerror/>)
二、配置文件struts.xml(配置拦截器,配置跳转页面,等待页面)
注:写上一后,session和页面就有token值了。我们在struts2的action中可以取到这两处的值~
但是,拦截器不会起作用,也就是说不会阻止表单提交
本人遇到的不解是:
1、页面解析到<s:token/>时候会将此token放到session中,同时在页面解析做两个hidden。
2、相同的则会提交表单,并移除session里的token(真的吗?),不同则会视为重复提交,阻止提交
使用firebug发现:第一次提交表单,session里的token和表单里的一样,刷新之后,session里的token变了(但是不是空的),而表单里的值和先前一样没有变(这个和上面说的有悖)
有个点需要注意:
两个token一样表单才可提交;不一样就视为重复提交了,会被阻止
本人使用的是,如果重复提交,弹出对话框,并终止程序进入action
1.页面
<body οnlοad="show(<s:property value='repeat'/>)">
<form>
<s:token name="mytoken"/>
</form>
</body>
js:if(){alert("stop!repeat");}
2.action
private String mytoken;(get/set)
private boolean repeat;(get/set)
public void validate() {
String tokenInSession = (String) httpSession.getAttribute("token");
if (StringUtils.isNotEmpty(mytoken)
&& StringUtils.isNotEmpty(tokenInSession)) {
if (!tokenInSession.equals(token)) {
// no
repeatFlag = true;
addFieldError("repeatMsg", "repeat");//这句话没有显示,单纯的告诉calidate验证不通过别执行下面的action了
}
}
}
struts.xml中配置没有改变只是多一个
<result name="input">/view/goods_apply.jsp</result>
注:name="input"在什么时候用呢?
答:在validate验证错误的时候会跳到这个页面~
上面写的更多的是我自己总结出来方法和原理,有不对的地方希望大家多指教。想具体学习,可以网搜(struts2阻止重复提交)会有很多很全面的文章
祝大家学习愉快~~~