表单重复提交问题解决办法

一、出现表单重复提交的原因

(1)网络延迟
(2)重新加载
(3)回退之后又返回之前页面进行提交

二、解决问题的办法

(1)从前台解决:

   1)控制提交事件只触发一次

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


  
    Form表单
  
  
  
      
用户名:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/saveServlet")
public class test extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("数据插入数据库操作");
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().println("保存成功");
    }
}

  2)点击事件发生后,提交按钮失效

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


  
    Form表单
  
  
  
      
用户名:

(2)从后台解决(原理)

使用token

package cache;

import java.util.UUID;

public class TokenUtils {
    public static String getToken(){
        return UUID.randomUUID().toString();
    }
}

先访问一个拦截器的servlet,然后它跳转到表单页面,正常的话应该是访问表单页面进入拦截器,这里简单模拟过程

package cache;

import org.apache.commons.lang3.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/formServlet")
public class FormServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String token = TokenUtils.getToken();
        HttpSession session = req.getSession();
        session.setAttribute("token",token);
        req.getRequestDispatcher("form2.jsp").forward(req,resp);
    }
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>


  
    Form表单
  
  
  
      
用户名:

 

package com.sun;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/saveServlet")
public class Test extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        boolean result = checkIsRepeatSubmit(req);
        if (result){
            System.out.println("重复提交");
            resp.getWriter().println("重复提交");
            return;
        }
        String username = req.getParameter("username");
        System.out.println("数据插入数据库操作");
        resp.getWriter().println("保存成功");
        req.getSession().removeAttribute("token");
    }

    private static boolean checkIsRepeatSubmit(HttpServletRequest req){
        String reqToken = req.getParameter("token");
        if(null == reqToken){
            return true;
        }
        HttpSession session = req.getSession(false);
        String token = (String) session.getAttribute("token");
        //如果session里面的token空了,这个请求还进来了,说明是重复提交
        if(null == token){
            return true;
        }
        //判断是否伪造token
        if (!(reqToken.equals(token))){
            return true;
        }
        return false;

    }
}

总结:

1)做了个小实验,前台如果没有防止重复提交的操作,只在后台防止,连续点击提交按钮会重复提交的情景还是存在,但是

重新加载和后退返回的情景出现重复提交的问题解决了

2)开发中应该前后台都进行处理,才能完全防止重复提交的问题出现

 

参考:https://www.cnblogs.com/myseries/p/10802079.html

https://blog.csdn.net/chichuhanga/article/details/79192831

你可能感兴趣的:(开发经验)