struts2 防止重复提交的解决方案

首先说说重复提交是怎么产生的,一般情况下有两种方式:

1,页面提交后再次刷新页面。

2,在提交的时候多次点击提交按钮。

strut1.x中解决防止提交1的方法是通过重定向解决,但是方式2在网速很慢或者是用户快速的点击提交按钮时,还是能够重复提交数据。

struts2中为方式2提供了解决方案(方式1用重定向是也可以防止用户刷新页面而引起的重复提交),struts2通过使用令牌(token)解决此类的问题。

要使用token,首先在页面上在你要提交的表单中加上<s:token/>,次标签解析后会生成两个隐藏域:

<input type ="hidden" name ="struts.token.name" value ="struts.token" />
<input type ="hidden" name ="struts.token" value ="LVYMI4CX9YBDS9A0AAF9UAJL8UDX1N05 " />
在该标签执行完成后会生成一个随机的值(红色部分),该值同时会加入到session中。
 其次,就是在你个struts.xml中加入token拦截器。
<package name="token-struts" extends="struts-default">
<interceptors>
<interceptor name="token"/>
<interceptor-stack name="token-default">
<interceptor-ref name=" token "/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="token-default"/> 
</package>
如果是用注解的话,那么的action要这么定义:@ParentPackage("token-struts")。
如果不是注解,可以将上面的拦截器栈加入到你的actin定义中。
这样就完成了整个防止重复提交的任务了。
如果你想了解此拦截器是这么工作的,你可以打开源码看看,其中TokenHelper.validToken()最是关键,就是通过这个帮助类完成对令牌的判断。

上述是可以解决重复提交的问题,但是随之而来的又是一个麻烦。
拦截器顾名思义就是用来对请求进行拦截的,一个请求在执行前就被拦截了,默认情况下拦截器会拦截被配置下所有的请求。但是很多情况下该配置下的其他请求不需要这个拦截,比如删除,更新操作。就完成不需要这个拦截器去拦截。拦截器又不能区分不同的请求而做出不同的操作。

这种情况就有两种解决方案:
第一,不用token拦截器,只在你需要防止重复提交的action处理方法中加入 TokenHelper.validToken()这个判断,如果为返回true就执行,否则跳过。
第二,用token拦截器,但是重写此拦截器TokenInterceptor。在重写的拦截器中判断tokenNames,如果值为空则不做任何操作,如果有值则做拦截。

猜你喜欢

转载自helloklzs.iteye.com/blog/1195269