`
Luob.
  • 浏览: 1584257 次
  • 来自: 上海
社区版块
存档分类
最新评论

Struts2 阻止表单重复 和 等待页面(四十四)

 
阅读更多
表单重复提交现象

导致表单重复提交的现象可以分为一下两种情况:
1.多次单击提交按钮
   对响应来不及。用户没有看到提交后的结果,导致用户频繁多次的点击提交按钮。
2.执行刷新操作
   对响应及时,也有可能出现表单重复提交现象。服务器段的程序在处理哟过户提交哦啊的信息后,调用RewuestDispatcher.forward()方法,将哟过户请求导向成功的页面,用户看到成功信息后,对成功页面执行花心操作,这是浏览器将再次提交用户先前输入的信息。


同步令牌的基本原理
在服务器端避免表单重复提交,通常采用同步令牌的方式来实现。同步令牌的基表原理如下:
1:服务器端在处理客户端请求时,创建一个Session对象和一个令牌(例如 token1)。然后 将token1作为影藏域随处理结果一起发送到客户端,同事将token1保存到session中
2.服务器端在处理到达的请求之前,将请求中的token1与保存在当前用户session中的值进行比较,肩擦这两个值是否匹配。
3.如果相等。表示用户是第一次提交表单,则清楚session中的token1,然后执行数据处理操作,同时产生一个新的令牌值(例如 token2) 然后保存到session中,当用户重新访问提交数据页面时,将新产生的token2做为表单影藏域的值。
4.如果用户重复提交,客户端传递过来的令牌值是token1,而服务器端的令牌为token2,这两个令牌的值不等,于是不在对用户的请求进行提交,从而有效防止表单重复提交发生。


Struts2 的实现方式
 Struts2框架提了token标签,使用该标签,需要指定一个令牌的名字,例如:<s:token name="user.token"/> token标签将创建一个新的令牌值,并根据指定的令牌名称将令牌值保存到session中。
token标签最终将会在表单中生成两个影藏字段。请求包含token标签的表单文件后,在运行页面的源文件中可以看到如下形式的代码:
  <input type="hidden" name="struts.token.name" value="user.token"/>
  <input type="hidden" name="user.token" value="5J6RS8NCMZSQBH7NZDX8XRG435O2XAP"/>
第一个隐藏字段的名字是struts.token.name 是固定的,第二个影藏字段的名称是user.token 它的value的值是令牌值。
服务器首先根据stuts.token.name 找到保存令牌的请求参数名,user.token 然后获取user.token请求参数得到令牌值。

token标签必须与token,tokenSession或者 execAndWait等拦截器配合使用,这3个拦截器都能对token标签进行处理
 上述3个拦截器的实现类分别为了TokenInterceprot,TokenSessionStoreInterceptor 和ExecuteAndWaitInterceptor,他们已经在Struts-default.xml文件中定义,但是没有包含在defaultStack拦截器栈中。


----使用 token 拦截器---


import com.opensymphony.xwork2.ActionSupport;

public class LoginAction extends ActionSupport{

	private String userName;
	private String userPassword;
	
	@Override
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		return  SUCCESS;
	}
// get set
}

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

<struts> 
	<!-- 如果 注解的action配置改变时候不需要重新启动tomcate -->
	<constant name="struts.devMode" value="true"/>  
    <constant name="struts.convention.classes.reload" value="true" /> 
	
	<package name="default" extends="struts-default">
		<action name="login" class="com.sh.action.LoginAction">
			<interceptor-ref name="defaultStack"/>
			<interceptor-ref name="token"/>
			<result name="invalid.token">/login.jsp</result>
			<result name="input">/login.jsp</result>
			<result name="success">/index.jsp</result>
		</action>
		
	</package>
    
</struts>


login.jsp
 <body>
   <STRONG>用户登录</STRONG>
   <s:form action="login">
   		<s:token/>
   		<s:actionerror/>
   		<s:textfield name="userName" label="姓名"/>
   		<s:textfield name="userPassword" label="密码"/>
   		<s:submit value="登录"/>
   </s:form>
  </body>

index.jsp
 <body>
    	<h4>用户登录成功</h4>
    	登录名称:${userName}
  </body>


----使用 tokenSession 拦截器---
   tokenSession拦截器扩展了token拦截器,但是tokenSession拦截器不会返回一个特殊的结果,也不会添加一个动作错误,只是阻断后面的提交,这样做的结果就是用户将看到你同样的响应,就好像只有一次提交。
   如果使用浏览器的后退功能,退回到登录页面,即使使用其他名称登录,提交表单后仍然显示原来扽牢固的名称。也就是说tokenSession拦截器只承认第一次提交。

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

<struts> 
	<!-- 如果 注解的action配置改变时候不需要重新启动tomcate -->
	<constant name="struts.devMode" value="true"/>  
    <constant name="struts.convention.classes.reload" value="true" /> 
	
	<package name="default" extends="struts-default">
		<action name="login" class="com.sh.action.LoginAction">
			<interceptor-ref name="defaultStack"/>
			<interceptor-ref name="tokenSession"/>
			<!-- 如果使用 token 下面的就有这样的一个返回值
			<result name="invalid.token">/login.jsp</result> -->
			<result name="input">/login.jsp</result>
			<result name="success">/index.jsp</result>
		</action>
		
	</package>
    
</struts>


---使用 ExecAndWait拦截器
    在 web应用中,往往会遇到需要执行很长时间的页面,例如上传一个很大的文件,服务器接受请求后,需要处理批量的数据。这种情况下,如果没有任何设置,那么在服务器处理的这个过程中。浏览器将呈现一片空白,这时用户不知道程序 有没有执行,很可能刷新该页面,甚至执行关闭页面的操作,因此,在等待处理的过程中,设置一个友好的信息提示页面是很有必要的。

使用execAndWait拦截器实现自动显示等待页面的具体过程如下:
(1) 当表单提交请求到来时。execAndWait拦截器将创建一个新的线程来执行Action,然后返回一个等待页面给用户,然用户只懂啊请求正在处理中。
(2) 等待页面将包含自动刷新功能,每隔几秒就通知浏览器,向初始请求的URL再次发送请求
(3) execAndWait拦截器再次截获请求,判断Action是否执行完毕,如果仍未执行完毕,则继续向用户返回等待页面;如果已经执行完毕,则向用户返回相应的执行成功页面。

execAndWait拦截器包含一下3个参数:

threadPriority:可选参数,用来指定线程的优先级。默认值为Thread.NORM_PRIORITY.

delay:可选参数,用来显示等待页面前初始的等待延迟时间,以毫秒为单位,默认情况下,没有等待延迟。

delaySleepInterval:可选参数,只能和delay参数一起使用,用来指定检查后进程是否执行完毕的时间间隔,以毫秒为单位,默认值为100毫秒。

初始等待延迟:就是可以让服务器在显示等待页面之前延迟一段时间,单位是毫秒。
在初始等待延迟时间里,execAndWait拦截器每隔100毫秒检查后台Action的执行情况,如果 Action对请求的处理,并不需要很长的时间,则等待页面不会被显示,如果Action需要较长的执行时间,则将等待页面返回给用户。

action.java  login.jsp index.jsp 和上面的一样
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts> 
	<!-- 如果 注解的action配置改变时候不需要重新启动tomcate -->
	<constant name="struts.devMode" value="true"/>  
    <constant name="struts.convention.classes.reload" value="true" /> 
	
	<package name="default" extends="struts-default">
		<action name="login" class="com.sh.action.LoginAction">
			<interceptor-ref name="defaultStack"/>
			
			<interceptor-ref name="execAndWait">
				<!-- 设置服务器处理请求的时间 ,如果超过这个时间 将显示等待页面 wait.jsp -->
				<param name="delay">1000</param>
			</interceptor-ref>
			<result name="wait">/wait.jsp</result>
			
			<!-- 使用 tokenSession 拦截器
			<interceptor-ref name="tokenSession"/> -->
			
			<!-- 如果使用 token 下面的就有这样的一个返回值
			<interceptor-ref name="token"/>
			<result name="invalid.token">/login.jsp</result> -->
			
			<result name="input">/login.jsp</result>
			<result name="success">/index.jsp</result>
		</action>
		
	</package>
    
</struts>


wait.jsp
<head>
    <base href="<%=basePath%>">
    
    <title>避免表单重复提交</title>

    <!--设置每5s刷新 这个页面-->
    <meta http-equiv="refresh" content="5,url=<s:url includeParams='all'/>">

  </head>
  
  <body>
   	<h4>正在登录系统<br/><br/>
   	请您稍候...</h4>
  </body>
分享到:
评论

相关推荐

    Struts2解决表单重复提交

    Struts2作为一个流行的Java Web框架,为解决表单重复提交提供了多种方法。 首先,关于表单重复提交的原因,有以下几点: 1. 服务器或网络延迟导致用户多次点击提交按钮。 2. 用户在表单提交后刷新浏览器页面。 ...

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

    6. **异常处理**:Struts2提供了`TokenAwareException`和`TokenMismatchException`来处理Token相关的问题。如果Token无效或已用过,Action执行后会抛出这些异常,开发者可以根据异常类型进行相应的错误处理。 通过...

    Struts2文件上传下载和表单重复提交问题

    综上所述,Struts2文件上传下载和表单重复提交涉及多个技术点,包括Struts2的配置、文件操作、HTTP响应头设置、安全性和异常处理。理解并熟练掌握这些知识点,对于构建健壮的Web应用程序至关重要。

    struts2令牌解决页面重复提交问题

    若不匹配或令牌已被使用,Struts2会抛出`TokenException`异常,此时可以捕获这个异常并显示错误信息,阻止重复操作。 5. **清理令牌**:处理完表单请求后,需要调用`clearToken()`方法来清除session中的令牌,以...

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

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

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

    总结起来,Struts2通过重定向策略可以有效地防止表单重复提交,结合其他如Token Session Strategy等方法,可以进一步提高应用的安全性和稳定性。开发者可以根据项目需求选择合适的防重提交方案,确保系统正常运行。

    Struts2防止表单重复提交示例

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

    Struts2 表单 重复提交

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

    struts2防止重复提交和等待画面

    struts2 防止 重复 提交 和 等待 画面

    应用Struts2处理表单数据

    综上所述,"应用Struts2处理表单数据"这个主题涵盖了Struts2框架中的诸多关键概念,包括Action设计、表单数据绑定、结果处理、拦截器、配置、表达式语言以及验证和异常处理机制。这些知识点对于理解和开发基于Struts...

    Struts2表单标签使用范例

    在Struts2中,表单标签是用于处理用户输入和展示数据的关键组件,它们使得视图层的构建更加简洁和高效。本示例将深入探讨Struts2的表单标签使用方法,帮助开发者更好地理解和应用这些标签。 首先,我们来了解一些...

    整合了struts2 jquery的formValidator表单验证的页面代码

    这个项目中的代码示例可以作为学习和参考,帮助开发者理解如何在实际项目中整合Struts2和jQuery的formValidator,提高表单验证的效率和用户体验。对于初学者来说,深入研究这个示例有助于掌握Struts2和jQuery在实际...

    Struts2表单数据获取项目

    当用户提交表单后,Struts2会调用匹配的Action类的`execute()`方法,此时,`name`和`email`属性已经被填充了表单数据。你可以在这里进行数据验证、业务处理等操作。 至于结果页面,Struts2支持JSP、FreeMarker、...

    struts2版注册表单.rar

    总的来说,这个压缩包提供了一个完整的Struts2注册表单实现,涵盖了MVC架构中的Model(Action)、View(JSP)和Controller(Struts2框架)。通过对这个示例的学习,你可以深入了解Struts2框架如何处理Web请求,如何...

    Struts2防止重复提交解决方案

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

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

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

    在Eclipse中配置Struts2项目(html)手把手教会你 +struts2 标签库介绍(html) + STRUTS2学习文档.pdf + Struts2―表单验证validate(html) + struts2和struts的比较 + struts教程(html)

    在Eclipse中配置Struts2项目(html)手把手教会你 如何在Eclipse中配置Struts2。 struts2 标签库介绍(html)对Struts2的...struts2和struts的比较 让你更清楚的知道struts2和struts的不同之处。 struts教程(html)

    struts2简单登录页面

    struts2简单登录页面struts2简单登录页面struts2简单登录页面struts2简单登录页面struts2简单登录页面struts2简单登录页面struts2简单登录页面struts2简单登录页面

Global site tag (gtag.js) - Google Analytics