session的使用:防止表单重复提交

来源:互联网 发布:大数据时代读后感3000 编辑:程序博客网 时间:2024/06/05 08:54

服务器端防止表单重复提交思路:

  1. 由服务器端发给每个表单唯一的随机数,作为表单令牌
  2. 每个客户端在服务器端保存的session对象中,存储生成的表单令牌
  3. 客户端提交表单后进行表单令牌的验证,如果客户端与服务器中的令牌一致,那么可以提交,并且提交后移除session中的令牌
  4. 如果不一致,说明已经注册过了,从而终止提交动作
  5. 令牌发生器采用单例模式,获取数据摘要,并进行base64编码,得到统一长度的随机令牌字符串

登录servlet:

package com.franky.login;import java.io.IOException;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 javax.servlet.http.HttpSession;import sun.misc.BASE64Encoder;/** * @作者 franky * @描述   防止表单重复提交 * @日期 2015-1-12 下午04:35:47 */public class LoginForm extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//生成随机数,将随机数写入表单TokenProcessor token = TokenProcessor.getInstance();String encode = token.generateToken();System.out.println(encode);//随机数写入sessionHttpSession session = request.getSession();session.setAttribute("token", encode);//随机数写入表单request.getRequestDispatcher("/login2.jsp").forward(request, response);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}/** *  * @作者 franky * @描述  随机数生成器,采用单例模式,防止重复随机数路领跑 * @日期 2015-1-12 下午04:35:33 */class TokenProcessor{private static final TokenProcessor instance = new TokenProcessor();private TokenProcessor(){}public static TokenProcessor getInstance(){return instance;}/**生成随机令牌的方法 * @return 返回随机字符串随机令牌 */public String generateToken(){String token = System.currentTimeMillis()+new Random().nextInt()+"";try {//获得数据摘要的方法MessageDigest md = MessageDigest.getInstance("md5");byte[] md5 = md.digest(token.getBytes());//base64编码的方法BASE64Encoder encoder = new BASE64Encoder();String encode = encoder.encode(md5);return  encode;} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return null;}}
转发的jsp页面:

<%@ 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><script type="text/javascript">var isSubmit = false;function doSubmit(){if(!isSubmit){isSubmit = true;return true;}else{window.alert("请不要重复注册");return false;}}</script></head><body><form  action="/javawebdemos/servlet/CheckServlet" method="post" ><input type="hidden" name="token" value="${token}"/>username:<input type="text" name="username"><br/><input type="submit" value="submit" onclick="return doSubmit()" ></form></body></html>

验证servlet:

package com.franky.login;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;/** * @作者 franky * @描述   防止表单重复提交,利用session中的表单令牌 * @日期 2015-1-12 下午04:43:02 */public class CheckServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//验证表单是否有效boolean isValid = isTokenValid(request);if(!isValid){System.out.println("请不要重复注册!");return;}request.getSession().removeAttribute("token");System.out.println("注册成功");}/** * 检验表单令牌是否有效 * @param request 传入request对象 * @return 返回令牌是否有效 */private boolean isTokenValid(HttpServletRequest request) {String c_token = request.getParameter("token");//验证表单令牌是否为空,为空返回falseif(c_token==null){return false;}HttpSession session = request.getSession();String s_token = (String) session.getAttribute("token");//验证服务器端令牌是否为空,为空返回falseif(s_token==null){return false;}//验证两端的令牌是否相同,不相同返回falseif(!s_token.equals(c_token)){return false;}//排除以上三种情况后,返回truereturn true;}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}



0 0