防止页面表单重复提交的解决方法

个人学习笔记,写下方便以后复用。

   当我们写了个注册页面时候,用户完成注册并提交,用户注册的资料并录入数据库保存,最不希望出现的是在一个会话中出现多次提交的结果,我们可以通过为请求设置标记来避免此类事件的发生。

   1.为每个请求设置一个标记,当此页面是首次被请求时,生成标记并放入session中,并且把此生成的标记的值作为隐含标签传递到处理页面

   2.提交表单时,跳转页面处理请求中的标记,如果判断请求中session对象的标记和隐含标签中的值相同,处理请求,并将session中的标记值去除

    

  ( TokenGen.java)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package  com.beans;
 
import  java.util.*;
import  javax.servlet.http.*;
 
public  class  TokenGen {
     private  static  TokenGen instance = new  TokenGen();
 
     private  TokenGen() {}
 
     public  static  TokenGen getInstance() {
         return  instance;
     }
 
     public  synchronized  boolean  isTokenValid(HttpServletRequest request) {
         // 没有session,判为非法
         HttpSession session = request.getSession( false );
         if  (session == null )
             return  false ;
 
         // session中不含token,
         // 说明form被提交过后执行了resetToken()清除了token
         // 判为非法
         String stoken = (String) session.getAttribute( "token" );
         if  (stoken == null )
             return  false ;
 
         // request请求参数中不含token,
         // 判为非法
         String rtoken = request.getParameter( "token" );
         if  (rtoken == null )
             return  false ;
 
         // request请求中的token与session中保存的token不等,判为非法
         return  stoken.equals(rtoken);
     }
     
     /*
      * 重新设置token,当页面被请求后,将session中的token属性去除
      */
     public synchronized void resetToken(HttpServletRequest request)
     {
         HttpSession session = request.getSession(false);
         if (session!=null)
         {
             session.removeAttribute("token");
         }
     }
     /*
      * 为请求新建一个token标记,此标记由一个随机的double数toString形成,并把字符值存入session中
      */
     
     public  synchronized  void  saveToken(HttpServletRequest request)
     {
         HttpSession session = request.getSession( true );
         Random rand = new  Random();
         Double d = rand.nextDouble();
         session.setAttribute( "token" , d.toString());   
     }
}
?
1
 
(form.jsp) 其中加粗加红为生成token标记的代码
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<%@ page language="java" import="com.beans.*" pageEncoding="gb2312"%>
 
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
< html >
  < head >
 
   < title >注册页面1</ title >
 
   < meta  http-equiv = "pragma"  content = "no-cache" >
   < meta  http-equiv = "cache-control"  content = "no-cache" >
   < meta  http-equiv = "expires"  content = "0" >
   < meta  http-equiv = "keywords"  content = "keyword1,keyword2,keyword3" >
   < meta  http-equiv = "description"  content = "This is my page" >
  </ head >
  <%
   TokenGen.getInstance().saveToken(request);
   String s = (String)session.getAttribute("token");
  %>
  < body >
   < form  id = "form1"  name = "form1"  method = "post"  action = "register.jsp" >
   
    < table  align = "center" >
    < tr >
     < td  colspan = "2" >< br >< input  type = "hidden"  name = "token"  value="<%=s%>"/>
     </ td >
    </ tr >
     < tr >
      < td  align = "right" >
       用户名:
      </ td >
      < td >
       < input  type = "text"  name = "t1"  />
      </ td >
     </ tr >
 
     < tr >
      < td  align = "right" >
       密码:
      </ td >
      < td >
       < input  type = "password"  name = "t2"  />
      </ td >
     </ tr >
 
     < tr >
      < td  align = "right" >
       确认密码:
      </ td >
      < td >
       < input  type = "password"  name = "t3"  />
      </ td >
     </ tr >
 
     < tr >
      < td  align = "right" >
       性别:
      </ td >
      < td >
       < input  type = "radio"  name = "radio"  id = "radio"  value = "boy"  />
      
       < input  type = "radio"  name = "radio"  id = "radio2"  value = "gril"  />
      
      </ td >
     </ tr >
 
     < tr >
      < td  align = "right" >
       个人说明:
      </ td >
      < td >
       < textarea  name = "textraea1"  rows = "15"  cols = "60" ></ textarea >
      </ td >
     </ tr >
 
     < tr >
      < td  align = "right" >
       < input  type = "submit"  name = "button"  id = "button"  value = "提交"  />
      </ td >
      < td >
       < input  type = "reset"  name = "button2"  id = "button2"  value = "重置"  />
      </ td >
     </ tr >
    </ table >
   </ form >
  </ body >
</ html >
(register.jsp)处理请求
   
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<%@ page language="java" import="com.beans.*" pageEncoding="gb2312"%>
 
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
< html >
   < head >
 
     
     < title >处理注册页面1</ title >
     
  < meta  http-equiv = "pragma"  content = "no-cache" >
  < meta  http-equiv = "cache-control"  content = "no-cache" >
  < meta  http-equiv = "expires"  content = "0" >   
  < meta  http-equiv = "keywords"  content = "keyword1,keyword2,keyword3" >
  < meta  http-equiv = "description"  content = "This is my page" >
  <!--
  <link rel="stylesheet" type="text/css" href="styles.css">
  -->
 
   </ head >
   
   < body >
    <%
     TokenGen tokenGen=TokenGen.getInstance();
     if (!tokenGen.isTokenValid(request))
     {
      out.print("这是重复提交或非法提交!");
     }
     else
     {
      // 处理请求,并执行resetToken方法,将session中的token去除
      tokenGen.resetToken(request);
     }
     
     %>
   </ body >
</ html >
  其中还有一种是通过设置时间间隔来限制重复提交,其实现原理和上面的大同小异。

 Que

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值