表单重复提交解决方案

Form表单重复提交是web开发中一个很常见的问题。先总结以下几种解决方案

模拟Action后台查询数据需要时间等待,此间用户可能会多次点击提交按钮或者刷新页面,此时Action也会反复执行多次,这并不是我们想要的。如下,模拟Action操作。

TestAction.java

 

public class TestAction {
	private User user;//省略get/set方法...
	public String execute() {
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("-------------业务处理-------------");
		System.out.println("user.username--->" + user.getUsername());
		System.out.println("user.age--->" + user.getAge());
		return "test";
	}
}

 

 struts.xml

<action name="test" class="com.lydia.web.action.TestAction" >
			<result name="test">/ognl.jsp</result>
<action>

 

 解决方案1:利用javascript脚步

 

index.jsp

   

<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8"%>
<html>
	<head>
		<script type="text/javascript" language="javascript">
			var isSubmitFlag = false;
			function checkSubmit(){
				if(!isSubmitFlag){
					isSubmitFlag = true;
					return true;
				}else{
				    alert("不能重复提交");
				    return false;
				}
			}
		</script>
	</head>
	<body>
		This is my JSP page.
		<br>
		<form name="form" action="test" method="post" onsubmit="return checkSubmit();">
			username : <input name="user.username" /> <br/>
			age : <input name="user.age " /><br/>
			<span id="t" style="color: red"></span>
			<input type="submit" value="提交"  id="sub"/>  
		</form>
	</body>
</html>

 

此种方法通过设置 onsubmit="return false" 来防止表单提交,类似的还可以在第一次提交后把提交按钮设置为不可用;或者显示正在提交中等。

function checkSubmit(){
	document.getElementById("tt").innerHTML="提交中...";
	document.getElementById("btu").disabled="disabled";
	return true;
	}

 

 

解决方案2:struts2的token令牌机制

这种做法非常简单,步骤如下

1)在jsp页面的表单中添加<s:token></s:token>标签。

2)修改struts.xml

    a,如果需要错误页面提示,点击多次也只提交一次,但是会跳转到错误页面提示表单重复提交了

       使用token

 

<action name="test" class="com.tarena.web.action.TestAction" >
		<result type="dispatcher" name="test">/ognl.jsp</result>
		<result type="redirect" name="index">/index.jsp</result>

		<result name="invalid.token">/error.jsp?message=重复提交</result>
	        <interceptor-ref name="token"></interceptor-ref>
		<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
     

 

b,不需要错误页面提示,即使点击多次也只提交一次。  使用tokenSession

 

<action name="test" class="com.tarena.web.action.TestAction" >
	<result type="dispatcher" name="test">/ognl.jsp</result>
	<result type="redirect" name="index">/index.jsp</result>

	<interceptor-ref name="tokenSession"></interceptor-ref>
	<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
 

 

注意:

a:当拦截器拦截到 当发生重复提交的action时候,会跳转到invalid.token指定的页面。

b:为了使用同一的错误页面,在错误页面上接受到message参数的值,可以在error.jsp使用${param['message']}

c:在提交页面的form中添加<s:token/>标签,需要在页面中加上

 

token的工作原理。我们会发现使用<s:token></s:token>后,jsp页面中会多出:

<input type="hidden" name="struts.token.name" value="struts.token" />

<input type="hidden" name="struts.token" value="HZC4XCH5K9Q3KEXR0D4HZKJI8PYOSAOJ" />

当页面提交的时候时候他会判断这个值是不是和session的一样,如果是一样的,你可以提交,并且会修改session里的值。如果你刷新或重复提交,那你页面上的值和session的值就不一样的,struts就不允许你提交数据了。就是这个原理。

参考文章:http://kingpingping.iteye.com/blog/1168254

猜你喜欢

转载自lydia-fly.iteye.com/blog/2018685