session防止表单重复提交

转载:http://www.cnblogs.com/xdp-gacl/p/3859416.html


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


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


import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/*表单重复提交:1.原因:可能由于网络延迟导致客户点击多次或者刷新是都会导致表单重复提交
 *           2.解决办法:(1)对于网络延迟的重复提交可以使用js判断,点击之后将按钮置灰
 *                    (2)可是使用token判断,两次请求的携带的token不一致则提示不可重复提交
 * */
public class ServletSession007 extends HttpServlet {


public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
      //客户端是以UTF-8编码传输数据到服务器端的,所以需要设置服务器端以UTF-8的编码进行接收,否则对于中文数据就会产生乱码
 /* request.setCharacterEncoding("utf-8");
       String userName=request.getParameter("username");
        try {
        //让当前的线程睡眠2秒钟,模拟网络延迟而导致表单重复提交的现象
Thread.sleep(2*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
//方法二:使用session防止客户端表单重复提交
boolean b=isRepeatSubmit(request);
if(b==true){
System.out.println("请不要重复提交");
return;
}
request.getSession().removeAttribute("token");   //移除session中的token
       

}
//判断客户端提交的令牌和服务端生成的令牌是否一致
   private boolean isRepeatSubmit(HttpServletRequest request){
  String client_token =request.getParameter("token");
//1.如果用户提交的表单数据中没有token,则用户是重复提交了表单
if(client_token==null){
return true;
}
//取出存储在session中的token
String server_token=(String)request.getSession().getAttribute("token");
//如果当前用户的Session中不存在Token(令牌),则用户是重复提交了表单
if(server_token==null){
return true;
}
 //3、存储在Session中的Token(令牌)与表单提交的Token(令牌)不同,则用户是重复提交了表单
  if(!client_token.equals(server_token)){
  return true;
  }
return false;
   }


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

  //生成token的工具类
class TokenProccessor{
/*
  *单例设计模式(保证类的对象在内存中只有一个)
       *1、把类的构造函数私有
  *2、自己创建一个类的对象
  *3、对外提供一个公共的方法,返回类的对象*/

private TokenProccessor(){}
private  final TokenProccessor instance=new TokenProccessor();
//返回类的对象
public  TokenProccessor getInstance(){
 return instance;
 }
//生成token
public String makeToken(){
String token =(System.currentTimeMillis())+new Random().nextInt(99999999)+"";
//数据指纹
try{
MessageDigest md=MessageDigest.getInstance("MD5");
byte md5[]=md.digest(token.getBytes());
//base64编码-任意二进制编码名为字符
BASE64Encoder encoder=new BASE64Encoder();
return encoder.encode(md5);
} catch (NoSuchAlgorithmException e) {
          throw new RuntimeException(e);
}
}
}


}


jsp文件:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>




form表单重复提交演示









<%--


用户名:
--%>





" />


用户名:







你可能感兴趣的:(JavaWeb开发)