用session防止表单重复提交
思路:在服务器端生成一个唯一的随机标识串Token,同时在当前用户的Session域中保存这个Token。然后将Token发送到客户端的Form表单中,在Form表单中使用隐藏域来存储这个Token,表单提交的时候连同这个Token一起提交到服务器端,然后在服务器端判断客户端提交上来的Token与服务器端生成的Token是否一致,如果不一致,那就是重复提交了,此时服务器端就可以不处理重复提交的表单。如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识串。
服务器程序将拒绝处理用户提交的表单请求:
1,存储Session域中的Token与表单提交的Token不同。
2,当前用户的Session中不存在Token。
3,用户提交的表单数据中没有Token。
代码:
1 /** 2 * 防重复提交工具类 3 */ 4 public class TokenUtil { 5 private static String REPEAT_SUBMIT_TOKEN = "REPEAT_SUBMIT_TOKEN"; 6 private static TokenUtil instance = new TokenUtil(); 7 8 private TokenUtil() { 9 10 } 11 12 public static TokenUtil getInstance() { 13 return instance; 14 } 15 16 public static boolean isTokenValid(HttpServletRequest request) { 17 return instance.isTokenValid(request, true); 18 } 19 20 public static boolean isTokenValid(HttpServletRequest request, boolean reset) { 21 HttpSession session = request.getSession(false); 22 23 if (session == null) { 24 return false; 25 } 26 27 String saved = (String) session.getAttribute(REPEAT_SUBMIT_TOKEN); 28 29 if (saved == null) { 30 return false; 31 } 32 33 if (reset) { 34 instance.resetToken(request); 35 } 36 37 String token = request.getParameter(REPEAT_SUBMIT_TOKEN); 38 39 if (token == null) { 40 return false; 41 } 42 43 return saved.equals(token); 44 } 45 46 public static void resetToken(HttpServletRequest request) { 47 HttpSession session = request.getSession(false); 48 49 if (session == null) { 50 return; 51 } 52 53 session.removeAttribute(REPEAT_SUBMIT_TOKEN); 54 } 55 56 public static void saveToken(HttpServletRequest request) { 57 HttpSession session = request.getSession(); 58 String token = instance.generateToken(request); 59 60 if (token != null) 61 session.setAttribute(REPEAT_SUBMIT_TOKEN, token); 62 } 63 64 public static void saveToken(HttpServletRequest request, ResponseJSON responseJSON) { 65 HttpSession session = request.getSession(); 66 String token = instance.generateToken(request); 67 68 if (token != null) { 69 session.setAttribute(REPEAT_SUBMIT_TOKEN, token); 70 } 71 if (responseJSON != null) { 72 responseJSON.setRepeatSubmitToken(token); 73 } 74 75 } 76 77 private String generateToken(HttpServletRequest request) { 78 HttpSession session = request.getSession(); 79 80 return generateToken(session.getId()); 81 } 82 83 private String generateToken(String id) { 84 try { 85 long current = System.currentTimeMillis(); 86 current += new java.util.Random().nextInt(100); 87 88 byte[] now = new Long(current).toString().getBytes(); 89 MessageDigest md = MessageDigest.getInstance("MD5"); 90 91 md.update(id.getBytes()); 92 md.update(now); 93 94 return toHex(md.digest()); 95 } catch (NoSuchAlgorithmException e) { 96 } 97 return null; 98 } 99 100 private String toHex(byte[] buffer) { 101 StringBuffer sb = new StringBuffer(buffer.length * 2); 102 103 for (int i = 0; i < buffer.length; i++) { 104 sb.append(Character.forDigit((buffer[i] & 0xF0) >> 4, 16)); 105 sb.append(Character.forDigit(buffer[i] & 0xF, 16)); 106 } 107 108 return sb.toString(); 109 } 110 }