Struts2 防止重复提交问题(转)相信都有表单提交的情况, 很多时候不希望出现重复提交原来的数据, 那么如何
Struts2 防止重复提交问题(转)
相信都有表单提交的情况, 很多时候不希望出现重复提交原来的数据, 那么如何防止重复提交问题, 下面我是思考和一些参考整理的结果, 先看看其原理:
?
防止重复提交原理:?
首先,在页面访问的时候server端产生一个标志位,其保存在session中,同时该标志位放到访问的页面的某个元素中(通常为隐藏域);?
其次,在session存在的有效时间内,没有其它操作时其值保持不变,当提交表单到server端时,会判断client端提交过来的标志位和server端的标志位的值是否相等;
最后,判断标志位的值,如果相等,则执行自己期望的操作;如果不相等,则转向指定的页面;
这个原理在我以前在ASP中实现的这个功能是一样的,在JAVA,PHP都适用,只是实现语言不同而已, 在struts2中中只不过别人都是封装成一些标签(client,server两端都做处理)可直接使用罢了,其实完全可以自己重写而不必受制于那些框架,但对开发着要求要明白其原理,程序写法也稍加注意吧;
下面看在JAVA的 struts2 是如何实现 防止重复提交问题 的:
1、使用Struts2的表单标签,其中需要增加token标签。如下:
?
[java]?view plaincopy
- ...??
- <%@?taglib?uri="/struts-tags"?prefix="s"?%>???
- <!--?注意:要确保jsp中能使用struts2标签,在web.xml中定义的过滤类型为任意,即/*?-->??
- ...??
- <s:form?action="goURL"?name="form1">???
- ...??
- <s:token/>???
- <s:reset/><s:submit/>???
- </s:form>???
2、
在struts配置文件中增加token拦截器。(token 和 token-session 拦截器的启用,是在 struts.xml 配置文件中,既可以为包启用,也可以单独为某个 action 启用)?
?
2.1 ?在 Action 中启用 token ,该拦截器仅为本 action 使用,
?
[html]?view plaincopy
- <?xml?version="1.0"?encoding="UTF-8"?>???
- <!DOCTYPE?struts?PUBLIC???
- "-//Apache?Software?Foundation//DTD?Struts?Configuration?2.0//EN"???
- "http://struts.apache.org/dtds/struts-2.0.dtd">???
- <struts>???
- <package?name="myGC"?extends="struts-default">???
- <action?name="goURL"?class="com.gc.actions.goURLAction"?method="execute">???
- <interceptor-ref?name="defaultStack"/>???
- <interceptor-ref?name="token"/>???
- <result?name="success">/success.jsp</result>???
- <result?name="invalid.token">/inputPage.jsp</result>???
- </action>???
- </package>???
- </struts>???
2.2 在包中启用 token , 该拦截器可为该包内所有的 action 元素使用;
注意,需要name为invaid.token的result。这是当拦截器判断是重复提交的时候,会转向的视图页面。
?
?
[html]?view plaincopy
- <package?name="myGC"?extends="struts-default">???
- ??<interceptors>???
- ??????<interceptor-stack?name="myStack">?????
- ??????<interceptor-ref?name="token"/>?????
- ??????<interceptor-ref?name="defaultStack"/>??????????
- ??????</interceptor-stack>????
- ??</interceptors>???
- ??<default-interceptor-ref?name="myStack"/>?????
- ??<action?name="goURL"?class="com.gc.actions.goURLAction">???
- ????<result?name="success">/success.jsp</result>???
- ????<result?name="invalid.token">/inputPage.jsp</result>???
- ??</action>???
- </package>???
3、invaid.token页面打印错误信息,一样可以使用struts标签。如下:?
?
?
[html]?view plaincopy
- <s:actionerror/>??
?
注意: ?如果在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需要用到,需要注意的是,当没有指定任何拦截器时,默认是隐式启用默认的拦截器的;