解决表单重复提交的问题

现象描述

最近在开发的时候,遇见这样的问题,当我们在网络状况不太好的情况、或者一个业务的后台业务逻辑执行时间较长的时候,用户可能会点击多次提交或刷新多次页面,导致表单数据被提交了多次,导致了可能出现莫名其妙的问题,解决这个问题,我们可以使用session加token的方式进行解决。

方案

JSP代码:

<%@ page import="java.util.UUID" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ page contentType="text/html;charset=UTF-8" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>test jsp</title>
</head>
<body>
<%
        String token = UUID.randomUUID().toString().replaceAll("-","");
        session.setAttribute("token",token);
%>

<form id="form1" method="post" action="/user/doSomething.do">
    username : <input type="text" id="username" value=""/>
    password : <input type="text" id="password" value=""/>
    <input type="hidden" name="formtoken" value="<%=token%>" >
    <input type="submit" value="submit"/>
</form>
</body>
</html>

Controller层:

@Controller
@RequestMapping(value="user")
public class UserController {

    @RequestMapping(value="doSomething.do")
    public String doSometing(String username, String password, HttpServletRequest request, RedirectAttributes attr) {
        String formToken = request.getParameter("formtoken");
        HttpSession session = request.getSession();
        String token = (String)session.getAttribute("token");
        if (formToken.equals(token)) {
            session.removeAttribute("token");
        } else {
            attr.addFlashAttribute("msg", "请不要重复提交!");
            return "redirect:error";
        }
    }
}

如果有多个Controller的方法都需要进行校验,可以写一个单独的校验方法,使用@ModelAttribute注解,这样让它在所有方法执行之前执行,校验是否表单重复提交了

@Controller
@RequestMapping(value="user")
public class UserController {

    @ModelAttribute
    public void checkForm(HttpServletRequest request, Model model) {
            String formToken = request.getParameter("formtoken");
            HttpSession session = request.getSession();
            String token = (String)session.getAttribute("token");
            if (formToken.equals(token)) {
                session.removeAttribute("token");
                model.addAttribute("checkResult", "success");
            } else {
                model.addAttribute("checkResult", "fail");
        }
    }   

    @RequestMapping(value="doSomething.do")
    public String doSometing(@ModelAttribute String checkResult, String username, String password, RedirectAttributes attr) {
        if (checkResult != null && checkResult.equals("success")) 
        {
            doSomething(username, password);    
        } else {
            attr.addFlashAttribute("msg","请不要重复提交");
            return "redirect:error";
        }
    }
}

原理

当多次提交的时候,session中的token已经更新,但是form中的token没有变化,因此可以用此进行校验。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值