求:Struts重复提交问题解决方案
解决方案 »
- jbpm4.4:同步分裂、或汇聚流程
- 请问一个javascript树的问题
- 很急又很简单的问题,,
- 兄弟有关jsp阿拉伯语资源文件显示的问题,请大侠帮忙。在线急等。问题见正文
- (急急急)请问各位大哥:一个关于用用struts的Package org.apache.struts.upload 的问题
- [求助]Hibernate配置文件里myeclipse.connection.profile是什么意思啊?
- jsp操作字符串问题?
- 高效 Java Web 应用开发框架 JessMA v3.2.2 正式发布
- jsp中从数据库中取的字段的值问题
- hibernate延迟加载分页session.createFilter(arg0,arg1)
- Fckeditor的使用问题?
- Jsp中怎样做文件上传和下载呀!
在《JSP避免Form重复提交的三种方案》一文中给出了三种方案,我们这里由于是普通JSP,没用struts,所以采用了第一种方案。但是应当注意的是在这里不能在form中检查,因为我们需要点击日历组件,将造成本没有多次提交却被当成多次提交。还有就是我们置的变量不能和函数名同名,不要也无法检查。源码如下: var checkrepeatSubmit = false; function repeatSubmit(){ if (checkrepeatSubmit){ alert('禁止重复提交!'); return false; } //alert('提交成功'); checkrepeatSubmit = true; return true;}检查代码如下:<IMG onClick="activecard();" style="cursor:pointer " height=27 alt="确认投保" src="cardimages/qrtb.gif" width=80 border=0>然后在activecard()中检查重复提交repeatSubmit()。function activecard(){ onsame(); if(repeatSubmit()){ if (checksave()){ var s="请确认投保信息真实、准确、完整,因投保信息虚假或遗漏导致的相关责任由投保人及被保险人承担,"; s+="确认投保后相关信息不能再进行修改。"; s+="确认投保请选择[确认],重新修改投保信息请选择[取消]"; //alert("嗨! 你好1"); if (confirm(s)) { //alert("嗨! 你好2"); document.active.action='clientinfo.jsp?key=active'; //alert("嗨! 你好3"); document.active.submit(); //alert("嗨! 你好4"); } } } }附 网上给出的提交方案:JSP避免Form重复提交的三种方案
1 javascript ,设置一个变量,只允许提交一次。
<script language="javascript">
var checkSubmitFlg = false;
function checkSubmit() {
if (checkSubmitFlg == true) {
return false;
}
checkSubmitFlg = true;
return true;
}
document.ondblclick = function docondblclick() {
window.event.returnValue = false;
}
document.onclick = function doconclick() {
if (checkSubmitFlg) {
window.event.returnValue = false;
}
}
</script>
<html:form action="myAction.do" method="post" onsubmit="return checkSubmit();">
2 还是javascript,将提交按钮或者image置为disable
<html:form action="myAction.do" method="post"
onsubmit="getElById('submitInput').disabled = true; return true;">
<html:image styleId="submitInput" src="images/ok_b.gif" border="0" />
</html:form> 3 利用struts的同步令牌机制
利用同步令牌(Token)机制来解决Web应用中重复提交的问题,Struts也给出了一个参考实现。
基本原理:
服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。
if (isTokenValid(request, true)) {
// your code here
return mapping.findForward("success");
} else {
saveToken(request);
return mapping.findForward("submitagain");
}
Struts根据用户会话ID和当前系统时间来生成一个唯一(对于每个会话)令牌的,具体实现可以参考TokenProcessor类中的generateToken()方法。
1. //验证事务控制令牌,<html:form >会自动根据session中标识生成一个隐含input代表令牌,防止两次提交
2. 在action中:
//<input type="hidden" name="org.apache.struts.taglib.html.TOKEN"
// value="6aa35341f25184fd996c4c918255c3ae">
if (!isTokenValid(request))
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("error.transaction.token"));
resetToken(request); //删除session中的令牌
3. action有这样的一个方法生成令牌
protected String generateToken(HttpServletRequest request) {
HttpSession session = request.getSession();
try {
byte id[] = session.getId().getBytes();
byte now[] =
new Long(System.currentTimeMillis()).toString().getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(id);
md.update(now);
return (toHex(md.digest()));
} catch (IllegalStateException e) {
return (null);
} catch (NoSuchAlgorithmException e) {
return (null);
}
}
2>.拦截器中引用token拦截器。
3>.Action中配置<result name="invalid.token"></result>问题解决
在form标签中使用<s:token>