標籤:
用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 }
java防止表單重複提交