`

session 的应用——防止表单重复提交——1.0版

阅读更多

1). 表单的重复提交:

> 在表单页面, 多次点击 "提交" 按钮.

> 在转发的情况下, "刷新" 在成功页面

> 点击 "后退" 后, 再次提交表单.

2). 不属于表单重复提交:

> 点击 "后退" 后,刷新表单页面 , 再次提交表单. 属于是一个新的请求

3). 思路:

> 在表单中做一个标记

> 在 Servlet 中验证标记是否存在, 若存在, 受理请求, 同时销毁标记; 若不存在, 视为重复提交

4). 步骤:

> 做标记

* 在表单中使用隐藏域: 不行! 因为在点击 "刷新" 时, 隐藏域和一般的表单域是一样的, 都会被提交到 Servlet 中.

* 放在 request 属性中: 不行! 因为 form 页面的 request 和点击 "提交" 按钮的 request 是两个不同的请求.

* 放在 session 属性中:

> 在 Servlet 中进行验证:

* 获取标记

* 检查标记是否为空, 若为空, 则按重复提交处理; 若不为空, 将其从  session 中清除, 处理表单

5). 完善:

> 在 Session 中放入的值应该是一个随机值, 且唯一: 使用当前的系统时间

> 在 Servelt 中不但要检验 Session 的值是否存在, 还要检查 Session 中的值是否和当时放的值是否一致: 把 Session 中的属性值放在隐藏域中



代码实现:


xml 文档自己配

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

	<%
                   //取得唯一值
		String time = "" +session.getId() + System.currentTimeMillis() ;
		session.setAttribute("token", time) ;
	%>

	<form action="LoginServlet" method="post">
		<!-- 用隐藏域将表单做上标记 -->
		<input type="hidden" name="token" value="<%=time %>"/>
		<table border="1">
			<tr>
				<td>Name:</td>
				<td>
					<input type="text" name="name"/>
				</td>
			</tr>
			
			<tr>
				<td>Password:</td>
				<td>
					<input type="password" name="password"/>
				</td>
			</tr>
			
			<tr rowspan="2">
				<td>
					<input type="submit" value="Submit"/>
				</td>
				<td>
					<input type="reset" value="Reset"/>
				</td>
			</tr>
		</table>
	</form>

</body>
</html>


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

	注册成功!

</body>
</html>



<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

	<h4>表单已经提交!请不要多次提交!</h4>

</body>
</html>


package com.syh.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response) ;
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			//模拟网速
			Thread.sleep(3000) ;
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		//0. 获取 "标记"
		boolean flag = true ;
		
		//1. 获取 HttpSession, 若 Session 不存在, 为重复提交
		HttpSession session = request.getSession(false) ;
		if(null == session) {
			flag = false ;
		}else {
			//2. 从 Session 中获取指定的属性值, 若指定的值不存在, 也是为重复提交
			String token = (String)session.getAttribute("token") ;
			if(null == token) {
				flag = false ;
			}else {
				//3. 从隐藏域中获取 Session 中存放的属性值, 若指定的值不存在, 也是为重复提交
				String token2 = request.getParameter("token") ;
				if(null == token2) {
					flag = false ;
				}else {
					//4. 比较 token 和 token2 的值是否一致
					if(token.equals(token2)) {
						//5. 从 Session 中移除属性
						session.removeAttribute("token") ;
					}
				}
			}
		}
			
		
		if(!flag){
			System.out.println("重复提交");
			response.sendRedirect(request.getContextPath() + "/error.jsp") ;
			return ;
		}
			String name = request.getParameter("name") ;
			System.out.println("添加成功-->" + name);
		
			//这里必须用转发!仔细想想就明白了!因为转发的时候,URL 没有改变!当我们再次刷新的时候,
			//再次对该页面请求了!故而同一个表单再次请求了!
			request.getRequestDispatcher("/success.jsp").forward(request, response) ;
			//response.sendRedirect(request.getContextPath() + "/success.jsp") ;
		
		 
	

	}	
}
 
分享到:
评论

相关推荐

    ASP.NET中防止刷新页面造成表单重复提交

    ### ASP.NET中防止刷新页面造成表单重复提交 在Web应用程序开发中,特别是在使用ASP.NET进行网站构建时,一个常见的问题是表单重复提交。这通常发生在用户通过按下浏览器的F5键来刷新页面的情况下,此时之前的表单...

    重复提交资料——解析

    6. **Session管理**:在用户提交表单时,服务器可以在Session中记录这一行为,后续的重复提交可以通过检查Session来阻止。 7. **数据库事务**:对于涉及数据库操作的表单提交,可以使用事务来确保数据的一致性。...

    JSP源码——JSP Explorer 文件浏览器 v1.0_fileexplorer.zip

    【JSP源码——JSP Explorer 文件浏览器 v1.0】是一个基于Java Server Pages (JSP) 技术实现的简单文件浏览应用。这个压缩包包含了一整套用于创建一个在线文件管理系统的基本组件,允许用户在Web环境中查看、管理...

    php表单加入Token防止重复提交的方法分析

    Token一般用在两个地方——防止表单重复提交、anti csrf攻击(跨站点请求伪造)。 两者在原理上都是通过session token来实现的。当客户端请求页面时,服务器会生成一个随机数Token,并且将Token放置到session当中,...

    tokenSession拦截器的使用

    `tokenSession`拦截器是Struts2框架提供的一个用于防止表单重复提交的机制。它通过生成一个唯一的令牌(token)并将其存储在用户的会话(session)中,以此来验证请求是否为重复提交。当用户首次提交表单时,服务器...

    PHP实例开发源码——PHP FexBook v1.0 Beta.zip

    7. **表单处理**:表单提交和验证是Web应用中的常见任务,源码中可能包含多种表单处理方法,如使用filter_var()进行输入验证,以及错误处理机制。 8. **AJAX异步通信**:为了提升用户体验,FexBook可能利用...

    PHP实例开发源码——搜书网投票系统PHP版 v1.0.zip

    版本号 "v1.0" 表明这是该系统的第一个正式版本,通常意味着基础功能已经完成,但可能缺乏一些高级特性和优化。 在压缩包内文件 "132699343130075788" 可能是系统的主要源代码文件或者数据库配置文件。在PHP项目中...

    使用struts的同步令牌避免form的重复提交

    为了有效地防止Web应用程序中的表单重复提交问题,Struts框架提供了一种简单而强大的解决方案——同步令牌模式(Synchronization Token Pattern, STP)。下面详细介绍如何在Struts项目中实现这一功能。 1. **生成...

    ASP实例开发源码——红码简约asp论坛博客版 v1.0.zip

    2. **请求与响应对象**:ASP中的Request对象用于获取客户端发送的数据,如表单提交的信息;Response对象则负责向客户端发送数据,包括HTML、CSS、JavaScript等。 3. **Session与Application对象**:在ASP中,...

    jsp源码实例2(获取表单参数).docx

    4. 解决JSP页面刷新时表单重复提交的问题,可以通过Session或Token机制来防止。 5. 在非表单请求中设置action的多种方式,扩展了页面交互的可能性。 6. jQuery AJAX提交表单,将action中的值传递给JSP,这种异步提交...

    ASP.NET源码——[博客空间]X3BLOG 单用户版 1.0 build80802 编译版.zip

    【X3BLOG单用户版1.0 build80802 编译版】是一个基于ASP.NET技术的博客系统源码,适用于个人用户搭建自己的在线博客。ASP.NET是微软公司开发的一种强大的Web应用程序框架,它提供了丰富的工具集、控件库以及高效的...

    asp应用手册——技巧实例

    在"asp应用手册——技巧实例"中,我们可以深入探讨ASP的核心概念、语法特性以及实际开发中的实用技巧。 ASP的主要特点包括: 1. **服务器端执行**:ASP代码在服务器上运行,生成HTML代码,然后发送到客户端浏览器...

    JSP源码——[上传下载]铁人下载系统 Liuxing 1.0_liuxing1.0.zip

    《JSP源码详解——深度剖析“铁人下载系统 Liuxing 1.0”》 JSP(JavaServer Pages)是一种动态网页技术,它允许开发者将Java代码嵌入到HTML页面中,以实现服务器端的数据处理和业务逻辑。本文将深入探讨名为“铁人...

    HttpSession/session,jsp,servlet——综合练习题一

    这里我们将深入探讨这些技术,并结合一个名为"web26_session5示例1"的压缩包文件,来解析它们在实际应用中的综合运用。 首先,`HttpSession`是Java Servlet API的一部分,它提供了在HTTP会话之间存储和检索对象的...

    用jsp编写的小的应用程序——简历的制作

    【标题】"用jsp编写的小的应用程序——简历的制作"涉及到的是使用JavaServer Pages(JSP)技术开发一个简易的在线简历制作应用。这个应用程序利用了动态网页技术,结合后端数据库存储,使得用户能够创建、编辑和管理...

    《Java Web开发基础——从Servlet到JSP》源代码v1.0

    《Java Web开发基础——从Servlet到JSP》是一本深入探讨Java Web开发的教程,主要涵盖了从基础的Servlet到高级的JSP技术。这个压缩包包含的源代码是该书教学内容的实践部分,旨在帮助读者更好地理解和应用所学知识。...

    ASP实例开发源码——asp食品安全研究中心双语版 v1.0.zip

    【ASP实例开发源码——asp食品安全研究中心双语版 v1.0】 ASP(Active Server Pages)是一种由微软公司推出的服务器端脚本环境,用于在IIS(Internet Information Services)上创建动态网页。这个实例开发源码是...

    《ASP实用技术——网络数据库应用系统设计》电子教案-2298-李禹生

    《ASP实用技术——网络数据库应用系统设计》是李禹生教授的一部教程,主要探讨了如何使用ASP(Active Server Pages)技术构建网络数据库应用系统。ASP是微软开发的一种服务器端脚本环境,常用于创建动态网页和交互式...

    ASP实例开发源码——仿IPAD留言板(asp+access) v1.0.zip

    在本实例"ASP实例开发源码——仿IPAD留言板(asp+access) v1.0.zip"中,我们将深入探讨如何利用ASP技术和Access数据库来构建一个类似于iPad留言板的应用。 一、ASP基础 ASP是Web开发的基础,它允许开发者使用诸如...

    ASP实例开发源码——长春阳光妇科医院在线预约系统 v1.0.zip

    【标题】"ASP实例开发源码——长春阳光妇科医院在线预约系统 v1.0.zip" 涉及的知识点主要集中在ASP(Active Server Pages)编程技术上,这是一款基于服务器端的脚本语言,用于创建动态网页。在这个实例中,我们看到...

Global site tag (gtag.js) - Google Analytics