session 的应用——防止表单重复提交——2.0版

session 的应用——防止表单重复提交——2.0版(使用了Struts1 中的重复提交组件: TokenProcessor和自定义标签)

Html代码   收藏代码
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <!-- 这里使用的是自定义标签 -->  
  4. <%@ taglib prefix="syh" uri="http://java.syh.com/jsp/syh/core"%>  
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  6. <html>  
  7. <head>  
  8. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  9. <title>Insert title here</title>  
  10.   
  11. <script type="text/javascript">  
  12.   
  13.     //点击 "提交" 按钮, 只能点击一次  
  14.     var flag = true;  
  15.       
  16.       
  17.     function token(btn){  
  18.         if(flag){  
  19.             flag = false;  
  20.             return true;  
  21.         }else{  
  22.             alert('已经提交过了');  
  23.         }  
  24.     }  
  25.       
  26.     /*  
  27.     下面的JS代码对 IE 不使用,对于 FF  
  28.     function token2(btn){  
  29.         if(flag){  
  30.             btn.disabled = true;  
  31.             return true;  
  32.         }  
  33.     }  
  34.     */  
  35.       
  36. </script>  
  37. </head>  
  38. <body>  
  39.   
  40.         <!--    
  41.             TokenProcessor.getInstance().saveToken(request)  
  42.               
  43.             1. 生成一个随机字符串, 可以保证其唯一  
  44.             2. 把该字符串放在 Session 域中  
  45.             3. 返回该字符串  
  46.         -->  
  47.           
  48.     <form action="LoginServlet" method="post" id="regForm">  
  49.         <!-- 这里使用的是自定义标签 -->  
  50.         <syh:token/>  
  51.         <table border="1">  
  52.             <tr>  
  53.                 <td>Name:</td>  
  54.                 <td>  
  55.                     <input type="text" name="name"/>  
  56.                 </td>  
  57.             </tr>  
  58.               
  59.             <tr>  
  60.                 <td>Password:</td>  
  61.                 <td>  
  62.                     <input type="password" name="password"/>  
  63.                 </td>  
  64.             </tr>  
  65.               
  66.             <tr rowspan="2">  
  67.                 <td>  
  68.                     <input type="submit" value="Submit" onclick="return token2(this);"/>  
  69.                 </td>  
  70.                 <td>  
  71.                     <input type="reset" value="Reset"/>  
  72.                 </td>  
  73.             </tr>  
  74.         </table>  
  75.     </form>  
  76.   
  77. </body>  
  78. </html>  


Html代码   收藏代码
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  4. <html>  
  5. <head>  
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  7. <title>Insert title here</title>  
  8. </head>  
  9. <body>  
  10.   
  11.     注册成功!  
  12.   
  13. </body>  
  14. </html>  


Html代码   收藏代码
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  4. <html>  
  5. <head>  
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  7. <title>Insert title here</title>  
  8. </head>  
  9. <body>  
  10.   
  11.     <h4>表单已经提交!请不要多次提交!</h4>  
  12.   
  13. </body>  
  14. </html>  


Java代码   收藏代码
  1. package com.syh.servlet;  
  2.   
  3. import java.io.IOException;  
  4. import javax.servlet.ServletException;  
  5. import javax.servlet.http.HttpServlet;  
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.http.HttpServletResponse;  
  8.   
  9.   
  10. public class LoginServlet extends HttpServlet {  
  11.     private static final long serialVersionUID = 1L;  
  12.   
  13.       
  14.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  15.             doPost(request, response) ;  
  16.     }  
  17.   
  18.       
  19.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  20.           
  21.         try {  
  22.             Thread.sleep(3000) ;  
  23.         } catch (InterruptedException e) {  
  24.             e.printStackTrace();  
  25.         }  
  26.           
  27.         try {  
  28.             //模拟网速  
  29.             Thread.sleep(1000);  
  30.         } catch (InterruptedException e) {  
  31.             e.printStackTrace();  
  32.         }  
  33.           
  34.         //1. 检验 Token 是否可用  
  35.         boolean flag = TokenProcessor.getInstance().isTokenValid(request) ;  
  36.         //2. 去除 Session 中的 Token 标记  
  37.         if(flag) {  
  38.             TokenProcessor.getInstance().resetToken(request) ;  
  39.         }else {  
  40.             System.out.println("重复提交");  
  41.             request.getRequestDispatcher("/error.jsp").forward(request, response) ;  
  42.             return ;  
  43.         }  
  44.           
  45.         String name = request.getParameter("name") ;  
  46.         System.out.println("添加成功-->" + name);  
  47.           
  48.         request.getRequestDispatcher("/success.jsp").forward(request, response) ;  
  49.     }  
  50.   
  51. }  


Java代码   收藏代码
  1. package com.syh.servlet;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.http.HttpSession;  
  5. import javax.servlet.jsp.JspException;  
  6. import javax.servlet.jsp.PageContext;  
  7. import javax.servlet.jsp.tagext.SimpleTagSupport;  
  8.   
  9. import java.io.IOException;  
  10. import java.security.MessageDigest;  
  11. import java.security.NoSuchAlgorithmException;  
  12.   
  13. public class TokenProcessor extends SimpleTagSupport{  
  14.       
  15.     @Override  
  16.     public void doTag() throws JspException, IOException {  
  17.   
  18.         PageContext pageContext = (PageContext) getJspContext();  
  19.         HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();  
  20.           
  21.         String output = "<input type='hidden' name='" + TOKEN_KEY + "' value='" + saveToken(request) + "'/>";  
  22.         pageContext.getOut().print(output);  
  23.     }  
  24.       
  25.     public static final String TAGLIB_PACKAGE = "org.apache.struts.taglib.html";  
  26.       
  27.     public static final String TRANSACTION_TOKEN_KEY =  
  28.         "org.apache.struts.action.TOKEN";  
  29.       
  30.     public static final String TOKEN_KEY = TAGLIB_PACKAGE + ".TOKEN";  
  31.       
  32.     private static TokenProcessor instance = new TokenProcessor();  
  33.   
  34.     private long previous;  
  35.   
  36.     public TokenProcessor() {  
  37.         super();  
  38.     }  
  39.   
  40.     public static TokenProcessor getInstance() {  
  41.         return instance;  
  42.     }  
  43.   
  44.     public synchronized boolean isTokenValid(HttpServletRequest request) {  
  45.         return this.isTokenValid(request, false);  
  46.     }  
  47.   
  48.     public synchronized boolean isTokenValid(HttpServletRequest request,  
  49.         boolean reset) {  
  50.         // Retrieve the current session for this request  
  51.         HttpSession session = request.getSession(false);  
  52.   
  53.         if (session == null) {  
  54.             return false;  
  55.         }  
  56.   
  57.         String saved =  
  58.             (String) session.getAttribute(TRANSACTION_TOKEN_KEY);  
  59.   
  60.         if (saved == null) {  
  61.             return false;  
  62.         }  
  63.   
  64.         if (reset) {  
  65.             this.resetToken(request);  
  66.         }  
  67.   
  68.         String token = request.getParameter(TOKEN_KEY);  
  69.   
  70.         if (token == null) {  
  71.             return false;  
  72.         }  
  73.   
  74.         return saved.equals(token);  
  75.     }  
  76.   
  77.     public synchronized void resetToken(HttpServletRequest request) {  
  78.         HttpSession session = request.getSession(false);  
  79.   
  80.         if (session == null) {  
  81.             return;  
  82.         }  
  83.   
  84.         session.removeAttribute(TRANSACTION_TOKEN_KEY);  
  85.     }  
  86.   
  87.     public synchronized String saveToken(HttpServletRequest request) {  
  88.         HttpSession session = request.getSession();  
  89.         String token = generateToken(request);  
  90.   
  91.         if (token != null) {  
  92.             session.setAttribute(TRANSACTION_TOKEN_KEY, token);  
  93.         }  
  94.           
  95.         return token;  
  96.     }  
  97.   
  98.     public synchronized String generateToken(HttpServletRequest request) {  
  99.         HttpSession session = request.getSession();  
  100.   
  101.         return generateToken(session.getId());  
  102.     }  
  103.   
  104.     public synchronized String generateToken(String id) {  
  105.         try {  
  106.             long current = System.currentTimeMillis();  
  107.   
  108.             if (current == previous) {  
  109.                 current++;  
  110.             }  
  111.   
  112.             previous = current;  
  113.   
  114.             byte[] now = new Long(current).toString().getBytes();  
  115.             MessageDigest md = MessageDigest.getInstance("MD5");  
  116.   
  117.             md.update(id.getBytes());  
  118.             md.update(now);  
  119.   
  120.             return toHex(md.digest());  
  121.         } catch (NoSuchAlgorithmException e) {  
  122.             return null;  
  123.         }  
  124.     }  
  125.   
  126.     private String toHex(byte[] buffer) {  
  127.         StringBuffer sb = new StringBuffer(buffer.length * 2);  
  128.   
  129.         for (int i = 0; i < buffer.length; i++) {  
  130.             sb.append(Character.forDigit((buffer[i] & 0xf0) >> 416));  
  131.             sb.append(Character.forDigit(buffer[i] & 0x0f16));  
  132.         }  
  133.   
  134.         return sb.toString();  
  135.     }  
  136. }  


Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2.   
  3. <taglib xmlns="http://java.sun.com/xml/ns/j2ee"  
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"  
  6.     version="2.0">  
  7.       
  8.   <description>MyTag 1.0 core</description>  
  9.   <display-name>MyTag core</display-name>  
  10.   <tlib-version>1.0</tlib-version>  
  11.   <short-name>syh</short-name>  
  12.   <uri>http://java.syh.com/jsp/syh/core</uri>  
  13.   
  14.     <tag>  
  15.         <name>token</name>  
  16.         <tag-class>com.syh.servlet.TokenProcessor</tag-class>  
  17.         <body-content>empty</body-content>  
  18.     </tag>  
  19.   
  20.     
  21.   
  22. </taglib>  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值