在Struts2中使用token標籤和內置的攔截器,來防止刷新提交和後退提交非常簡單方便。
1. 在需要防止重複提交的jsp中,只需添加一個標籤<s:token />
2. 在對應的struts.xml中進行配置token攔截器,如下代碼,紅色部分
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="cinema" extends="struts-default">
<global-results>
<result name="error">/index.jsp</result>
</global-results>
<action name="cinema" class="cinemaAction">
<result name="saveSuccess" type="redirect-action">cinema!listCinema</result>
<result name="listSuccess">cinema/listCinema.jsp</result>
<result name="deleteSuccess" type="redirect-action">cinema!listCinema</result>
<result name="toUpdate">cinema/updateCinema.jsp</result>
<result name="updateSuccess" type="redirect-action">cinema!listCinema</result>
<result name="toAddSuccess">cinema/addCinema.jsp</result>
<result name="toAddScreen" type="redirect-action">screen!preAddScreen</result>
<result name="invalid.token" type="redirect-action">cinema!listCinema</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="token">
<!-- includeMethods表示包含指定的方法,即對標記爲includeMethods的方法進行攔截 -->
<param name="includeMethods">saveCinema,saveCinemaAndtoAddScreen,updateCinema</param>
<!-- 定義被排除的方法名,也就是你action中不被這個攔截器攔截的方法名 -->
<param name="excludeMethods"></param>
-->
</interceptor-ref>
</action>
</package>
</struts>
以上兩步即完成了使用Struts2 內置過濾器進行防止後退重複提交的方式。
首先要在jsp的from標籤里加入<s:token/>防重複提交標籤,<s:token/>生成如下的內容:(struts.token.name 標識哪個隱藏域存了 token 值)
<input type="hidden" name="struts.token.name"value="struts.token"/>
<input type="hidden" name="struts.token"value="7GXL55LPSGU19SDC9D3VP54I20XT3BVA"/>
注意自定義的表單域別重名了。它的作用是防止表單重複提交,每次加載頁面 struts.token的值都不一樣,如果兩次提交時該值一樣,則認爲是重複提交。此時要啓用 TokenInterceptor(token)攔截器,最好是也啓用 TokenSessionStoreInterceptor(token-session)攔截器,不然後臺會出現錯誤提示:
2008-11-17 20:39:21com.opensymphony.xwork2.interceptor.ParametersInterceptorsetParameters
嚴重: ParametersInterceptor - [setParameters]: Unexpected Exceptioncatched: Error setting expression 'struts.token' with value'[Ljava.lang.String;@1c2e163'
2008-11-17 20:39:21com.opensymphony.xwork2.interceptor.ParametersInterceptorsetParameters
嚴重: ParametersInterceptor - [setParameters]: Unexpected Exceptioncatched: Error setting expression 'struts.token.name' with value'[Ljava.lang.String;@abaf8c'
但不影響使用。不過如果只有 token-session 攔截器卻是不行的。
token 和 token-session 攔截器的啓用,是在 struts.xml 配置文件中,既可以爲包啓用,也可以單獨爲某個action 啓用:
1) 爲包啓用 token 和 token-session
<packagename="TestStruts"extends="struts-default">
<interceptors>
<interceptor-stackname="myStack">
<interceptor-refname="token"/>
<interceptor-refname="token-session"/>
<interceptor-refname="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-refname="myStack"/>
<actionname="Login"class="com.unmi.struts2.action.LoginAction">
<resultname="input">/login.jsp</result>
<resultname="invalid.token">/exception.jsp</result>
</action>
............................................................................
2) 爲 Action 啓用 token 和 token-session
<actionname="Login"class="com.unmi.struts2.action.LoginAction">
<interceptor-refname="token"/>
<interceptor-refname="token-session"/>
<interceptor-refname="defaultStack"/>
<resultname="input">/login.jsp</result>
<resultname="invalid.token">/exception.jsp</result>
</action>
............................................................................
注意 token、token-session 和 defaultStack 的順序要保證,還需要加上名爲"invalid.token" 的 result,當發現重複提交時轉向到這個邏輯頁,如 /exception.jsp,在/exception.jsp 加上 <s:actionerror />在出現重複提交時就會提示:Theform has already been processed or no token was supplied, pleasetry again.
<interceptor-ref name="token"/><interceptor-ref name="token-session"/><!--注意struts2.0 攔截器名字爲token-session struts2.1.2 已經更改爲tokenSession-->
token: 在活動中檢查合法令牌(token), 防止表單的重複提交;
token-session: 同上,但是在接到非法令牌時將提交的數據保存在session中;