zoukankan      html  css  js  c++  java
  • JavaWeb_HttpSession之表单的重复提交

    表单的重复提交

    1)重复提交的情况

    1>在表单提交到一个Servlet,而Servlet又通过请求转发的方式响应了一个JSP(HTML)页面,此时地址栏还保留着Servlet的那个路径,在响应页面点击“刷新”。

    2>在响应页面没有到达时重复点击“提交按钮”

    3>点击“返回”,再点击“提交”

    2)不是重复提交的情况

    1>点击“返回”,“刷新”原表单页面,再“提交”

    3)如何避免表单的重复提交

    1>在表单中做一个标记,提交到Servlet时,检查标记是否存在且是否和预定义的标记一致,若一致,则受理请求,并销毁标记,若不一致或没有标记,则直接响应提示信息:“重复提交”

    (1)仅提供一个隐藏域:<input type="hidden" name="token" value="YHS"/>行不通:没有办法清除固定的请求参数。

    (2)把标记放在request中,行不通,因为表单页面刷新后,request已经被销毁,再提交表单是一个新的request。

    (3)把标记放在session中,可以!

      >在原表单页面,生成一个随机值token

      >在原表单页面,把token值放入session属性中

      >在原表单页面,把token值放入隐藏域中。

    ——提交表单

      >在目标的servlet中:获取session和隐藏域中的token值

      >比较两个值是否一致:若一致,受理请求,且把session域中的token属性清除

      >若不一致,则直接响应提示页面:"重复提交"

    原理:在原表单页面,创建一个session属性,和隐藏域,两个值开始时是一个相同的随机值,当进入servlet中比较两个值是否相同,相同删除session属性。

    login.jsp

    单击提交表单

     

    点击返回,点击提交表单。

    刷新原表单页面,连续点击提交

    源码:

    login.jsp

    <%@ page import="java.util.Date" %><%--
      Created by IntelliJ IDEA.
      User: dell
      Date: 2019/7/11
      Time: 16:05
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <%
        String tokenValue = new Date().getTime() + "";
        session.setAttribute("token",tokenValue);
    %>
    <form action="<%= request.getContextPath()%>/TokenServlet" method="post">
        <input type="hidden" name="token" value="<%= tokenValue%>">
        name: <input type="text" name="name">
        <input type="submit" value="Submit">
    </form>
    </body>
    </html>
    

    tokenservlet

    package com.demo.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    public class TokenServlet extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            HttpSession session = req.getSession();
    
            Object token = session.getAttribute("token");
            String tokenValue = req.getParameter("token");
            System.out.println(token);
            System.out.println(tokenValue);
    
    
            if (token!=null&&token.equals(tokenValue)){
                session.removeAttribute("token");
            }else{
                resp.sendRedirect(req.getContextPath()+"/stoken/error.jsp");
                return;
            }
            String name = req.getParameter("name");
            System.out.println("name: " +name);
            resp.sendRedirect(req.getContextPath()+"/stoken/success.jsp");
        }
    }
  • 相关阅读:
    Hash工具下载地址
    微信聊天记录查看器(程序+源码)
    XEN的启动信息输出到“Platform timer is 14.318MHz HPET”就暂停接收的解决办法
    利用 Serial Over Lan(SOL)搭建 XEN 的调试信息输出环境
    Windows内核开发中如何区分文件对象究竟是文件还是文件夹?
    白盒密码入门
    选择Asp for javascript,非.net。
    8个你至少应该参加一次的极客盛会
    程序员的四种类型
    超棒的30款JS类库和工具
  • 原文地址:https://www.cnblogs.com/yangHS/p/11170891.html
Copyright © 2011-2022 走看看