这篇博文介绍第一种方法:判断session或其他缓存中保存的token,这里以session为例,具体大家也可以自行扩展以其他的缓存实现。

这种方式比较麻烦,每次在提交表单时都必须传入上次的token。而且当一个页面使用ajax时,多个表单提交就会有问题。

1、自定义注解FormToken

注解的作用主要是用来标识哪些类需要被拦截,处理防重复提交的问题,具体代码如下:

package io.mykit.filter.spring.repeat.annotation;

import java.lang.annotation.Documented;

import java.lang.annotation.ElementType;

import java.lang.annotation.Inherited;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

* 以Token注解形式方式重复提交内容

* @author liuyazhuang

*

*/

@Inherited

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface FormToken {

boolean save() default false;

boolean remove() default false;

}

2、创建拦截器类FormTokenInterceptor

这个类主要是对标识了@FormToken的方法进行拦截,并且按照相应的规则进行处理,FormTokenInterceptor不进行具体的规则处理,具体规则交由子类实现。具体代码如下:

package io.mykit.filter.spring.repeat.interceptor;

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;

import io.mykit.filter.spring.repeat.annotation.FormToken;

/**

* 基于Token形式的防重复提交拦截器

* @author liuyazhuang

*

*/

public abstract 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);

}

}

/**

* 具体规则交由子类实现

* @param request

* @return

*/

public abstract boolean isRepeatSubmit(HttpServletRequest request);

}

3、创建具体规则实现类MyFormTokenInterceptor

这个类继承FormTokenInterceptor类,实现isRepeatSubmit方法来提供具体的处理规则,这个类也是本例提供的处理方式,如果大家想用其他的处理方式,可自行定义处理类继承FormTokenInterceptor,实现isRepeatSubmit方法即可,这也体现了本实例的高可扩展性。具体代码如下:

package io.mykit.filter.spring.repeat.interceptor.impl;

import javax.servlet.http.HttpServletRequest;

import io.mykit.filter.spring.repeat.interceptor.FormTokenInterceptor;

/**

* 具体规则的实现,这种方式页面需要添加

*

* @author liuyazhuang

*

*/

public class MyFormTokenInterceptor extends FormTokenInterceptor {

@Override

public 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;

}

}

4、配置springmvc-interceptor.xml文件

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xmlns:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-2.5.xsd

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.0.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

5、具体使用

在相关的web工程中的springmvc配置文件中引入springmvc-interceptor.xml文件

如下:

当你自己继承FormTokenInterceptor类实现了具体的拦截规则时,就不能在相关的web工程中的springmvc配置文件中引入springmvc-interceptor.xml文件了,需要添加如下配置

然后在接口的方法上加上注解即可。在需要生成token的controller上增加@FormToken(save=true),而在需要检查重复提交的controller上添加@FormToken(remove=true)就可以了。

另外,你需要在view里在form里增加下面代码:

注意在ajax提交时 要加上 formToken参数

6、附上pom.xml依赖配置

UTF-8

javax.servlet

javax.servlet-api

3.0.1

cglib

cglib

3.2.6

com.alibaba

fastjson

1.2.47

org.springframework

spring-expression

${spring.version}

org.springframework

spring-messaging

${spring.version}

org.springframework

spring-jms

${spring.version}

org.springframework

spring-aop

${spring.version}

org.springframework

spring-jdbc

${spring.version}

org.springframework

spring-context

${spring.version}

org.springframework

spring-context-support

${spring.version}

org.springframework

spring-web

${spring.version}

org.aspectj

aspectjtools

1.9.1

org.springframework

spring-webmvc

${spring.version}

java mvc中重复提交_SpringMVC之——防止重复提交表单的方法(一)相关推荐

  1. java mvc httpget怎么使用_springMVC正确使用GET POST PUT和DELETE方法,如何传递参数

    1. 向服务器请求数据:GET 这是标准的http的GET最擅长的, 应该使用GET请求,但是在使用时候我们会需要传递一个或多个参数给服务器, 这些出参数可能是基本数据类型页可能是对象,get方法可以 ...

  2. php ajax 重复提交,ThinkPHP防止重复提交表单的方法实例分析

    本文实例总结分析了ThinkPHP防止重复提交表单的方法.分享给大家供大家参考,具体如下: 为什么会有表单重复的坑 在开发中,如果一个新增或修改的表单,在后台完成数据库操作后我们设定的不是跳转到其他页 ...

  3. java向注册表单传递数据php_PHP提交from表单的方法

    PHP提交from表单的方法 PHP独特的语法混合了C.Java.Perl以及PHP自创的.语法.它可以比CGI或者Perl更快速地执行动态网页.下面是小编为大家搜索整理的PHP提交from表单的方法 ...

  4. [翻译-ASP.NET MVC]Contact Manager开发之旅迭代3 - 验证表单

    本翻译系列为asp.net mvc官方实例教程.在这个系列中,Stephen Walther将演示如何通过ASP.NET MVC framework结合单元测试.TDD.Ajax.软件设计原则及设计模 ...

  5. java 填充pdf_Java创建和填充PDF表单域方法

    表单域,可以按用途分为多种不同的类型,常见的有文本框.多行文本框.密码框.隐藏域.复选框.单选框和下拉选择框等,目的是用于采集用户的输入或选择的数据.下面的示例中,将分享通过Java编程在PDF中添加 ...

  6. php curlopen,php自动提交表单的方法(基于fsockopen与curl)

    搜索热词 本文实例讲述了PHP基于fsockopen与curl实现自动提交表单的方法.分享给大家供大家参考,具体如下: PHP自动提交表单 1. fsockopen方法: PHP;"> ...

  7. java mvc中重复提交表单,spring mvc 防止重复提交表单的两种方法,推荐第二种

    第一种方法:判断session中保存的token 比较麻烦,每次在提交表单时都必须传入上次的token.而且当一个页面使用ajax时,多个表单提交就会有问题. 注解Token代码: package c ...

  8. java mvc模式工作流程_SpringMVC的简介和工作流程

    一.简介 Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块.Spri ...

  9. Java Web学习总结(12)——使用Session防止表单重复提交

    在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提 ...

最新文章

  1. 【初阶】unity3d官方案例_太空射击SpacingShooter 学习笔记 显示分数时,如何让函数之间相互交流...
  2. git合并多个commit
  3. go语言生成自定义uuid_竟然不用写代码!一款可视化 Web 管理后台生成工具
  4. Java日志框架-Spring中使用Logback(Spring/Spring MVC)
  5. welcome to my blog
  6. Python数据结构与算法(二)--timeit模块
  7. Kafka单节点多broker的部署和使用
  8. 《深入理解分布式事务》第六章 最终一致性分布式事务解决方案
  9. 计算机视觉基础-图像处理 Task06 边缘检测
  10. 我的天!你竟然不会用IDEA远程调试Tomcat...
  11. 某直装外挂卡密校验逆向分析
  12. markdown 在线解析 工具
  13. python uci_UCI机器学习数据库的Python API介绍
  14. 简述FAT32、exFAT、NTFS的区别
  15. 过犹不及,别再在编程中高射炮打蚊子
  16. 网吧服务器多长时间维护,网吧服务器常用设置维护工具
  17. 懒虫读诗 (树形dp+分组背包)
  18. 2048AI设计与实现
  19. atan、atanf、atanl、atan2、atan2f、atan2l
  20. 如何提高团队管理能力3

热门文章

  1. js ‘use strict’详解
  2. PHP开发框架[国内框架]
  3. 看视频学编程之最最基础的基础(1)
  4. DELPHI怎样编写COM组件
  5. python发送excel文件_Python操作Excel, 开发和调用接口,发送邮件
  6. arduino 上传项目出错_Arduino多核编程:简单例子
  7. 微信小程序 等待几秒、_微信小程序—setTimeout定时器的坑
  8. 列主元消去法例题详解_高斯列主元消元法解方程组的步骤
  9. [转载] python 元组tuple - python基础入门(14)
  10. Java RandomAccessFile skipBytes()方法与示例