您的位置:首页 > 编程语言 > Java开发

Struts中防止表单重复提交

2016-04-15 15:42 543 查看
先了解下为什么会有重复提交问题:

重复提交说白了就是重复操作了相同的记录,导致内存中有多条相同的记录的情况。

1、 在表单提交到一个action,而action又通过请求转发dispatcher(forward)的方式响应了一个JSP(HTML)页面,
此时地址栏还保留着action的那个路径,在响应页面点击“刷新”,这就是一个重复提交的情况。

2、在响应页面没有到达时,重复点击提交按钮。即我们所说的网络阻塞情况下。

3、点击返回,再点击提交。例如:登陆成功后,后退后再登陆。

处理表单重复提交有2中方法:客户端处理和服务端处理:

客户端处理:(用js定义一个全局的变量来控制表单不提交)

定义一个js:

<script language="javascript">
var checkSubmitFlg = false;
function checkSubmit() {
if (checkSubmitFlg == true) {
return false;
}
checkSubmitFlg = true;
return true;
}
</script>
总结:处理表单重复提交的方法

<s:form name="userForm" method="post" action="user/add_user" onSubmit="return checkSubmit();">

服务端处理(令牌机制)
介绍下struts2提供了一种Session级别的令牌机制Token

原理:

1.在regist.jsp页面使用<s:
token />中生成一个唯一随机值,当用户访问此表单的网页时,就将其保存到Session中, 同时将其保存为表单的隐藏域的值.

2.在处理注册的请求时,获取Session中值,获取请求参数的值,比较两者是否相同, 如果相同说明不是重复提交,请求通过同时删除session中保存的值, 如果不相同则是重复提交, 不能通过.

这里我就介绍下用token来防止:

<div style="color: rgb(51, 51, 51); text-align: left;"><span style="font-family: 'Microsoft Yahei', 微软雅黑, arial, 宋体, sans-serif;">					<s:form name="loginForm" method="post" action="login"</span></div><div style="color: rgb(51, 51, 51); text-align: left;">						theme="simple"></div><span style="color:#333333;">						<tr>
</span><div style="color: rgb(51, 51, 51); text-align: left;"><span style="font-family: 'Microsoft Yahei', 微软雅黑, arial, 宋体, sans-serif;">							<td width="30" height="31"><input name="user.userName"</span></div><span style="color:#333333;">							<td width="70" height="31" align="center">用户名:</td>
</span><div style="color: rgb(51, 51, 51); text-align: left;"><span style="font-family: 'Microsoft Yahei', 微软雅黑, arial, 宋体, sans-serif;">							<td width="20" height="31" align="right"><s:fielderror</span></div><span style="color:#333333;">								type="text" class="input"></td>
fieldName="userName"></s:fielderror></td>
</span><div style="color: rgb(51, 51, 51); text-align: left;"><span style="font-family: 'Microsoft Yahei', 微软雅黑, arial, 宋体, sans-serif;">							<td width="30" height="29"><input name="user.passWord"</span></div><span style="color:#333333;">						</tr>
<tr>
<td width="70" height="29" align="center">密  码:</td>
</span><div style="color: rgb(51, 51, 51); text-align: left;"><span style="font-family: 'Microsoft Yahei', 微软雅黑, arial, 宋体, sans-serif;">							<td width="20" height="31" align="right"><s:fielderror</span></div><span style="color:#333333;">								type="password" class="input">
</td>
fieldName="password"></s:fielderror></td>
</tr>
</span><div style="color: rgb(51, 51, 51); text-align: left;"><span style="font-family: 'Microsoft Yahei', 微软雅黑, arial, 宋体, sans-serif;">								type="submit" name="Submit" value="登陆" class="button"></span></div><span style="color:#333333;">						<tr>
<td height="30" colspan="2" align="center"><input
  <input type="reset" name="Submit2" value="重置"
</span><div style="text-align: left;"><span style="font-family: 'Microsoft Yahei', 微软雅黑, arial, 宋体, sans-serif;"><span style="color:#333333;">						</span><span style="color:#ff0000;"><s:token /></span></span></div><span style="color:#333333;">								class="button">
</td>
</span><div style="color: rgb(51, 51, 51); text-align: left;"><span style="font-family: 'Microsoft Yahei', 微软雅黑, arial, 宋体, sans-serif;">						</tr></span></div>


然后再struts.xml中配置一个拦截器:
<span style="white-space:pre">		</span><interceptors>
<interceptor-stack name="tokenStack">
<interceptor-ref name="token" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
在需要拦截的action中配置该拦截器:
<span style="color: rgb(51, 51, 51); white-space: pre;">		</span><span style="color:#333333;"><action name="login" class="loginAction" method="login">
<interceptor-ref name="tokenStack"></interceptor-ref>
</span><span style="color:#ff0000;"><result name="invalid.token">/WEB-INF/error/error.jsp</result></span><span style="color:#333333;">
<!-- 这里用redirect防止在刷新时造成重复提交表单的问题 -->
<result name="login_success" type="redirectAction">empty/manage_empty</result>
<result name="input" type="redirect">/index.jsp</result>
</action></span>

ps:

以前说重定向可以解决表单重复提交的问题,但这只能防止用户点击刷新按钮,如果用redirect,url会改变,也就没有重复提交的问题,但是当我点击浏览器中的返回,然后再点击提交,如此反复,仍然在重复调用action,这也是重复提交,这时就要用token防止了。

总结:如果使用客户端处理,则重复提交不上去,页面也不会跳转。

如果用服务端处理,需要定义一个重复提交的页面,这样做的好处是可以自己处理重复提交的业务逻辑。

总之,仁者见仁智者见智……

总结:处理表单重复提交的方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: