struts2的令牌,可以用来防止重复提交,其原理是在提交jsp页面中,写入一个隐藏域name="token",然后在action中定义一个变量token并get、set。在服务器端避免表单重复提交,通常是采用同步令牌的方式实现,其基本原理是:

(1)用户访问包含表单的页面,服务器端在这次会话中,创建一个Session对象,并产生一个令牌值,将这个令牌值作为隐藏输入域(<input>元素的type属性为hidden)的值,随表单一起发送到客户端,同时将令牌值保存到Session中。

(2)用户提交页面,服务器端首先判断请求参数中的令牌值和Session中保存的令牌值是否相等,如果相等,则清除Session中的令牌值,然后执行数据处理操作。如果不相等,则提示用户已经提交过了表单,同时产生一个新的令牌值,保存到Session中。当用户重新访问提交数据页面中,将新产生的令牌值作为隐藏输入域的值。

假定提交前该令牌号为LY7DPVNMJ872N6EOJ1OTO8URRON7P0NX,如果保存后返回到jsp页面令牌号会重新生成并保存到session中。那么你通过刷新或后退再次保存,提交到后台的令牌号依然是上次的LY7DPVNMJ872N6EOJ1OTO8URRON7P0NX。这样,这次保存提交的号与session中的号就不一样了。那么系统就可以判断出你是重复提交,然后跳转到相应的提示页面!

下面是java代码:

  1. import com.opensymphony.xwork2.ActionSupport;
  2. public class Test extends ActionSupport {
  3. private String token;  //令牌
  4. public String getToken() {
          return token;
       }
      public void setToken(String token) {
         this.token = token;
      }
  5. 。。
  6. 。。
  7. 。。
  8. }

package com.test;

import com.opensymphony.xwork2.ActionSupport;

public class Test extends ActionSupport {
/**
*
*/
private static final long serialVersionUID = 8650051575559688141L;
private String message;
public String execute(){
System.out.println(message);
return SUCCESS;
}
public String save(){
return "ok";
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}

}

struts.xml文件代码:

  1. <!DOCTYPE struts PUBLIC
  2. "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
  3. "http://struts.apache.org/dtds/struts-2.0.dtd">
  4. <struts>
  1. <!-- action 设置-->
  2. <package name="test" extends="struts-default" namespace="/testToken">
  3. <action name="test" class="com.test.Test">
  4. <result name="invalid.token">/error.jsp</result> <!当重复提交时,转到error.jsp页面>
  5. <result>/test.jsp</result>
  6. <interceptor-ref name="defaultStack" />
  7. <interceptor-ref name="token" />
  8. </action>
  9. </package>
  10. </struts>

<?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>
<!-- 指定Web应用的默认编码集,相当于调用HttpServletRequest的setCharacterEncoding方法 -->
<constant name="struts.i18n.encoding" value="UTF-8" />
<!--
该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。
如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。
-->
<constant name="struts.action.extension" value="do" />
<!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 -->
<constant name="struts.serve.static.browserCache" value="false" />
<!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 -->
<constant name="struts.configuration.xml.reload" value="true" />
<!-- 开发模式下使用,这样可以打印出更详细的错误信息 -->
<constant name="struts.devMode" value="true" />
<!-- 默认的视图主题 -->
<constant name="struts.ui.theme" value="simple" />

<!-- action 设置-->
<package name="test" extends="struts-default" namespace="/testToken">
<action name="test" class="com.test.Test">
<result name="invalid.token">/error.jsp</result> <!--当重复提交时,转到error.jsp页面-->
<result>/test.jsp</result>

<interceptor-ref name="defaultStack" />
<interceptor-ref name="token" />

</action>
</package>

</struts>

test.jsp代码

  1. pageEncoding="utf-8"%>
  2. <%@ taglib prefix="s" uri="/struts-tags"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  4. <html xmlns="http://www.w3.org/1999/xhtml">
  5. <head>
  6. <title>struts2 test token</title>
  7. <s:head />
  8. </head>
  9. <body>
  10. <s:actionerror/>
  11. <s:form action="test" namespace="/testToken">
  12. <s:textfield name="message" label="请输入您的信息"/>
  13. <s:token name="token"/>
  14. <s:submit value="确定" />
  15. </s:form>
  16. </body>
  17. </html>

<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>struts2 test token</title>
<s:head />
</head>
<body>
<s:actionerror/>
<s:form action="test" namespace="/testToken">
<s:textfield name="message" label="请输入您的信息"/>
<s:token name="token"/>
<s:submit value="确定" />
</s:form>

</body>
</html>

error.jsp代码

  1. <%@ taglib prefix="s" uri="/struts-tags" %>
  2. <html>
  3. <body>
  4. <s:actionerror/>
  5. 不能重复提交表单!
  6. </body>
  7. </html>
04-07 15:52
查看更多