`

Struts中防止表单提交

 
阅读更多

首先是web.xml文件

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<welcome-file-list>
		<welcome-file>testToken.jsp</welcome-file>
	</welcome-file-list>
</web-app>

 然后是用于输入用户名和密码以测试重复提交表单的testToken.jsp页面

 

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<h2>测试表单重复提交</h2>

<s:actionerror/>

<s:form action="testToken" theme="simple">
	<s:token name="hello"/>
	姓名:<s:textfield name="username"/><br/>
	密码:<s:password name="password"/><br/>
	<s:submit value="提交"/>
</s:form>

<%--
==========================================================================================
【表单重复提交】
只需在<s:form/>中添加<s:token/>即可
然后运行项目,打开该页面右键查看源文件发现<s:token/>转化成了如下代码
<input type="hidden" name="struts.token.name" value="struts.token" />
<input type="hidden" name="struts.token" value="KF98D738ZRY8TNVQWJL3GYSB8LO5U748" />
其中struts.token.name是永远固定的,第一个hidden的value值与第二个hidden的name值是关联在一起的
第二个hidden的value值是一个32位的随机的被加密过的字符串,由大写A到Z加上数字0到9组成
另外,如果页面中写成<s:token name="hello"/>的话,那么再运行项目,查看该页面的源代码后发现
此时的第一个hidden的value值与第二个hidden的name值都已经变成了hello了
==========================================================================================
【通过<s:token name="hello"/>举例说明】
<input type="hidden" name="struts.token.name" value="hello"/>
<input type="hidden" name="hello" value="HUZU1PLOZ2111AAN5XN48I5914IUM668"/>
由于<s:token/>是个标签,所以必然存在相应的标签库的代码文件
当服务器端解析到页面中的<s:token/>标签的位置时,该标签对应的类文件就会自动生成两个hidden
第二个hidden的value属性对应的是Struts2产生的一个GUID值(Globally Unique Identifier全局唯一标识符)
这个GUID是一个类似于HUZU1PLOZ2111AAN5XN48I5914IUM668的字符串
然后Struts2会将HUZU1PLOZ2111AAN5XN48I5914IUM668放到HttpSession中,然后使用hello来标识它
由于<s:token name="hello"/>是放在了表单里面,所以当我们提交表单的时候
就会把两个hidden全部发送到服务器上,然后名为token的表单重复提交的拦截器就会截获struts.token.name
如果截获到struts.token.name的话,就读取它的value值hello
接着再以hello为name来读取HUZU1PLOZ2111AAN5XN48I5914IUM668
然后就把HUZU1PLOZ2111AAN5XN48I5914IUM668值与已经放在HttpSession中的值进行比较
如果两个值是一样的话,它就认为该表单是第一次提交,接着程序就正常执行
如果第一次提交完毕之后,再去刷新页面或者进行第二次提交的话,仍然会发送一个被加密过的字符串
当第一次提交成功之后,Struts2会将session里面的加密字符串删掉,也就是说session里面就不存在这个值了
既然不存在这个值,那么客户端再发过来一个加密字符串的话。二者一比较,不一样,于是就认为这是第二次提交
这样的话,就可以有效的对提交请求进行拦截。这个功能是通过拦截器来实现的
这里用到的token拦截器,对应org.apache.struts2.interceptor.TokenInterceptor类
它继承了MethodFilterInterceptor拦截器。另外token并没有配置在defaultStack拦截器里
我们可以发现Struts2采用的防止表单重复提交的方式与Struts1是一模一样的,原理上没有任何改变
但在使用方式上却简化又简化,不像Struts1那样还要写代码。显然比Struts1采用的token方式简洁得多得多
==========================================================================================
【重复提交表单时的提示信息的国际化】
表单重复提交时的报错信息是存放在ActionError中的。在前台页面对错误信息进行输出结果如下所示
The form has already been processed or no token was supplied, please try again. 
在org.apache.struts2.struts-message.properties中查找到了该信息对应的key
然后我们就可以设置国际化信息,以输出中文提示
==========================================================================================
【tokenSession拦截器】
使用token拦截器的做法在论坛中用得比较多,不过也有一些商务网站使用的是tokenSession拦截器
商务网站通常会给用户一个提交成功的提示,而不管用户刷新多少次页面,它都会一直显示给用户提交成功的提示
只不过这个成功提交可能会让用户产生误解罢了。事实上也仅仅提交成功了一次,后面的刷新操作都被忽略掉了
这个功能就是由tokenSession拦截器实现的,使用这个拦截器不需要我们配置任何result,它返回的永远是成功页面
也就是说,使用tokenSession拦截器时,前台不用做任何改变,还是在表单里面放置一个<s:token/>标签
然后在struts.xml中写成<interceptor-ref name="tokenSession"/>即可
如果发现用户重复提交表单数据的话,由于tokenSession拦截器的作用,它会返回result为success的页面
我们也可以在Action的方法中打印输出一句话来测试是否仅仅第一次的提交被成功执行了
经过测试得知,无论用户在客户端刷新几百遍几千遍,最后只有第一次的提交操作被执行了
事实上后面的刷新的提交操作都被tokenSession拦截器给拦截了
因为它发现客户端的session与服务器上的session不一样,于是就把后面的请求给拦截了
==========================================================================================
--%>

 然后是当用户名和密码正确时显示的result.jsp页面

 

<%@ page pageEncoding="UTF-8"%>
<h2>Login Success</h2>

 然后是Struts2的配置文件struts.xml

 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
						"http://struts.apache.org/dtds/struts-2.1.dtd">

<struts>
	<package name="struts2.1" extends="struts-default">
		<action name="testToken" class="com.jadyer.action.LoginAction" method="testToken">
			<result>/result.jsp</result>
			<result name="invalid.token">/testToken.jsp</result>
			<interceptor-ref name="token"/>
			<interceptor-ref name="defaultStack"/>
		</action>
		<!-- 当Struts2发现用户进行表单重复提交时,它会寻找invalid.token -->
		<!-- 并根据invalid.token找到与之对应的页面。所以记得要配置invalid.token结果 -->
	</package>
</struts>

 最后是处理所输入的用户名和密码的LoginAction.java

 

package com.jadyer.action;

import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings("serial")
public class LoginAction extends ActionSupport {
	public String testToken() throws Exception {
		return SUCCESS;
	}
}

 

 

分享到:
评论

相关推荐

    struts2 防止表单重复提交的例子

    Struts2框架提供了一种解决方案,即使用Token机制来防止表单的重复提交。以下是对这个主题的详细说明: 1. **表单重复提交问题**:当用户在提交表单时,由于网络延迟或用户误操作,可能会导致同一个表单被多次提交...

    Struts2防止重复提交解决方案

    在Struts2中,防止重复提交是一个重要的问题,因为它可能导致数据不一致性和服务器资源的浪费。本文将详细介绍如何在Struts2中解决这个问题,以及相关的技术概念。 首先,我们要理解Struts2中的拦截器(Interceptor...

    struts2防止表单重复提交--重定向

    下面将详细解释Struts2如何通过重定向来防止表单重复提交。 首先,理解表单重复提交的场景:用户在提交表单后,由于网络延迟或其他原因,可能会无意中多次点击提交按钮。如果服务器没有处理这些重复请求,那么相同...

    struts2利用token防止表单重复提交(源代码)

    struts2防止表单重复提交,利用struts的拦截器tokenSession,轻轻松松解决表单重复提交的问题。 附件为源代码,后台延迟了3秒,可直接在web服务器下部署运行,输入用户名和密码后,多点几次提交按钮,然后看控制台...

    Struts2防止表单重复提交示例

    在Struts2中防止表单重复提交的过程主要包括以下几个步骤: 1. **生成Token**:当用户发起表单请求时,服务器会生成一个唯一的Token并将其存储在服务器的会话(Session)中,同时将这个Token作为隐藏字段放入到HTML...

    Struts2解决表单重复提交

    在配置示例代码中,开发者需要在login.jsp页面中加入&lt;s:token&gt;&lt;/s:token&gt;标签,并确保表单提交到对应的Action,如LoginAction。在Struts2的配置文件struts.xml中,需要配置action,并引用token拦截器和defaultStack...

    【原创】Struts2防止表单重复提交.doc

    本文详细介绍了如何在Struts2框架中使用`&lt;s:token/&gt;`标签和`token`拦截器来防止表单重复提交。通过这种方式,可以有效地避免因重复提交而导致的数据冗余和其他潜在问题。对于开发者来说,理解和掌握这些技术是非常...

    防止表单重复提交

    在Web开发中,表单提交是一项基础且关键的操作,它允许用户向服务器发送数据进行处理。然而,如果没有适当处理,可能会出现表单重复提交的问题,这可能导致数据的不一致性和服务器资源的浪费。本篇文章将深入探讨...

    struts2防止重复提交

    Struts2提供了几种策略来防止表单的重复提交,确保请求的唯一性和事务的一致性。 一、令牌(Token)机制 Struts2的Token插件是防止重复提交的一种常见方法。这里的"Strut2Token"很可能是指这个插件的应用。它的...

    Struts2防止重复提交的解决方案

    在Web应用程序开发中,一个常见的问题是如何有效地防止表单的重复提交。这不仅能够提高用户体验,还能增强系统的安全性。Struts2作为一款广泛使用的Java Web应用框架,提供了多种方式来解决这一问题。 #### 二、...

    Struts2 表单 重复提交

    "防止表单重复提交 token"是Struts2提供的一种解决方案,通过在请求中加入一个唯一的token来确保请求的唯一性和一致性。 首先,我们来看如何实现这个机制。在Struts2中,我们可以使用拦截器(Interceptor)来实现...

    struts数据回显、模型驱动、防止表单重复提交

    本主题将深入探讨Struts框架中的数据回显、模型驱动以及如何防止表单重复提交,这些都是在实际开发中非常关键且实用的技术点。 1. 数据回显: 数据回显是指在用户提交表单后,服务器端处理数据并返回结果页面时,将...

    struts token 防止页面刷新,重复提交

    在Web应用开发过程中,特别是在使用MVC框架如Apache Struts进行开发时,防止表单重复提交是一个重要的安全措施。表单重复提交通常发生在用户点击“提交”按钮后,由于网络延迟或其他原因没有及时收到反馈,导致用户...

    Struts表单重复提交问题

    通过这样的令牌机制,Struts能够有效地防止表单的重复提交,确保每次提交都是唯一的。这有助于维护数据的一致性和完整性,避免因用户误操作或网络问题导致的数据冗余。在实际开发中,除了Struts的令牌机制,还可以...

    Struts之Token解决表单那重复提交

    在处理用户交互时,尤其是表单提交,一个常见的问题是防止表单的重复提交。这可能导致数据的不一致性和其他问题。本文将深入探讨如何在Struts框架中利用Token机制来解决这个问题。 一、表单重复提交问题 表单重复...

    struts2中防止重复提交的方法

    - **客户端验证**:在客户端使用 JavaScript 或 jQuery 等库来检测表单提交,一旦提交成功,就禁用提交按钮,防止用户再次点击。 - **服务端状态管理**:服务器端记录每个请求的状态,例如在数据库中设置一个临时...

    struts2中token限制表单多次提交

    Struts2提供了Token插件来解决这个问题,确保每个表单提交只能被执行一次。下面将详细阐述Struts2中Token机制的工作原理、配置以及使用方法。 1. Token机制概述: Token机制是通过在客户端(浏览器)和服务器之间...

Global site tag (gtag.js) - Google Analytics