最近完成了阻止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 onload="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阻止重复提交)会有很多很全面的文章
祝大家学习愉快~~~
?
?
?