原理:在去某个页面直接生成一个随机数(这里使用的是UUID)并放入session中,用户提交表单时将这个随机数传入服务端与session中的值进行比较,如果不不存在或不相等,则认为是重复提交;如果相等则不是重复提交。

实现技术:采用springmvc的拦截器统一处理

下面实现(五步)

第一步:

package com.xxx.utils.anti_resubmit;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

 * 防止重复提交用

 * @author wsc

 * 2016年12月5日

 */

@Target(ElementType.METHOD)//如果用在类上,将此行注释

@Retention(RetentionPolicy.RUNTIME)

public @interface Token {

boolean save() default false;  

boolean remove() default false;

}

第二步:拦截器

package com.xxx.inteceptors;

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 com.xxx.annotation.anti_resubmit.Token;

/**

 * 防止重复提交

 * @author wsc

 * 2016年12月5日

 */

public class TokenInterceptor extends HandlerInterceptorAdapter {

private static final String TOKEN_NAME = "token";

@Override

public boolean preHandle(HttpServletRequest request,

HttpServletResponse response, Object handler) throws Exception {

if(handler instanceof HandlerMethod){

HandlerMethod handlerMethod = (HandlerMethod) handler;

Method method = handlerMethod.getMethod();

Token annotation = method.getAnnotation(Token.class);

if(annotation != null){

boolean need2SaveSession = annotation.save();

if(need2SaveSession){

request.getSession(false).setAttribute("token", UUID.randomUUID().toString());

}

boolean need2RemoveSession = annotation.remove();

if(need2RemoveSession){

if(isRepeatSubmit(request)){

return false;

}

request.getSession(false).removeAttribute("token");

}

}

return true;

}else{

return super.preHandle(request, response, handler);

}

}

/**检查是否是重复提交(为空,不相等)*/

private boolean isRepeatSubmit(HttpServletRequest request) {

String serverToken = (String) request.getSession(false).getAttribute(TOKEN_NAME);//服务端

if(serverToken == null){

return true;

}

String clientToken = request.getParameter(TOKEN_NAME);//客户端

if(clientToken == null){

return true;

}

if(!serverToken.equals(clientToken)){

return true;

}

return false;

}

}

第三步:

springmvc配置文件(拦截器)

   <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">

<property name="interceptors">

<list>

<!-- <ref bean="wechatLoginInterceptor"/> -->

<ref bean="tokenInteceptor"/>

</list>

</property>

</bean>

<bean id="tokenInteceptor" class="com.xxx.inteceptors.TokenInterceptor"/>

第四步:

controller中使用

@RequestMapping("/add.jspf")

@Token(save=true)

public String add() {

//省略

return TPL_BASE + "index";

}

@RequestMapping("/save.jspf")

@Token(remove=true)

public void save() {

//省略

}

第五步:

页面

<input type="text" name="token" value="${token}"/>

  

161116、springmvc自己实现防止表单重复提交(基于注解)的更多相关文章

  1. Strusts2笔记9--防止表单重复提交和注解开发

    防止表单重复提交: 用户可能由于各种原因,对表单进行重复提交.Struts2中使用令牌机制防止表单自动提交.以下引用自北京动力节点:

  2. spring boot 学习(七)小工具篇:表单重复提交

    注解 + 拦截器:解决表单重复提交 前言 学习 Spring Boot 中,我想将我在项目中添加几个我在 SpringMVC 框架中常用的工具类(主要都是涉及到 Spring AOP 部分知识).比如 ...

  3. 大型运输行业实战_day05_1_登录+注销+表单重复提交+登录拦截器

    1.登录 登录实现如下步骤: 1.在首页中添加登录按钮 html代码如下: <%@ page contentType="text/html;charset=UTF-8" la ...

  4. 12、Struts2表单重复提交

    什么是表单重复提交 表单的重复提交: 若刷新表单页面, 再提交表单不算重复提交. 在不刷新表单页面的前提下: 多次点击提交按钮 已经提交成功, 按 "回退" 之后, 再点击 &qu ...

  5. java防止表单重复提交

    用session防止表单重复提交 思路:在服务器端生成一个唯一的随机标识串Token,同时在当前用户的Session域中保存这个Token.然后将Token发送到客户端的Form表单中,在Form表单 ...

  6. java web学习总结(十三) -------------------使用Session防止表单重复提交

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

  7. 使用Struts 2防止表单重复提交

    用户重复提交表单在某些场合将会造成非常严重的后果.例如,在使用信用卡进行在线支付的时候,如果服务器的响应速度太慢,用户有可能会多次点击提交按钮,而这可能导致那张信用卡上的金额被消费了多次.因此,重复提 ...

  8. js阻止form表单重复提交

    防止表单重复提交的方法总体来说有两种,一种是在js中阻止重复提交:另一种是在后台利用token令牌实现,大致思路是生成一个随机码放到session和form表单的隐藏输入框中,提交表单时两者对比,表单 ...

  9. PHP简单利用token防止表单重复提交

    <?php /* * PHP简单利用token防止表单重复提交 * 此处理方法纯粹是为了给初学者参考 */ session_start(); function set_token() { $_S ...

随机推荐

  1. Failed to load PDF in chrome/Firefox/IE

    笔者的公司搭建了一个Nexus服务器,用来管理我们自己的项目Release构件和Site文档. 今天的问题是当用户访问一个Site里的PDF文件的时候,报错说“detected that the ne ...

  2. oracle dump event

    一.Memory Dumps 1).Global Area ALTER SESSION SET EVENTS 'immediate trace name global_area level n'; 1 ...

  3. php数组遍历

    <?php $arr = array('a','b','c','d','e','f'); //for语句只能遍历索引数组 for($i = 0; $i < 6; $i++){ echo $ ...

  4. 微信公众平台开发(110) 微信连Wi-Fi

    关键字:微信公众平台 微信连Wi-Fi 微信 WiFi 硬件鉴权作者:方倍工作室 原文:http://www.cnblogs.com/txw1958/p/weixin-wifi.html 微信连Wi- ...

  5. linux 安装apahce的configure: error: APR not found. Please read the documentation解决办法

    1.下载所需软件包: 下载apr并配置 wget http://apache.freelamp.com/apr/apr-1.4.2.tar.gz 下载apr ./configure –prefix=/ ...

  6. linux多个python版本下导致no request报错

    解决办法: sudo apt-get install uwsgi uwsgi-core uwsgi-plugin-python sudo apt-get install uwsgi-plugin-py ...

  7. 使用APICloud平台一周时间开发出休闲娱乐内容类APP

    这款app是我花一周左右时间做出来的,一款阅读笑话,段子,糗事,脑筋急转弯,神回复,语录,谜语等的休闲娱乐app,用户除了可以浏览他人发布的内容外,自己也可以发布相关内容,和其他人一同分享有趣的内容, ...

  8. JRE和JDK的区别

    1. 定义 JRE(Java Runtime Enviroment)是Java的运行环境.面向Java程序的使用者,而不是开发者.如果你仅下载并安装了JRE,那么你的系统只能运行Java程序.JRE是 ...

  9. VS中使用系统的环境变量作为INCLUDE和LIBPATH的值

    所谓INCLUDE的值实际上就是头文件的搜索路径,而LIBPATH就是.lib的搜索路径,对应着命令行中的/I和/LIBPATH选项 假设你有一个 D:/demo/abc/include/abc.h, ...

  10. Swift动画编程指南-01 简介

    大家好,我是老镇,这段时间家里和工作上发生了很多的事情,所以很长一段时间都没有出来搞什么小动作了.在接下来的一段时间内我会制作一些列关于使用Swift进行动画编程的视频,希望和大家胃口. 在iOS的世 ...