使用token标签的时候,Struts2会建立一个GUID(全局唯一的字符串)放在session中,并且会成为一个hidden放在form中。
token拦截器会判断客户端form提交的token和session中保存的session是否equals。如果equals则执行Action。否则拦截器直接返回invaid.token结果,Action对应的方法也不会执行
struts.xml中配置
<action name="userRegister" class="UserRegisterAction"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="token" /> <result name="invalid.token"> /jsp/service/power/login.jsp </result> <result name="success"> /jsp/service/power/login.jsp </result> <result name="fail"> /jsp/service/user/userRegister.jsp </result> </action>
使用<s:token>得到控制台提示信息:"Could not find token name in params“,后来发现原来是把<s:token>标签放在了<form>标签外面,导致出现以上问题。
<s:token>标签使用很简单,用以避免表单的重复提交,其原理是用户访问页面时,服务器产生一个令牌值一起发送给客户端。当这个页面被提交时,比较客户端和已经保存先前的令牌值,如果相等则清除令牌值,不相等表明表单已被提交,同时产生一个新令牌值,保存到session中。
step 1:在<form>标签里面定义标签<s:token/>
step 2:在struts.xml文件内配置token拦截器
<interceptor-ref name="token">
<param name="excludeMethods">....</param> //这里可以配置token拦截器的排队方法
</interceptor-ref>
<result name=“invaild.token">/***.jsp</result>
step 3:可在页面中添加<s:actionerror>显示重复提交信息
step 4:测试。提交页面后,单击刷新,就自动转到***.jsp
token 是在上一个action的执行方法后 会产生一个新的token放在session中 key 为“struts.token” <s:token></s:token> 现实再页面的时候会生成俩个隐藏标签 一个叫struts.token.name 一个叫做是你struts.token.name 值作为name的隐藏标签,
提交到后台进行token 比对 不一样返回invaild.token
注:
1. 当使用token拦截器时,必须设置invalid.token的result,而使用tokenSession时,则不需要。
2. 使用token拦截器时,必须使用<s:token>标签,而且该标签必须包含在Form中。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
我在使用struts2 token的过程中,遇到了一个问题,用了很长时间才解决,特记录一下。
使用struts2 的 token,我的form表单不能实例化,为null ,
有个论坛上说的是使用<s:form>表单,修改后没有任何变化。
最后在http://hi.baidu.com/miatrzofgvcgjor/item/29d6ae07b93771c72e4c6b80上找到了解决方案。
如何使用struts2拦截器,或者自定义拦截器。特别注意,在使用拦截器的时候,在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈defaultStack,如下(这里我是引用了struts2自带的checkbox拦截器):
<interceptor-ref name="checkbox">
<param name="uncheckedValue">0</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
(必须加,否则出错)
我的Action配置如下,
<action name="lossRateAction!*"
class="com.oarage.lossanalyse.exchange.action.LossRateAction"
method="{1}">
<interceptor-ref name="token">
<param name="includeMethods">addLossRate</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
<result name="list">
/framepages/lossRate/LossRateList.jsp
</result>
<result name="initAddLossRate">
/framepages/lossRate/LossRateAdd.jsp
</result>
<result name="initUpdateLossRate">
/framepages/lossRate/LossRateUpdate.jsp
</result>
</action>
这样就可以正常使用了。记住,一定要添加上默认的拦截器。