Session应用之---防止表单重复提交

Session应用之---防止表单重复提交

客户端防止(采用JavaScript阻止方式):

PS:防得住君子,防不了小人

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>防表单重复提交</title>

    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">

    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

	<script type="text/javascript">
		/*
		var iscommitted = false;
		function dosubmit(){
			if(!iscommitted){
				iscommitted = true;
				return true;
			}else{
				return false;
			}

		}
		*/
		function dosubmit(){
			document.getElementById("submit").disabled = 'disabled';
			return true;
		}

	</script>

  </head>

  <body>
    <form action="/day07/servlet/FormSubmitServlet" method="post" onsubmit="return dosubmit()">
    	用户名:<input type="text" name="username"><br/>
    	<input id="submit" type="submit" value="提交">
    </form>
  </body>
</html>

服务器端防止:

表单页面由servlet程序生成,servlet为每次产生的表单页面分配一个唯一的随机标识号,并在FORM表单的一个隐藏字段中设置这个标识号,同时在当前用户的Session域中保存这个标识号。

当用户提交FORM表单时,负责处理表单提交的serlvet得到表单提交的标识号,并与session中存储的标识号比较,如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号。

在下列情况下,服务器程序将拒绝用户提交的表单请求:

1,存储Session域中的表单标识号与表单提交的标识号不同

2,当前用户的Session中不存在表单标识号

3,用户提交的表单数据中没有标识号字段

产生表单:

package cn.itcast.form;

import java.io.IOException;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import sun.misc.BASE64Encoder;
//产生表单
public class FormServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		PrintWriter  out = response.getWriter();

		String token = TokenProcessor.getInstance().generateToken();
		request.getSession().setAttribute("token", token);

		out.print("<form action='/day07/servlet/FormSubmitServlet' method='post'>");
			out.print("<input type='hidden' name='token' value='"+token+"'>");
			out.print("<input type='text' name='username'>");
			out.print("<input type='submit' value='提交'>");
		out.print("</form>");

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}

class TokenProcessor{
	//1.  把构造方法私有
	//2.  自己产生一个类的对象
	//3.  定义一个方法返回上面产生的对象

	private TokenProcessor(){};
	public static final TokenProcessor instance = new TokenProcessor();
	public static TokenProcessor getInstance(){
		return instance;
	}

	public String generateToken(){

		//3843849384   9849238402840243802  983434
		String token = System.currentTimeMillis() + "" + new Random().nextInt(99999999);

		//数据指纹 数据摘要  md5
		try {
			MessageDigest md = MessageDigest.getInstance("md5");
			byte md5[] = md.digest(token.getBytes());   //128位  16个字节【12,23,34,544543543543,】

			//base64编码    SABDSSDSD
			BASE64Encoder encoder = new BASE64Encoder();
			return encoder.encode(md5);

		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException(e);
		}
	}
}

检验是否重复提交:

package cn.itcast.form;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FormSubmitServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		boolean b = isToken(request);
		if(!b){
			//用户带过来的令牌无效,阻止提交
			System.out.println("你是重复提交!!");
			return;
		}

		//用户带过来的令牌有效,处理提交
		request.getSession().removeAttribute("token");

		String username = request.getParameter("username");
		//把用户提交的数据保存到数据库中
		System.out.println("处理提交请求,把" + username + "保存到数库中!!");

	}

	//判断用户带过来的令牌是否有效
	private synchronized boolean isToken(HttpServletRequest request) {
		String client_token = request.getParameter("token");
		if(client_token==null){
			return false;
		}

		String server_token = (String) request.getSession().getAttribute("token");
		if(server_token==null){
			return false;
		}

		if(!client_token.equals(server_token)){
			return false;
		}

		return true;
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
时间: 2024-10-10 23:27:52

Session应用之---防止表单重复提交的相关文章

Servlet/JSP-07 Session应用:避免表单重复提交

Session应用:避免表单重复提交 一. 表单的重复提交 1. 重复提交的情况 ①在表单提交到一个 Servlet,而 Servlet 又通过请求转发的方式响应了一个 JSP 或者 HTML 页面,此时浏览器地址栏还保留着 Servlet 路径,在此响应页面点击”刷新“按钮 ② 在响应页面尚未到达时,重复点击表单的”提交“按钮 ③ 点击”返回“按钮或者浏览器的回退按钮,再点击”提交“按钮 2.如何避免表单重复提交? 原理:在表单中做一个标记,当表单提交到Servlet时,检查标记是否存在且是否

[原创]java WEB学习笔记34:Session 案例 之 解决表单重复提交

本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 ---------------------------------

session案例:防止表单重复提交、一次性校验码

session案例1:防止表单重复提交 原理: 1,表单页面由servlet程序生成,servlet为每次产生的表单页面分配一个唯一的随机标识号,并在FORM表单的一个隐藏字段中设置这个标识号,同时在当前用户的Session域中保存这个标识号. 2,当用户提交FORM表单时,负责处理表单提交的serlvet得到表单提交的标识号,并与session中存储的标识号比较,如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号. 3,在下列情况下,服务器程序将拒绝用户提交的表单请求

弹出窗口Session丢失、防止表单重复提交问题

一.弹出窗口Session丢失问题 弹出窗口Session丢失使用window.showModalDialog进行信息的提示,相当方便,也容易控制外观和布局.但是存在一个严重的问题,就是Session丢失.当在A页面进行showModalDialog时,弹出的模态窗口open新页面或new dialog()时,会得不到A页面中的Session,这样就严重地限制了他的使用范围.进一步的使用模式窗口可以发现session的丢失总是便随页面的刷新1.在普通页面中弹出模式窗口且进行new dialog(

session,url重写,防止表单重复提交

Session入门_session原理 1.Session概述 1.在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象), 注意:一个浏览器独占一个session对象(默认情况下). 2.Session 是一个域 1.作用范围:一个浏览器和服务器会话范围 2.生命周期: 创建 当程序第一次调用到request.getSession()方法时说明客户端明确的需要用到session此时创建出对应客户端的Session对象. request.getSession()=req

php通过token验证表单重复提交

PHP防止重复提交表单 2016-11-08 轻松学PHP 我们提交表单的时候,不能忽视的一个限制是防止用户重复提交表单,因为有可能用户连续点击了提交按钮或者是攻击者恶意提交数据,那么我们在提交数据后的处理如修改或添加数据到数据库时就会惹上麻烦. 那么如何规避这中重复提交表单的现象出现呢?我们可以从很多方面入手,首先从前端做限制.前端JavaScript在按钮被点击一次后禁用,即disabled,这个方法简单的防止了多次点击提交按钮,但是缺点是如果用户禁用了javascript脚本则失效.第二,

JavaWeb学习总结(十三)——使用Session防止表单重复提交

在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提交的常见应用场景 有如下的form.jsp页面 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML>

10-客户端防表单重复提交和服务器端session防表单重复提交

/****************************************************DoFormServlet********************************************************/ package session; import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import

利用session防止表单重复提交

转自:http://www.cnblogs.com/xdp-gacl/p/3859416.html 利用Session防止表单重复提交 对于[场景二]和[场景三]导致表单重复提交的问题,既然客户端无法解决,那么就在服务器端解决,在服务器端解决就需要用到session了. 具体的做法:在服务器端生成一个唯一的随机标识号,专业术语称为Token(令牌),同时在当前用户的Session域中保存这个Token.然后将Token发送到客户端的Form表单中,在Form表单中使用隐藏域来存储这个Token,