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