Struts2 防止重复提交问题

来源:互联网 发布:广告语录音软件 编辑:程序博客网 时间:2024/05/01 06:49

相信都有表单提交的情况, 很多时候不希望出现重复提交原来的数据, 那么如何防止重复提交问题, 下面我是思考和一些参考整理的结果, 先看看其原理:


防止重复提交原理: 

首先
,在页面访问的时候server端产生一个标志位,其保存在session中,同时该标志位放到访问的页面的某个元素中(通常为隐藏域); 

其次,在session存在的有效时间内,没有其它操作时其值保持不变,当提交表单到server端时,会判断client端提交过来的标志位和server端的标志位的值是否相等;

最后,判断标志位的值,如果相等,则执行自己期望的操作;如果不相等,则转向指定的页面;


这个原理在我以前在ASP中实现的这个功能是一样的,在JAVA,PHP都适用,只是实现语言不同而已, 在struts2中中只不过别人都是封装成一些标签(client,server两端都做处理)可直接使用罢了,其实完全可以自己重写而不必受制于那些框架,但对开发着要求要明白其原理,程序写法也稍加注意吧;


下面看在JAVA的 struts2 是如何实现 防止重复提交问题 的:

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

[java] view plaincopy
  1. ...  
  2. <%@ taglib uri="/struts-tags" prefix="s" %>   
  3. <!-- 注意:要确保jsp中能使用struts2标签,在web.xml中定义的过滤类型为任意,即/* -->  
  4. ...  
  5. <s:form action="goURL" name="form1">   
  6. ...  
  7. <s:token/>   
  8. <s:reset/><s:submit/>   
  9. </s:form>   

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

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

[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <!DOCTYPE struts PUBLIC   
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"   
  4. "http://struts.apache.org/dtds/struts-2.0.dtd">   
  5. <struts>   
  6. <package name="myGC" extends="struts-default">   
  7. <action name="goURL" class="com.gc.actions.goURLAction" method="execute">   
  8. <interceptor-ref name="defaultStack"/>   
  9. <interceptor-ref name="token"/>   
  10. <result name="success">/success.jsp</result>   
  11. <result name="invalid.token">/inputPage.jsp</result>   
  12. </action>   
  13. </package>   
  14. </struts>   

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

[html] view plaincopy
  1. <package name="myGC" extends="struts-default">   
  2.   <interceptors>   
  3.       <interceptor-stack name="myStack">     
  4.       <interceptor-ref name="token"/>     
  5.       <interceptor-ref name="defaultStack"/>          
  6.       </interceptor-stack>    
  7.   </interceptors>   
  8.   <default-interceptor-ref name="myStack"/>     
  9.   <action name="goURL" class="com.gc.actions.goURLAction">   
  10.     <result name="success">/success.jsp</result>   
  11.     <result name="invalid.token">/inputPage.jsp</result>   
  12.   </action>   
  13. </package>   

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

[html] view plaincopy
  1. <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需要用到,需要注意的是,当没有指定任何拦截器时,默认是隐式启用默认的拦截器的;

0 0
原创粉丝点击