在页面中使用WebWork的token标签解决表单重复提交问题

迷途d书童 发布于 2012/03/09 12:20
阅读 256
收藏 0
 

在页面中使用WebWorktoken标签解决表单重复提交问题

 

王保政

 

我们的项目是基于Struts开发的,在设计时没有考虑重复提交的问题,所以用户在点击页面的提交,然后在下一个浏览器页面点后退,或者点提交时没跳转到新页面,在当前页面多次点击提交按钮,这两种情况都会产生重复提交的问题,例如用户基本信息维护的新增页面,点两次保存会向数据库提交两次,这时数据库中会新增两条记录。

后来我们引入了Webwork框架(项目的主框架仍然是基于struts的,只是将webwork配置到当前项目中,就可以使用webworktoken标签),通过Webworktoken标签解决了这个问题(当然不是必须引入webwork才能解决,而是webwork提供了现成的token标签供我们使用),下面是引入了webworktoken标签的JSP代码:

<%@ taglib uri="webwork" prefix="ww" %>

<html>

<head></head>

<body>

Please enter your 姓名:

<form action="helloWorld.action">

<ww:token name="UserInfo.token"/>

<input type="textfield" name="name" />

<input type="submit"/>

 </form>

</body>

</html>

<%

String s = (String)session.getAttribute("UserInfo.token");

if(s!=null){

System.out.println(s);

}

%>

其中UserInfo.token是我们为当前表单的token定义了一个名字,不同的表单可以定义不同的token名。

访问此JSP,在浏览器中查看此JSP生成的html代码:

 

<html>

<head></head>

<body>

Please enter your 姓名:

<form action="helloWorld.action">

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

<input type="hidden" name="UserInfo.token" value="8QXRRY5TI9CVRZO29VCZ6LQDOOEXF4NB"/>

<input type="textfield" name="name" />

<input type="hidden" name="operate" value="updateUser" />

<input type="submit"/>

 

</form>

 

</body>

 

</html>

可以看到webwork在表单中生成了一个webwork.token.nameUserInfo.token的隐藏列,webwork除了生成了隐藏列外,还将token值写入到了session中的UserInfo.token变量。

 

在录入页面中生成了token之后,在struts的控制层如何控制表单不重复提交?见下面的控制层的代码:

 

try

{

String requestToken = request.getParameter("UserInfo.token");

String sessionToken = (String)session.getAttribute("UserInfo.token"); //JSP中直接使用//session,在Strutsaction类中用request.getSession()获取Session

System.out.println("请求中的token:");

System.out.println(requestToken);

if(sessionToken.equals(requestToken))

{

   System.out.println("1:token值相同,下面处理正常业务,并删除Session中的token!!");

   session.setAttribute("UserInfo.token","0"); //也可以直接removeAttribute,这样在异常里//提示session中的token为空,不能重复操作!设为等同于清空,因为生成的token肯定不//,这样做是为了不抛出异常。

   //session.removeAttribute(“UserInfo.token”);

      

}

else

{

   System.out.println("2:token值不同,为重复提交!!");

}

 

 

}

catch(Exception ex)

{

   System.out.println("session中的token被删除,为重复提交!");

}

 

token防止重复提交的大致思路是这样的:

(1)              在开始访问一个页面时Webwork新建了一个token隐藏字段,另外将token写入到session中,例如上面的UserInfo.token字段和session中的UserIno.token字段,在一开始访问用户录入页面时,两个值相等。

(2)              在录入页面点提交,然后控制层的类就开始判断request参数中的UserInfo.token(对应的UserInfo.token隐藏字段)和session中的UserInfo.token的值是否相等,如果相等,则说明是第一次访问,可以提交,但处理完业务后,要将此token清空。

(3)              如果是录入页面通过后退或重复点击进行保存的操作,因为这两种情况都不会再次在Session中生成UserInfo.token(此值已在处理完业务后被清空),所以控制层根据session中的此值为空或不等于request中的token值来判断是否为重复提交。

 

Webwork可以在控制层配置TokenInterceptor,可以不需要将token控制代码写到Action类中。以上实现方案供大家参考,在项目中如果需要用这种方式防止重复提交,实际上只需要在form中添加<ww:token name=”yourformtokenname”/>,并将控制层的防止重复提交的代码封装到Action基础类,如果使用webwork框架,直接为action配置TokenInterceptor就可以了。


原文链接:http://blog.csdn.net/baozhengw/article/details/1847973
加载中
返回顶部
顶部