SpringMVC实现防止重复提交表单的方法详解

 更新时间:2025年06月11日 08:10:00   作者:牛肉胡辣汤  
在Web开发中,防止表单重复提交是一个常见的需求,本文将介绍几种在SpringMVC框架中防止表单重复提交的有效方法,有需要的小伙伴可以了解下

在Web开发中,防止表单重复提交是一个常见的需求。用户可能因为网络延迟、页面刷新或多次点击提交按钮等原因,导致同一个表单被多次提交,这可能会引发数据不一致或其他问题。本文将介绍几种在SpringMVC框架中防止表单重复提交的有效方法。

1. 使用Token机制

原理

Token机制是防止表单重复提交的一种常用方法。服务器生成一个唯一的Token,并将其嵌入到表单中。当用户提交表单时,这个Token会被一起发送到服务器。服务器端会验证这个Token的有效性,如果有效则处理请求并删除或标记该Token为已使用;如果无效,则拒绝请求。

实现步骤

  • 生成Token:在用户访问表单页面时,服务器生成一个唯一的Token,并存储在Session中。
  • 嵌入Token:将生成的Token嵌入到表单的隐藏字段中。
  • 验证Token:在表单提交时,服务器端验证表单中的Token是否与Session中的Token一致,且未被使用过。
  • 处理Token:如果Token验证通过,处理表单数据,并从Session中移除或标记该Token为已使用。

示例代码

控制器

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
 
import javax.servlet.http.HttpSession;
import java.util.UUID;
 
@Controller
public class FormController {
 
    @GetMapping("/form")
    public String showForm(HttpSession session, Model model) {
        String token = UUID.randomUUID().toString();
        session.setAttribute("token", token);
        model.addAttribute("token", token);
        return "form";
    }
 
    @PostMapping("/submit")
    public String submitForm(@RequestParam("token") String token, HttpSession session) {
        String sessionToken = (String) session.getAttribute("token");
        if (sessionToken != null && sessionToken.equals(token)) {
            session.removeAttribute("token");
            // 处理表单数据
            return "success";
        } else {
            return "error";
        }
    }
}

表单页面(form.html)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Form</title>
</head>
<body>
<form th:action="@{/submit}" method="post">
    <input type="hidden" name="token" th:value="${token}">
    <label for="name">Name:</label>
    <input type="text" id="name" name="name">
    <button type="submit">Submit</button>
</form>
</body>
</html>

2. 使用JavaScript禁用提交按钮

原理

通过JavaScript在用户点击提交按钮后立即禁用该按钮,防止用户多次点击提交。

实现步骤

添加JavaScript代码:在表单页面中添加JavaScript代码,监听提交按钮的点击事件。

禁用按钮:在点击事件中禁用提交按钮。

示例代码

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Form</title>
    <script>
        function disableButton() {
            document.getElementById('submitBtn').disabled = true;
        }
    </script>
</head>
<body>
<form th:action="@{/submit}" method="post" onsubmit="disableButton()">
    <label for="name">Name:</label>
    <input type="text" id="name" name="name">
    <button type="submit" id="submitBtn">Submit</button>
</form>
</body>
</html>

3. 使用SpringMVC的​​@SessionAttributes​​注解

原理

通过​​@SessionAttributes​​注解将表单数据存储在Session中,每次提交表单时检查Session中是否存在该数据,如果存在则拒绝处理。

实现步骤

标注控制器:在控制器类上使用​​@SessionAttributes​​注解,指定需要存储在Session中的属性。

检查Session:在处理表单提交的方法中,检查Session中是否已经存在该属性。

示例代码

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
 
@Controller
@SessionAttributes("formData")
public class FormController {
 
    @GetMapping("/form")
    public String showForm(Model model) {
        model.addAttribute("formData", new FormData());
        return "form";
    }
 
    @PostMapping("/submit")
    public String submitForm(FormData formData, BindingResult result, Model model) {
        if (model.containsAttribute("formData")) {
            // 表单数据已存在,拒绝处理
            return "error";
        }
        // 处理表单数据
        model.addAttribute("formData", formData);
        return "success";
    }
}
 
class FormData {
    private String name;
 
    // getters and setters
}

4.方法补充

防止表单重复提交是Web开发中一个重要的问题,本文介绍了三种在SpringMVC框架中实现这一功能的方法:

  • 使用Token机制。
  • 使用JavaScript禁用提交按钮。
  • 使用SpringMVC的​​@SessionAttributes​​注解。

在Web开发中,防止表单重复提交是一个常见的需求,尤其是在处理敏感操作如订单提交、用户注册等场景时尤为重要。Spring MVC提供了多种方法来防止表单重复提交,下面我将介绍几种常用的方法,并提供相应的示例代码。

方法一:使用Token(令牌)

生成Token:在用户访问表单页面时生成一个唯一的Token,并将其存储在Session中。

验证Token:在表单提交时,将Token作为隐藏字段传递到服务器端进行验证,如果验证通过,则处理表单数据并从Session中移除该Token;如果验证不通过或Token已不存在,则拒绝处理表单数据。

示例代码

Controller代码:

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
 
import javax.servlet.http.HttpSession;
import java.util.UUID;
 
@Controller
public class FormController {
 
    @GetMapping("/form")
    public String showForm(Model model, HttpSession session) {
        // 生成Token
        String token = UUID.randomUUID().toString();
        session.setAttribute("token", token);
        model.addAttribute("token", token);
        return "form";
    }
 
    @PostMapping("/submit")
    public String submitForm(@RequestParam("token") String clientToken, HttpSession session) {
        // 获取Session中的Token
        String serverToken = (String) session.getAttribute("token");
        
        if (serverToken != null && serverToken.equals(clientToken)) {
            // Token验证通过,处理表单逻辑
            // 处理完成后移除Token
            session.removeAttribute("token");
            return "success";
        } else {
            // Token验证失败,提示错误信息
            return "error";
        }
    }
}

form.html (Thymeleaf模板):

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Form</title>
</head>
<body>
<form th:action="@{/submit}" method="post">
    <input type="hidden" name="token" th:value="${token}"/>
    <label for="username">Username:</label>
    <input type="text" id="username" name="username" required/>
    <br/>
    <label for="password">Password:</label>
    <input type="password" id="password" name="password" required/>
    <br/>
    <button type="submit">Submit</button>
</form>
</body>
</html>

方法二:使用重定向

另一种简单有效的方法是在处理完表单后使用重定向,这样可以避免用户刷新页面导致的重复提交问题。

示例代码

Controller代码:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
@Controller
public class FormController {
 
    @GetMapping("/form")
    public String showForm() {
        return "form";
    }
 
    @PostMapping("/submit")
    public String submitForm(RedirectAttributes redirectAttributes) {
        // 处理表单逻辑
        // ...
 
        // 添加成功消息
        redirectAttributes.addFlashAttribute("message", "Form submitted successfully!");
        return "redirect:/result";
    }
 
    @GetMapping("/result")
    public String showResult() {
        return "result";
    }
}

form.html (Thymeleaf模板):

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Form</title>
</head>
<body>
<form th:action="@{/submit}" method="post">
    <label for="username">Username:</label>
    <input type="text" id="username" name="username" required/>
    <br/>
    <label for="password">Password:</label>
    <input type="password" id="password" name="password" required/>
    <br/>
    <button type="submit">Submit</button>
</form>
</body>
</html>

result.html (Thymeleaf模板):

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Result</title>
</head>
<body>
<h1 th:text="${message}"></h1>
<a href="/form" rel="external nofollow" >Back to form</a>
</body>
</html>

这两种方法都可以有效地防止表单重复提交,具体选择哪种方法可以根据实际需求和项目复杂度来决定。

在Web开发中,防止用户重复提交表单是一个常见的需求,尤其是在处理诸如订单、支付等关键操作时。Spring MVC框架提供了几种有效的方法来防止表单的重复提交,包括使用Token机制、重定向策略以及JavaScript前端控制等。下面我将详细介绍这些方法及其代码实现。

1. 使用Token机制

原理:在用户访问页面时生成一个唯一的Token,并将其存储在服务器端(如Session)和客户端(如隐藏字段)。当用户提交表单时,服务端会验证这个Token的有效性。如果Token有效,则处理表单并删除或更新该Token;如果无效,则拒绝处理。

实现步骤:

生成Token: 在Controller中生成Token,并将其添加到Model中以便在视图中使用。

@GetMapping("/form")
public String showForm(Model model, HttpSession session) {
    String token = UUID.randomUUID().toString();
    session.setAttribute("token", token);
    model.addAttribute("token", token);
    return "form";
}

表单页面: 在表单中包含一个隐藏的Token字段。

<form action="/submit" method="post">
    <input type="hidden" name="token" value="${token}">
    <!-- 其他表单字段 -->
    <button type="submit">Submit</button>
</form>

验证Token: 在处理表单提交的Controller方法中验证Token。

@PostMapping("/submit")
public String handleForm(@RequestParam String token, HttpSession session) {
    String sessionToken = (String) session.getAttribute("token");
    if (sessionToken != null && sessionToken.equals(token)) {
        // 处理表单逻辑
        session.removeAttribute("token"); // 防止重复提交
        return "success";
    } else {
        return "error"; // Token无效或已过期
    }
}

2. 使用重定向策略

原理:在处理完表单提交后,通过重定向到另一个页面来避免用户刷新页面导致的重复提交。

实现步骤:

处理表单提交: 在处理完表单逻辑后,重定向到成功页面。

@PostMapping("/submit")
public String handleForm(/* 表单参数 */) {
    // 处理表单逻辑
    return "redirect:/success";
}

成功页面: 显示成功信息的页面。

@GetMapping("/success")
public String success() {
    return "success";
}

3. 使用JavaScript前端控制

原理:在用户点击提交按钮时,通过JavaScript禁用提交按钮,防止用户多次点击。

实现步骤:

表单页面: 添加JavaScript代码来禁用提交按钮。

<form id="myForm" action="/submit" method="post">
    <!-- 表单字段 -->
    <button type="submit" id="submitButton">Submit</button>
</form>
 
<script>
document.getElementById('myForm').addEventListener('submit', function() {
    document.getElementById('submitButton').disabled = true;
});
</script>

总结

以上三种方法都可以有效地防止表单的重复提交,具体选择哪种方法取决于你的应用场景和需求。Token机制是最常用且最安全的方法,重定向策略简单有效,而JavaScript前端控制则可以提供更好的用户体验。在实际开发中,通常会结合多种方法来确保系统的健壮性和安全性。

到此这篇关于SpringMVC实现防止重复提交表单的方法详解的文章就介绍到这了,更多相关SpringMVC防止重复提交表单内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Java接收和处理OpenTelemetry数据的完整指南

    使用Java接收和处理OpenTelemetry数据的完整指南

    在现代分布式系统中,OpenTelemetry 成为了一种常见的标准,用于跟踪和监控应用程序的性能和行为,OTLP是 OpenTelemetry 社区定义的一种数据传输协议,文将介绍如何使用 Java 编写代码来接收和处理 OTLP 数据,需要的朋友可以参考下
    2024-04-04
  • 浅谈SpringBoot如何正确拦截thymeleaf异常

    浅谈SpringBoot如何正确拦截thymeleaf异常

    Thymeleaf是一个模板引擎工具,主要用于页面渲染操作,本文主要介绍了浅谈SpringBoot如何正确拦截thymeleaf异常,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • Java学生信息管理系统设计(数据库版)

    Java学生信息管理系统设计(数据库版)

    这篇文章主要为大家详细介绍了数据库版的Java学生信息管理系统设计,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • 十个最常见的Java字符串问题(翻译)

    十个最常见的Java字符串问题(翻译)

    这篇文章主要介绍了十个最常见的Java字符串问题(翻译),需要的朋友可以参考下
    2015-03-03
  • Java实现解析Excel复杂表头

    Java实现解析Excel复杂表头

    这篇文章主要为大家详细介绍了如何使用Java实现解析Excel复杂表头功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-01-01
  • Java开启新线程并传参方法代码实现

    Java开启新线程并传参方法代码实现

    这篇文章主要介绍了Java开启新线程并传参方法代码实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • eclipse如何搭建Springboot项目详解

    eclipse如何搭建Springboot项目详解

    今天带大家学习eclipse如何搭建Spring boot项目,文中有非常详细的图文解说,对正在学习java的小伙伴们有很好地帮助,需要的朋友可以参考下
    2021-05-05
  • Mybatis表的关联查询详情

    Mybatis表的关联查询详情

    这篇文章主要介绍了Mybatis表的关联查询详情,文章通过围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • java获取微信accessToken的方法

    java获取微信accessToken的方法

    这篇文章主要为大家详细介绍了java获取微信accessToken的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • Java 多线程有序执行的几种方法总结

    Java 多线程有序执行的几种方法总结

    这篇文章主要介绍了Java 多线程有序执行的几种方法总结的相关资料,需要的朋友可以参考下
    2017-03-03

最新评论