防止表单重复提交主要用的到标签是<s: token />,拦截器 <interceptor-refname="token"/>,还有一个默认的返回值<resultname="invalid.token">/input.jsp</result>
在页面加载时,<s: token />产生一个GUID(Globally Unique Identifier,全局唯一标识符)值的隐藏输入框如:
<input type="hidden" name="struts.token.name" value="struts.token"/>
<input type="hidden" name="struts.token" value="BXPNNDG6BB11ZXHPI4E106CZ5K7VNMHR"/>
同时,将GUID放到会话(session)中;在执行action之前,“token”拦截器将会话token与请求token比较,如果两者相同,则将会话中的token删除并往下执行,否则向actionErrors加入错误信息。如此一来,如果用户通过某种手段提交了两次相同的请求,两个token就会不同。
以下为action代码
package com.ljq.action; import java.util.ArrayList; import java.util.List; public class PersonAction { private String name; @SuppressWarnings( " unchecked " ) // 观看控制台 // 如果token生效则不会在控制台输出name的值,而会输出如下警告: 2011-3-14 20:45:32 com.opensymphony.xwork2.util.logging.commons.CommonsLogger // warn 警告: Form token EDZ4S96RNDN5VD8B1CQTK6FTHIJUPC66 does not match the session token null. public String execute() { List ls = new ArrayList(); ls.add(name); for ( int i = 0 ; i < ls.size(); i ++ ) { System.out.println(ls.get(i)); } return " success " ; } public String getName() { return name; } public void setName(String name) { this .name = name; } }
再看看JSP的写法
<% @ page language = " java " import = " java.util.* " pageEncoding = " UTF-8 " %> <% @ taglib uri = " /struts-tags " prefix = " s " %> <! DOCTYPE HTML PUBLIC " -//W3C//DTD HTML 4.01 Transitional//EN " > < html > < head > < title > 防止表单重复提交 </ title > < meta http - equiv = " pragma " content = " no-cache " > < meta http - equiv = " cache-control " content = " no-cache " > < meta http - equiv = " expires " content = " 0 " > </ head > < body > <!-- 防止表单重复提交,记得在form表单里填上 < s:token ></ s:token > --> <!-- action = " token " 、action = " tokenSession " --> < s:form action = " token " namespace = " /test " method = " post " ><s:token></s:token>姓名: < s:textfield name = " name " />< s:token ></ s:token > < input type = " submit " value = " 发送 " /> </ s:form > </ body > </ html >
下面是struts2的配置文件
<?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> <!-- 默认的视图主题 --> <constant name="struts.ui.theme" value="simple" /> <!-- struts2在防止表单重复提交的拦截中有2个,分别是:token,tokenSession。tokenSession继承token而来。 通常情况下,使用tokenSession客户端感觉会比较友好。 --> <!-- 如果重复提交,会跳转到error.jsp页面 --> <package name="person" namespace="/test" extends="struts-default"> <action name="token" class="com.ljq.action.PersonAction"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="token" /> <!-- 如果重复提交,跳转到error.jsp页面 --> <result name="invalid.token">/WEB-INF/page/error.jsp</result> <result>/WEB-INF/page/message.jsp</result> </action> <action name="tokenSession" class="com.ljq.action.PersonAction"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="tokenSession" /> <!-- 如果重复提交,不会跳转到error.jsp页面 --> <result name="invalid.token">/WEB-INF/page/error.jsp</result> <result>/WEB-INF/page/message.jsp</result> </action> </package>
以上XML片段值注意的是加入了“token”拦截器和“invalid.token”结果,因为“token”拦截器在会话token与请求token不一致时,将会直接返回“invalid.token”结果。