Struts 的 Token (令牌)机制能够很好的解决表单重复提交的问题,基本原理是:服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配。在处理完该请求后,且在答复发送给 客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次提交的 话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。
个人理解:用户在请求包含 token 标签的页面, struts 会计算出一个令牌值,并把它添加进 session ,同时把令牌值赋给 jsp 页面的隐藏域 struts.token, 当用户提交表单后,将请求包含的令牌值与 session 的令牌值比较,看是否匹配!同时产生新的令牌值,新令牌值覆盖 session 中的旧令牌值,如果用户回退到提交页面再提交,则 struts.token 的值与 session 中令牌值将不同,返回 invalid.token 结果。
用法:
第一步:在表单中加入 <s:token/> 标签
如:
<s:form action="test"> <s:textfield name="field"></s:textfield> <s:token/> <!-- 添加token --> <s:submit/> </s:form>
转换成的网页源码 如下:
<form id="test" name="test" action="test" method="post"> <input type="text" name="field" value="" id="test_field"/> <input type="hidden" name="struts.token.name" value="struts.token" /> <input type="hidden" name="struts.token" value="NIZV18PR9HIRA3UARD0HWXHRRK4NMIQL" /> <input type="submit" id="test_0" value="Submit"/> </form>
第二步:在相应的 action 中添加拦截器和 invalid.token 视图
<action name="test" class="test.showAction"> <interceptor-ref name="defaultStack"></interceptor-ref> ① <interceptor-ref name="token"></interceptor-ref> ② <result name="success">/show.jsp</result> <result name="invalid.token">/index.jsp</result> ③ </action>
扫描二维码关注公众号,回复:
1237266 查看本文章
①. Struts 默认拦截器
②.阻止表单重复提交的拦截器
③.重复提交后的跳转视图
注意: struts 一旦额外添加其他拦截器后,就不会调用默认拦截器,即①,因此要额外添加默认拦截器,否则默认拦截器提供的一些功能就无法使用
第三步: invaid.token 页面打印错误信息,一样可以使用 struts 标签。如下:
<s:actionerror/>