防止表单重复提交主要用的到标签是<s: token />,拦截器 <interceptor-ref name="token" />,
还有一个默认的返回值<result name="invalid.token">/xxxx.jsp</result>
在页面加载时,此标签解析后会生成两个隐藏域:
<input type="hidden" name="struts.token.name"value="struts.token" />
<input type="hidden" name="struts.token"value="126456U743S2852V2288NIUJPG10XQ20" />
基本原理:用户访问做了重复提交的页面,服务器会生成一个令牌,这个令牌一方面以隐藏字段的方式存于页面上。另一方面保存与session中,当用户第一次提交信息时,服务端会拿页面上得同session里的作对比,相同则通过,并清空session中的值。
这样,当第二次提交该页面时,页面上得值与session中的就不一样了,这样便会返回input,提示重复提交了。
Struts 2标签中的token标签,可以用来生成一个独一无二的标记。这个标记必须嵌套在form标签中使用,它会在表单里插入一个隐藏字段并把标记保存到HttpSession对象里。toke标签必须与Token或Token Session拦截器配合使用,两个拦截器都能对token标签进行处理。Token拦截器遇到重复提交表单的情况,会返回一个"invalid.token"结果并加上一个动作级别的错误。TokenSession拦截器扩展了Token拦截器并提供了一种更复杂的服务,它采取的做法与Token拦截器不同,它只是阻断了后续的提交,这样用户不提交多少次,就好像只是提交了一次。
实例代码
jsp
<form name="ctl00" method="post" action="/dang/order/confirmOrder.action"id="ctl00">
<s:token/> --- 防止重复提交Struts标签
………
</form>
strut.xml
<package name="dang-order"namespace="/order"extends="dang-default">
…
<action name="confirmOrder" class="org.tarena.dang.action.order.ConfirmOrderListAction">
<interceptor-refname="tokenSession"></interceptor-ref>
<interceptor-refname="defaultStack"></interceptor-ref>
<result name="success">/order/order_ok.jsp</result>
<result name="invalid.token">/main/main.jsp</result>
</action>
…
</package>
说明:name="tokenSession"如果出现二次提交不会跳转到/main/main.jsp页面, f返回的页面任然是/order/order_ok.jsp这样无论用户提交多少次就好像提交一次,提高用户体验度
若改为name="token" 则会跳转,第一种会Action代码
Action业务代码不需要更改,此处略
相关Struts2的内置拦截器:
<interceptor name="token"class="org.apache.struts2.interceptor.TokenInterceptor"/>
<interceptorname="tokenSession"
class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
token:
这个拦截器主要 用于阻止重复提交,它检查传到Action中的token,从而防止多次提交。tokenSession:
这个拦截器的作用与前一个基本类似,只是它把token保存在HttpSession中。