第一种方法:判断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 防止重复提交表单的两种方法,推荐第二种相关推荐

  1. 求链式线性表的倒数第K项(两种方法,第二种较好)

    求链式线性表的倒数第K项 题目 答案 第一种解法 第二种解法(较好) 注意 题目 答案 第一种解法 这种方法是正常输入,然后将链表逆置,虽然pta是可以通过的(写数组应该都能通过),但明显没有下一种好 ...

  2. php ajax jquery 表单重复提交,jQuery的 $.ajax防止重复提交的两种方法(推荐)

    下面给大家带来两种关于jquery 的ajax防止重复提交的解决方法,具体介绍如下所示: 1.第一种,对于onclick事件触发的的ajax 可以采用如下方法: 即在beforeSend中使点击按钮不 ...

  3. java框架高频面试题2(Spring MVC面试题)

    目录 一.spring MVC介绍 二.什么是spring MVC? 三.介绍下Spring MVC的执行流程 总结:SpringMVC框架的总结(常用注解和三大重点) 常用注解 (1)RestCon ...

  4. Java框架搭建-Maven、Mybatis、Spring MVC整合搭建

    Java框架搭建-Maven.Mybatis.Spring MVC整合搭建 1. 下载eclipse 到网站下载 http://www.eclipse.org/downloads/packages/e ...

  5. Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)...

    Spring MVC 学习总结(九)--Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务) 目录 一.JSON 1.1.概要 1.2.使用ModelAndView ...

  6. jQuery的 $.ajax防止重复提交的两种方法(推荐)

    本文给大家分享两种jquery 的ajax防止重复提交的方法,第一种方法对于onclick事件触发的ajax,在beforeSend中使点击按钮不可用,ajax结果返回后置为可用,第二种利用jquer ...

  7. java的字符串截取函数_java 字符串截取的三种方法(推荐)|chu

    众所周知,java提供了很多字符串截取的方式.下面就来看看大致有几种. 1.split()+正则表达式来进行截取. 将正则传入split().返回的是一个字符串数组类型.不过通过这种方式截取会有很大的 ...

  8. java截取倒数后六位的字符串_java 字符串截取的三种方法(推荐)

    众所周知,java提供了很多字符串截取的方式.下面就来看看大致有几种. 1.split()+正则表达式来进行截取. 将正则传入split().返回的是一个字符串数组类型.不过通过这种方式截取会有很大的 ...

  9. Python中给字典排序的三种方法(有一种你绝对没见过)

    我们经常在计算机等级考试中遇到词频排序的问题,我们一般先通过生成字典的方法,统计词的频次,然后给字典排序.那么如何快速地给字典按照键值进行排序呢?下面介绍三种方法.第一种方法相对比较常见,但是第二种方 ...

最新文章

  1. 转Linux环境下段错误的产生原因及调试方法小结
  2. 从web.xml谈谈SpringMVC集成spring的初始化流程及SpringBoot集成SpringMVC
  3. IM设计思考:XMPP多用户文本聊天协议(MUC:Multi User Chat)
  4. Apoll进阶课程㉞丨Apollo ROS原理—3
  5. HTML引用外部css 、js的路径
  6. 小程序入门学习14--用户管理
  7. 共享内存+互斥量实现 Linux 进程间通信
  8. SQL2000和SQL2005同时安装问题(转载)
  9. 浅谈Java程序员的黄金五年,如何实现快速进阶
  10. 统一建模语言(UML)介绍和使用
  11. 硅谷真假u盘测试软件,硅谷硅谷真假u盘测试
  12. 获取百度网盘直链下载链接的方法
  13. google浏览器呗7654流氓解除
  14. 方法重写的两同两小一大原则
  15. 华为BBU3900学习
  16. Python格式化输出 %s %d %f
  17. 画火柴人动画的手机软件_火柴人动画制作软件(Pivot Stickfigure Animator)2.25 中文版附教程...
  18. 【C++】(十五)自定义数据类型——共用体类型、枚举类型
  19. 首款产后抑郁药问世;京东推出城市操作系统;阿里将推出全新销售平台;香港政府砸5300亿填海;脸书再爆隐私丑闻;这就是今天的大新闻...
  20. Linux Bash常用的脚本工具整理

热门文章

  1. 网管型工业以太网交换机的几种管理方式
  2. 【渝粤教育】国家开放大学2018年春季 0062-22T港台文学专题讲座 参考试题
  3. matlab eig 复杂度,MATLAB中的eig函数
  4. 使用java自带的日志管理_java日志管理
  5. html用c 绑定sql,HTML、SQL、C++及C综合测试六(含答案).pdf
  6. idea中maven执行install报错_IntelliJ IDEA Maven编译install时报错,无效的发行版:1.8
  7. 开发转测试没人要_前端开发,测试,后端,该如何选择?
  8. Atitit各种SDM 软件开发过程SDP sdm的ddd tdd bdd设计
  9. 自动计算尺寸列表功能案例ios源码
  10. USB描述符【整理】