您的位置:首页 > 编程语言 > Java开发

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

2013-09-10 19:49 344 查看
session 的应用——防止表单重复提交——2.0版(使用了Struts1 中的重复提交组件: TokenProcessor和自定义标签)

Html代码  


<%@ page language="java" contentType="text/html; charset=UTF-8"  

    pageEncoding="UTF-8"%>  

<!-- 这里使用的是自定义标签 -->  

<%@ taglib prefix="syh" uri="http://java.syh.com/jsp/syh/core"%>  

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  

<html>  

<head>  

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  

<title>Insert title here</title>  

  

<script type="text/javascript">  

  

    //点击 "提交" 按钮, 只能点击一次  

    var flag = true;  

      

      

    function token(btn){  

        if(flag){  

            flag = false;  

            return true;  

        }else{  

            alert('已经提交过了');  

        }  

    }  

      

    /*  

    下面的JS代码对 IE 不使用,对于 FF  

    function token2(btn){  

        if(flag){  

            btn.disabled = true;  

            return true;  

        }  

    }  

    */  

      

</script>  

</head>  

<body>  

  

        <!--    

            TokenProcessor.getInstance().saveToken(request)  

              

            1. 生成一个随机字符串, 可以保证其唯一  

            2. 把该字符串放在 Session 域中  

            3. 返回该字符串  

        -->  

          

    <form action="LoginServlet" method="post" id="regForm">  

        <!-- 这里使用的是自定义标签 -->  

        <syh:token/>  

        <table border="1">  

            <tr>  

                <td>Name:</td>  

                <td>  

                    <input type="text" name="name"/>  

                </td>  

            </tr>  

              

            <tr>  

                <td>Password:</td>  

                <td>  

                    <input type="password" name="password"/>  

                </td>  

            </tr>  

              

            <tr rowspan="2">  

                <td>  

                    <input type="submit" value="Submit" onclick="return token2(this);"/>  

                </td>  

                <td>  

                    <input type="reset" value="Reset"/>  

                </td>  

            </tr>  

        </table>  

    </form>  

  

</body>  

</html>  

Html代码  


<%@ page language="java" contentType="text/html; charset=UTF-8"  

    pageEncoding="UTF-8"%>  

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  

<html>  

<head>  

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  

<title>Insert title here</title>  

</head>  

<body>  

  

    注册成功!  

  

</body>  

</html>  

Html代码  


<%@ page language="java" contentType="text/html; charset=UTF-8"  

    pageEncoding="UTF-8"%>  

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  

<html>  

<head>  

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  

<title>Insert title here</title>  

</head>  

<body>  

  

    <h4>表单已经提交!请不要多次提交!</h4>  

  

</body>  

</html>  

Java代码  


package com.syh.servlet;  

  

import java.io.IOException;  

import javax.servlet.ServletException;  

import javax.servlet.http.HttpServlet;  

import javax.servlet.http.HttpServletRequest;  

import javax.servlet.http.HttpServletResponse;  

  

  

public class LoginServlet extends HttpServlet {  

    private static final long serialVersionUID = 1L;  

  

      

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  

            doPost(request, response) ;  

    }  

  

      

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  

          

        try {  

            Thread.sleep(3000) ;  

        } catch (InterruptedException e) {  

            e.printStackTrace();  

        }  

          

        try {  

            //模拟网速  

            Thread.sleep(1000);  

        } catch (InterruptedException e) {  

            e.printStackTrace();  

        }  

          

        //1. 检验 Token 是否可用  

        boolean flag = TokenProcessor.getInstance().isTokenValid(request) ;  

        //2. 去除 Session 中的 Token 标记  

        if(flag) {  

            TokenProcessor.getInstance().resetToken(request) ;  

        }else {  

            System.out.println("重复提交");  

            request.getRequestDispatcher("/error.jsp").forward(request, response) ;  

            return ;  

        }  

          

        String name = request.getParameter("name") ;  

        System.out.println("添加成功-->" + name);  

          

        request.getRequestDispatcher("/success.jsp").forward(request, response) ;  

    }  

  

}  

Java代码  


package com.syh.servlet;  

  

import javax.servlet.http.HttpServletRequest;  

import javax.servlet.http.HttpSession;  

import javax.servlet.jsp.JspException;  

import javax.servlet.jsp.PageContext;  

import javax.servlet.jsp.tagext.SimpleTagSupport;  

  

import java.io.IOException;  

import java.security.MessageDigest;  

import java.security.NoSuchAlgorithmException;  

  

public class TokenProcessor extends SimpleTagSupport{  

      

    @Override  

    public void doTag() throws JspException, IOException {  

  

        PageContext pageContext = (PageContext) getJspContext();  

        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();  

          

        String output = "<input type='hidden' name='" + TOKEN_KEY + "' value='" + saveToken(request) + "'/>";  

        pageContext.getOut().print(output);  

    }  

      

    public static final String TAGLIB_PACKAGE = "org.apache.struts.taglib.html";  

      

    public static final String TRANSACTION_TOKEN_KEY =  

        "org.apache.struts.action.TOKEN";  

      

    public static final String TOKEN_KEY = TAGLIB_PACKAGE + ".TOKEN";  

      

    private static TokenProcessor instance = new TokenProcessor();  

  

    private long previous;  

  

    public TokenProcessor() {  

        super();  

    }  

  

    public static TokenProcessor getInstance() {  

        return instance;  

    }  

  

    public synchronized boolean isTokenValid(HttpServletRequest request) {  

        return this.isTokenValid(request, false);  

    }  

  

    public synchronized boolean isTokenValid(HttpServletRequest request,  

        boolean reset) {  

        // Retrieve the current session for this request  

        HttpSession session = request.getSession(false);  

  

        if (session == null) {  

            return false;  

        }  

  

        String saved =  

            (String) session.getAttribute(TRANSACTION_TOKEN_KEY);  

  

        if (saved == null) {  

            return false;  

        }  

  

        if (reset) {  

            this.resetToken(request);  

        }  

  

        String token = request.getParameter(TOKEN_KEY);  

  

        if (token == null) {  

            return false;  

        }  

  

        return saved.equals(token);  

    }  

  

    public synchronized void resetToken(HttpServletRequest request) {  

        HttpSession session = request.getSession(false);  

  

        if (session == null) {  

            return;  

        }  

  

        session.removeAttribute(TRANSACTION_TOKEN_KEY);  

    }  

  

    public synchronized String saveToken(HttpServletRequest request) {  

        HttpSession session = request.getSession();  

        String token = generateToken(request);  

  

        if (token != null) {  

            session.setAttribute(TRANSACTION_TOKEN_KEY, token);  

        }  

          

        return token;  

    }  

  

    public synchronized String generateToken(HttpServletRequest request) {  

        HttpSession session = request.getSession();  

  

        return generateToken(session.getId());  

    }  

  

    public synchronized String generateToken(String id) {  

        try {  

            long current = System.currentTimeMillis();  

  

            if (current == previous) {  

                current++;  

            }  

  

            previous = current;  

  

            byte[] now = new Long(current).toString().getBytes();  

            MessageDigest md = MessageDigest.getInstance("MD5");  

  

            md.update(id.getBytes());  

            md.update(now);  

  

            return toHex(md.digest());  

        } catch (NoSuchAlgorithmException e) {  

            return null;  

        }  

    }  

  

    private String toHex(byte[] buffer) {  

        StringBuffer sb = new StringBuffer(buffer.length * 2);  

  

        for (int i = 0; i < buffer.length; i++) {  

            sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16));  

            sb.append(Character.forDigit(buffer[i] & 0x0f, 16));  

        }  

  

        return sb.toString();  

    }  

}  

Xml代码  


<?xml version="1.0" encoding="UTF-8" ?>  

  

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"  

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"  

    version="2.0">  

      

  <description>MyTag 1.0 core</description>  

  <display-name>MyTag core</display-name>  

  <tlib-version>1.0</tlib-version>  

  <short-name>syh</short-name>  

  <uri>http://java.syh.com/jsp/syh/core</uri>  

  

    <tag>  

        <name>token</name>  

        <tag-class>com.syh.servlet.TokenProcessor</tag-class>  

        <body-content>empty</body-content>  

    </tag>  

  

    

  

</taglib>  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  表单 struts 重复提交