去年开发项目总结的重复提交的问题:如:退回,刷新都造成重复提交的问题;现在把总结的知识点给大家分享下,有什么不足之处多多指教:
一、Struts.xml配置文件
<action name="channel" class="channel">
<interceptor-ref name="token">
<param name="includeMethods">insertChannel(action拦截方法)</param>
</interceptor-ref>
<interceptor-ref name="defaultStack">
<param name="includeMethods">insertChannel</param>
</interceptor-ref>
<result
name="invalid.token">/manage_chuanbo/token.jsp</result>
<action>
<!----注释---->
1.。。。<action name="channel" class="channel">---要拦截的action
<interceptor-ref name="token">---拦截器token
<param name="includeMethods">insertChannel(action(要拦截)方法)</param>
2...<interceptor-ref name="defaultStack">---
<param name="includeMethods">insertChannel(action要拦截方法)</param>
</interceptor-ref>
3... <result
name="invalid.token">/manage_chuanbo/token.jsp</result>---如果是重复提交的时候,跳转token.jsp。对用户进行提示
<!----------说明--------------------->
在jsp页面中要显示错误信息则需要使用到标签:error.jsp:
<s:actionerror/> 这个标签打印出错误信息, 因为token的拦截器生成的信息是action级别的错误
关于提示信息的处理:
struts.messages.invalid.token=The form has already been processed or no token was supplied, please try again.
struts.internal.invalid.token=Form token {0} does not match the session token {1}.
这里似乎要修改.jar中的这两个地方啦……,难道就不能在什么地方覆盖一下么?
d这里生成一个struts-messages_zh.properties并打包到文件struts2-core-2.0.11.2.jar中且位于:
org\apache\struts2\下面,当然我们只需要重点对struts.messages.invalid.token进行相关zh的处理就可以基本满足需要,而struts.internal.invalid.token,似乎只是在控制台输出调试信息使用的。
WARN:
16:06:55,859 WARN [TokenHelper] Form token 68X75K1RDD3M6Q4ZPD0AG6LXBK4HJFSH does not match the session token null.
这个信息的出现主要是我们生成了一个token给form后,我们又重新启动了下服务(清除了session),然后才提交表单引起的
二、Jsp页面配置
<s:token></s:token>
<!--s:token 隐藏域 -->
<!-------标签的实现机制----->
在页面加载时,<s: token />产生一个GUID(Globally Unique Identifier,全局唯一标识符)值的隐藏输入框如:
xml 代码
1 <input type="hidden" name="struts.token.name" value="struts.token"/>
2 <input type="hidden" name="struts.token" value="BXPNNDG6BB11ZXHPI4E106CZ5K7VNMHR"/>
同时,将GUID放到会话(session)中;在执行action之前,“token”拦截器将会话token与请求token比较,如果两者相同,则将会话中的token删除并往下执行,否则向actionErrors加入错误信息。如此一来,如果用户通过某种手段提交了两次相同的请求,两个token就会不同。
<s:token/>标签有个name的属性,可以用来明确指定保存在session中的GUID的名字,如:<s:token name="token"/>,则会把该token以"token"放到session中,可以在action中通过session.getAttribute("token");来取得.如果不指定,默认的名字是struts.token.
<!------token访问action运行机制-------->
Struts在你每次访问Action的时候,都会产生一个令牌,保存在你的Session里面,如果你在Action里的函数里面,使用了saveToken(request);,那么这个令牌也会保存在这个Action所Forward到的jsp所生成的静态页面里。
如果你在你Action的方法里使用了isTokenValid,那么Struts会将你从你的request里面去获取这个令牌值,然后和Session里的令牌值做比较,如果两者相等,就不是重复提交,如果不相等,就是重复提交了。
当然你也可以在你的action所继承的父类里面做表单重复提交的控制,这样就可以不用在所有的子类里来分别再写防止重复提交的代码
三、在action 去掉 extends ActionSupport
配置token(令牌)需要注意的过程