首页 > 其他分享 >解决表单重复提交问题

解决表单重复提交问题

时间:2022-11-01 12:33:35浏览次数:71  
标签:重复 spring springframework 表单 version 提交 import org LOGGER


分享知识 传递快乐

 

防止表单重复提交有多种,经常用到的有两种:

 

一种是Token(令牌),这种可以用于from表单,但用于ajax就有点力不从心了;

另一种是对请求的url和参数验证,如果一样就不提交,否则提交(推荐)。

 

代码如下:

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xh.token</groupId>
<artifactId>prevent-resubmit</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>prevent-resubmit Maven Webapp</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
<spring.version>4.3.13.RELEASE</spring.version>
<fastjson.version>1.2.46</fastjson.version>
<log4j.version>1.2.17</log4j.version>
<slf4j.version>1.7.25</slf4j.version>
<servlet.version>3.1.0</servlet.version>
<ehcache.version>2.6.11</ehcache.version>
<jackson.version>2.9.0</jackson.version>
</properties>


<dependencies>
<!-- 通用包 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>

<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>


<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>


<!--日志 start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>

<!-- servlet 如果用不到jsp个人认为没必要引用 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<!-- ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>${ehcache.version}</version>
</dependency>

<!-- jackson begin -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>

</dependencies>

<build>
<finalName>prevent-resubmit</finalName>
</build>
</project>

 

java核心代码:

 

SameUrlDataInterceptor

package com.xh.token.commons.same;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSON;

/**
* <p>Title: 一个用户 相同url 同时提交 相同数据 验证 主要通过 session中保存到的url 和 请求参数。如果和上次相同,则是重复提交表单 </p>
* <p>Description: </p>
*
* @author H.Yang
* @QQ 1033542070
* @date 2018年3月7日
*/
public class SameUrlDataInterceptor extends HandlerInterceptorAdapter {

private final Logger LOGGER = LogManager.getLogger(getClass());
private static HttpSession session = null;

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
session = request.getSession();
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
SameUrlData annotation = method.getAnnotation(SameUrlData.class);

// LOGGER.info("annotation=" + annotation);

if (annotation != null) {
// 如果重复相同数据
if (repeatDataValidator(request)) {
// 重定向到登录页面
// LOGGER.info("请求地址:" + session.getAttribute("oldUrl"));
response.sendRedirect(request.getContextPath() +session.getAttribute("oldUrl"));
session.removeAttribute("oldUrl");
session.removeAttribute("repeatData");
return false;
} else {
return true;
}
}
// LOGGER.info("保存请求地址:" + request.getServletPath());
session.setAttribute("oldUrl", request.getServletPath());
return true;
} else {
// LOGGER.info("handler=" + handler);
return super.preHandle(request, response, handler);
}
}

/**
* 验证同一个url数据是否相同提交 ,相同返回true
* @param request
* @return
*/
public boolean repeatDataValidator(HttpServletRequest request) {
String params = JSON.toJSONString(request.getParameterMap());
// LOGGER.info("params=" + params);
String url = request.getRequestURI();
// LOGGER.info("url=" + url);
Map<String, String> map = new HashMap<String, String>();
map.put(url, params);
String nowUrlParams = map.toString();//

Object preUrlParams = session.getAttribute("repeatData");
// 如果上一个数据为null,表示还没有访问页面
if (preUrlParams == null) {
LOGGER.info("未提交数据");
session.setAttribute("repeatData", nowUrlParams);
return false;
} else {
// 否则,已经访问过页面
// 如果上次url+数据和本次url+数据相同,则表示城府添加数据
if (preUrlParams.toString().equals(nowUrlParams)) {
LOGGER.info("已经提交数据 ");
return true;
} else {
LOGGER.info("两次提交的数据不一至,可以提交");
// 如果上次 url+数据 和本次url加数据不同,则不是重复提交
session.setAttribute("repeatData", nowUrlParams);
return false;
}

}
}
}

 

controller

package com.xh.token.controller;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import com.xh.token.commons.same.SameUrlData;

@Controller
public class LoginController {

// 控制器本来就是单例,这样似乎更加合理
private final Logger LOGGER = LogManager.getLogger(getClass());

@GetMapping("/login")
public String login() {
LOGGER.info("GET请求登录");
return "login";
}

@PostMapping("/login2")
@SameUrlData
public String login(HttpServletRequest request, String name, String password) {
LOGGER.info("from请求如下:name=" + name + "\t password=" + password);

try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "redirect:/login";
}

}

 

 

 

源码:​​点击打开链接​

 

标签:重复,spring,springframework,表单,version,提交,import,org,LOGGER
From: https://blog.51cto.com/u_15856116/5813287

相关文章

  • 解决layui表单ajax提交回调函数不起作用问题的两种方式
    最近想用layui开发一个论坛模板用的是fly-ui,才接触layui对其还不太熟悉。一个简单的登录就困扰了我很久。登录的form通过ajax提交回调函数老是不起作用。经过浪费了N多时间......
  • git提交指定文件 git add git commit git stash pop
    git提交指定文件gitaddgitcommitgitstashpopgit提交指定文件,如果此时修改了其他代码,可先提交指定代码,然后忽略不想提交的代码,最后push之后,恢复之前忽略的代码......
  • 使用Vue框架修改表单数据回显失败的一种情况
    今天在完成项目的某个模块的修改业务时,数据没有回显在表单里js文件constdefaultForm={processNo:'',name:'',reasons:'',overtimeStart:'',overti......
  • 26. 删除有序数组中的重复项
    给你一个升序排列的数组nums,请你原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。元素的相对顺序应该保持一致。由于在某些语言中不能改......
  • JS正则RegExp.test()使用注意事项(不具有重复性)
    参考来源:https://www.jb51.net/article/101466.htm本文实例分析了JS正则RegExp.test()使用注意事项。分享给大家供大家参考,具体如下:先看下面这段代码://2012-12-121......
  • html-表单
    <!--form定义表单域,将其范围内的表单元素提交给服务器--><formaction="demo.php"method="get">  <h3>表单元素</h3>  <h2>input</h2>  <!--text文本......
  • sqlserver 分区函数去重复排序
     sqlserver分区函数去重复排序--获取,FlowID去重复的,按时间排序的,前一行select*from(select*,row_number()over(partitionbyFlowIDorderbyConfirmDat......
  • 宜搭自定义表单中的表格,添加数据源变量
    在数据源处添加的变量是全局变量,可以作为中间值完成后台和前端的数据传递。具体:通过添加“远程变量”,获得后台数据赋值给全局变量用“:”,键和值的格式,表格组件添加数据源来......
  • sqlserver 根据多个字段查询重复数据
     sqlserver根据多个字段查询重复数据如:表a abcdef 121231121231121232121232表中每个字段只要有一个不一样就算不重复 selecta,b,......
  • IDEA中的Cherry-Pick的使用及分支提交记录的合并
    什么是 cherry-pickhttps://blog.csdn.net/GBS20200720/article/details/123840359前言这里的cherry-pick指的是git的命令,cherry-pick这个命令的作用就是把指定的commi......