编程语言 php java

Struts 防止重复提交方法

java HTML我帮您 1年前  0次浏览
用户重复提交同一个HTML表单的原因不在乎两种:一是操作失误;二是某个表单的处理时间过长而使得用户不知该如何是好。在某些场合,重复提交同一个HTML表单的后果可能非常严重;在另外一些场合,这种情况也许只会令人敢不快而已。例如,在使用使用卡进行在线支付到时候,如果服务器的响应速度太慢,用户难免会再次点击提交按钮,而这就有可能导致那张信用卡上的金额被划走两次。我们再来看一个后果没那么严重的例子 -- 用来录入产品信息的表单,重复提交这些表单可能同一中产品被添加二次。

在防止重复提交同一个表单方面,不同的浏览器有这不同的行为。Mozilla Firefox浏览器对重复点击同一按钮将不予理睬,这为我们提供了某种形式的保护。其他品牌的浏览器,包括IE在内,目前还没有实现能够防止重复提交的功能。此外,Mozilla和非Mozilla浏览器都算上,如果在请求被处理之后按下了浏览器本身的Refresh/Reload(刷新)按钮。同样的请求就会被再次提交,而这显然是一种重复提交行为。因为,质押重复提交有可能给你的业务逻辑带来不良影响,你就必须采取必要的预防措施。

Struts已经内置了能够防止用户重复提交同一个HTML表单的功能。它采用的办法在其他一些用来开发Web应用程序的技术里也可以见到:让服务器生成一个唯一标记,并在服务器和表单里保存一份这个标记的副本。此后,在用户提交表单的时候,表单里的标记将虽说这其他请求参数一起发送到服务器,服务器将对它收到的标记和它留存的标记进行比较。如果两者匹配,这次从提交来的表单就是被认为是有效的,服务器将对之做出必要的处理并重新设置一个标记。随后(因为不小心)提交相同的表单就会失败,因为服务器上的标记已经重置。
下面看在JAVA的 struts2 是如何实现 防止重复提交问题 的:

1、使用Struts2的表单标签,其中需要增加token标签。如下:


...
<%@ taglib uri="/struts-tags" prefix="s" %>
注意:要确保jsp中能使用struts2标签,在web.xml中定义的过滤类型为任意,即/*
...

...





2、在struts配置文件中增加token拦截器。(token 和 token-session 拦截器的启用,是在 struts.xml 配置文件中,既可以为包启用,也可以单独为某个 action 启用)

2.1 在 Action 中启用 token ,该拦截器仅为本 action 使用,



"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">





/success.jsp
/inputPage.jsp





2.2 在包中启用 token , 该拦截器可为该包内所有的 action 元素使用;
注意,需要name为invaid.token的result。这是当拦截器判断是重复提交的时候,会转向的视图页面。











/success.jsp
/inputPage.jsp




3、invaid.token页面打印错误信息,一样可以使用struts标签。如下:





注意: 如果在session失效时间外再提交页面,同样出现不相等的情况,因而转到 invaid.token 指定的视图页面中去;

总结:
1、JSP使用< s:token/ >标签的时候,Struts2会建立一个UUID(全局唯一的字符串)放在session中,并且会成为一个hidden放在form中。


2、token拦截器会判断客户端form提交的token值和session中保存的值是否equals。如果equals则执行Action。否则拦截器直接返回invaid.token结果转向对应的视图,Action对应的方法也不会执行;


3、当指定了别的拦截器时,如本例的token,仅仅完成某项功能,后面同时需要指定默认的拦截器,因struts2需要用到,需要注意的是,当没有指定任何拦截器时,默认是隐式启用默认的拦截器的;

发表评论