java mvc中重复提交表单,spring mvc 防止重复提交表单的两种方法,推荐第二种
第一种方法:判断session中保存的token
比较麻烦,每次在提交表单时都必须传入上次的token。而且当一个页面使用ajax时,多个表单提交就会有问题。
注解Token代码:
package com.thinkgem.jeesite.common.repeat_form_validator;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 页面form token
* @author Administrator
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FormToken {
boolean save() default false;
boolean remove() default false;
}
拦截器TokenInterceptor代码:
package com.thinkgem.jeesite.common.repeat_form_validator;
import java.lang.reflect.Method;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class FormTokenInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
FormToken annotation = method.getAnnotation(FormToken.class);
if (annotation != null) {
boolean needSaveSession = annotation.save();
if (needSaveSession) {
request.getSession(false).setAttribute("formToken", UUID.randomUUID().toString());
}
boolean needRemoveSession = annotation.remove();
if (needRemoveSession) {
if (isRepeatSubmit(request)) {
return false;
}
request.getSession(false).removeAttribute("formToken");
}
}
return true;
} else {
return super.preHandle(request, response, handler);
}
}
private boolean isRepeatSubmit(HttpServletRequest request) {
String serverToken = (String) request.getSession(false).getAttribute("formToken");
if (serverToken == null) {
return true;
}
String clinetToken = request.getParameter("formToken");
if (clinetToken == null) {
return true;
}
if (!serverToken.equals(clinetToken)) {
return true;
}
return false;
}
}
然后在Spring MVC的配置文件里加入:
相关代码已经注释,相信你能看懂。
关于这个方法的用法是:在需要生成token的controller上增加@FormToken(save=true),而在需要检查重复提交的controller上添加@FormToken(remove=true)就可以了。
另外,你需要在view里在form里增加下面代码:
已经完成了,去试试看你的数据还能重复提交了吧。
注意在ajax提交时 要加上 formToken参数
第二种方法(判断请求url和数据是否和上一次相同)
推荐,非常简单,页面不需要任何传入,只需要在验证的controller方法上写上自定义注解即可
写好自定义注解
package com.thinkgem.jeesite.common.repeat_form_validator;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 一个用户 相同url 同时提交 相同数据 验证
* @author Administrator
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SameUrlData {
}
写好拦截器
package com.thinkgem.jeesite.common.repeat_form_validator;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.thinkgem.jeesite.common.mapper.JsonMapper;
/**
* 一个用户 相同url 同时提交 相同数据 验证
* 主要通过 session中保存到的url 和 请求参数。如果和上次相同,则是重复提交表单
* @author Administrator
*
*/
public class SameUrlDataInterceptor extends HandlerInterceptorAdapter{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
SameUrlData annotation = method.getAnnotation(SameUrlData.class);
if (annotation != null) {
if(repeatDataValidator(request))//如果重复相同数据
return false;
else
return true;
}
return true;
} else {
return super.preHandle(request, response, handler);
}
}
/**
* 验证同一个url数据是否相同提交 ,相同返回true
* @param httpServletRequest
* @return
*/
public boolean repeatDataValidator(HttpServletRequest httpServletRequest)
{
String params=JsonMapper.toJsonString(httpServletRequest.getParameterMap());
String url=httpServletRequest.getRequestURI();
Map map=new HashMap();
map.put(url, params);
String nowUrlParams=map.toString();//
Object preUrlParams=httpServletRequest.getSession().getAttribute("repeatData");
if(preUrlParams==null)//如果上一个数据为null,表示还没有访问页面
{
httpServletRequest.getSession().setAttribute("repeatData", nowUrlParams);
return false;
}
else//否则,已经访问过页面
{
if(preUrlParams.toString().equals(nowUrlParams))//如果上次url+数据和本次url+数据相同,则表示城府添加数据
{
return true;
}
else//如果上次 url+数据 和本次url加数据不同,则不是重复提交
{
httpServletRequest.getSession().setAttribute("repeatData", nowUrlParams);
return false;
}
}
}
}
配置spring mvc
java mvc中重复提交表单,spring mvc 防止重复提交表单的两种方法,推荐第二种相关推荐
- 求链式线性表的倒数第K项(两种方法,第二种较好)
求链式线性表的倒数第K项 题目 答案 第一种解法 第二种解法(较好) 注意 题目 答案 第一种解法 这种方法是正常输入,然后将链表逆置,虽然pta是可以通过的(写数组应该都能通过),但明显没有下一种好 ...
- php ajax jquery 表单重复提交,jQuery的 $.ajax防止重复提交的两种方法(推荐)
下面给大家带来两种关于jquery 的ajax防止重复提交的解决方法,具体介绍如下所示: 1.第一种,对于onclick事件触发的的ajax 可以采用如下方法: 即在beforeSend中使点击按钮不 ...
- java框架高频面试题2(Spring MVC面试题)
目录 一.spring MVC介绍 二.什么是spring MVC? 三.介绍下Spring MVC的执行流程 总结:SpringMVC框架的总结(常用注解和三大重点) 常用注解 (1)RestCon ...
- Java框架搭建-Maven、Mybatis、Spring MVC整合搭建
Java框架搭建-Maven.Mybatis.Spring MVC整合搭建 1. 下载eclipse 到网站下载 http://www.eclipse.org/downloads/packages/e ...
- Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)...
Spring MVC 学习总结(九)--Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务) 目录 一.JSON 1.1.概要 1.2.使用ModelAndView ...
- jQuery的 $.ajax防止重复提交的两种方法(推荐)
本文给大家分享两种jquery 的ajax防止重复提交的方法,第一种方法对于onclick事件触发的ajax,在beforeSend中使点击按钮不可用,ajax结果返回后置为可用,第二种利用jquer ...
- java的字符串截取函数_java 字符串截取的三种方法(推荐)|chu
众所周知,java提供了很多字符串截取的方式.下面就来看看大致有几种. 1.split()+正则表达式来进行截取. 将正则传入split().返回的是一个字符串数组类型.不过通过这种方式截取会有很大的 ...
- java截取倒数后六位的字符串_java 字符串截取的三种方法(推荐)
众所周知,java提供了很多字符串截取的方式.下面就来看看大致有几种. 1.split()+正则表达式来进行截取. 将正则传入split().返回的是一个字符串数组类型.不过通过这种方式截取会有很大的 ...
- Python中给字典排序的三种方法(有一种你绝对没见过)
我们经常在计算机等级考试中遇到词频排序的问题,我们一般先通过生成字典的方法,统计词的频次,然后给字典排序.那么如何快速地给字典按照键值进行排序呢?下面介绍三种方法.第一种方法相对比较常见,但是第二种方 ...
最新文章
- 转Linux环境下段错误的产生原因及调试方法小结
- 从web.xml谈谈SpringMVC集成spring的初始化流程及SpringBoot集成SpringMVC
- IM设计思考:XMPP多用户文本聊天协议(MUC:Multi User Chat)
- Apoll进阶课程㉞丨Apollo ROS原理—3
- HTML引用外部css 、js的路径
- 小程序入门学习14--用户管理
- 共享内存+互斥量实现 Linux 进程间通信
- SQL2000和SQL2005同时安装问题(转载)
- 浅谈Java程序员的黄金五年,如何实现快速进阶
- 统一建模语言(UML)介绍和使用
- 硅谷真假u盘测试软件,硅谷硅谷真假u盘测试
- 获取百度网盘直链下载链接的方法
- google浏览器呗7654流氓解除
- 方法重写的两同两小一大原则
- 华为BBU3900学习
- Python格式化输出 %s %d %f
- 画火柴人动画的手机软件_火柴人动画制作软件(Pivot Stickfigure Animator)2.25 中文版附教程...
- 【C++】(十五)自定义数据类型——共用体类型、枚举类型
- 首款产后抑郁药问世;京东推出城市操作系统;阿里将推出全新销售平台;香港政府砸5300亿填海;脸书再爆隐私丑闻;这就是今天的大新闻...
- Linux Bash常用的脚本工具整理
热门文章
- 网管型工业以太网交换机的几种管理方式
- 【渝粤教育】国家开放大学2018年春季 0062-22T港台文学专题讲座 参考试题
- matlab eig 复杂度,MATLAB中的eig函数
- 使用java自带的日志管理_java日志管理
- html用c 绑定sql,HTML、SQL、C++及C综合测试六(含答案).pdf
- idea中maven执行install报错_IntelliJ IDEA Maven编译install时报错,无效的发行版:1.8
- 开发转测试没人要_前端开发,测试,后端,该如何选择?
- Atitit各种SDM 软件开发过程SDP sdm的ddd tdd bdd设计
- 自动计算尺寸列表功能案例ios源码
- USB描述符【整理】