使用aop注解实现表单防重复提交功能
原文:https://www.cnblogs.com/manliu/articles/5983888.html
1.这里采用的方法是:使用get请求进入表单页面时,后台会生成一个tokrn_flag分别放到session和request中,表单页面用一个隐藏域储存该token_flag,在提交表单时,将该token_flag一并提交到后台,后台将该token_flag和session中对比,只要比对通过就立即删除session中的token_flag,这样就能保证表单最多只有一次成功提交的机会。
2.表单防重复提交一般前后端都会做,前端比较简单,点击过一次就将提交按钮置灰或disabled。
3.因为生成和验证token_flag具有通用性,一般不建议嵌入到具体方法中,最好的方法就是使用aop+注解的方式
4.注解

/**
* 表单注解,放在需要验证表单的方法上,一般是controller上
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface FormToken { }

5.AOP

@Aspect
@Component
public class ResubmitAspect {
private static final String PARAM_TOKEN = "token";
private static final String PARAM_TOKEN_FLAG = "TokenFlag_"; /**
* 执行切面拦截逻辑
*/
@Around("@annotation(formToken)")
public void execute(ProceedingJoinPoint joinPoint, FormToken formToken) throws Throwable {
if (formToken != null) {
//方法入参列表
Object[] args = joinPoint.getArgs();
//类名
String className = joinPoint.getTarget().getClass().getName();
for (Object arg : args) {
//方法入参是否包含request
if (arg != null && arg instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) arg;
HttpSession session = request.getSession(true);
if ("GET".equalsIgnoreCase(request.getMethod())) {
/* GET 生成 token */
this.generate(joinPoint, request, session, PARAM_TOKEN_FLAG + className);
} else {
/* POST 验证 token */
this.validation(joinPoint, request, session, PARAM_TOKEN_FLAG + className);
}
}
}
}
}
/**
* <p>
* 生成表单 token
* </p>
*/
public void generate(ProceedingJoinPoint joinPoint, HttpServletRequest request, HttpSession session,
String tokenFlag) throws Throwable {
String uuid = UUID.randomUUID().toString();
session.setAttribute(tokenFlag, uuid);
request.setAttribute(PARAM_TOKEN, uuid);
joinPoint.proceed();
}
/**
* <p>
* 验证表单 token
* </p>
* <p>
* 验证结果一致,既为第一次提交,删除会话中存储的token,并继续执行方法。<br>
* 否则不做任何处理。
* </p>
*/
public void validation(ProceedingJoinPoint joinPoint, HttpServletRequest request, HttpSession session,
String tokenFlag) throws Throwable {
Object sessionFlag = session.getAttribute(tokenFlag);
Object requestFlag = request.getParameter(PARAM_TOKEN);
if (sessionFlag != null && sessionFlag.equals(requestFlag)) {
//删除已验证的token
session.removeAttribute(tokenFlag);
joinPoint.proceed();
}
}
}

6.配置
在spring配置文件中
<aop:aspectj-autoproxy />
<context:component-scan base-package="com.baomidou.framework.aop">
</context:component-scan>
7.html中使用
<input type="hidden" name="token" value="${token}" />
使用aop注解实现表单防重复提交功能的更多相关文章
- Spring MVC表单防重复提交
利用Spring MVC的过滤器及token传递验证来实现表单防重复提交. 创建注解 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RU ...
- Token注解防止表单的重复提交
注解的一些基础: 参见http://blog.csdn.net/duo2005duo/article/details/50505884和 http://blog.csdn.net/duo2005duo ...
- struts2 文件的上传下载 表单的重复提交 自定义拦截器
文件上传中表单的准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设 ...
- php中如何防止表单的重复提交
在php中如何防止表单的重复提交?其实也有几种解决方法. 下面小编就为大家介绍一下吧.需要的朋友可以过来参考下 代码: <?php /* * php中如何防止表单的重复提交 * by www.j ...
- php-- 避免表单的重复提交
用户提交表单时可能因为网速的原因,或者网页被恶意刷新,致使同一条记录重复插入到数据库中,这是一个比较棘手的问题.我们可以从客户端和服务器端一起着手,设法避免同一表单的重复提交. 1.使用客户端脚本 提 ...
- Session机制三(表单的重复提交)
1.表单的重复提交的情况 在表单提交到一个servlet,而servlet又通过请求转发的方式响应了一个JSP页面,这个时候地址栏还保留这servlet的那个路径,在响应页面点击刷新. 在响应页面没有 ...
- HttpSession解决表单的重复提交
1). 重复提交的情况: ①. 在表单提交到一个 Servlet, 而 Servlet 又通过请求转发的方式响应一个 JSP(HTML) 页面, 此时地址栏还保留着 Serlvet 的那个路径, 在响 ...
- Struts2 - 表单的重复提交问题
用户重复提交表单在某些场合将会造成非常严重的后果.例如,在使用信用卡进行在线支付的时候,如果服务器的响应速度太慢,用户有可能会多次点击提交按钮,而这可能导致那张信用卡上的金额被消费了多次.因此,重复提 ...
- HttpSession之表单的重复提交 & 验证码
如果采用 HttpServletResponse.sendRedirct() 方法将客户端重定向到成功页面,将不会出现重复提交问题 1.表单的重复提交 1). 重复提交的情况: ①. 在表单提交到一个 ...
随机推荐
- elasticsearch in语句和not in语句
sql语句示例: select * from table where t_id in (1,2,3,4) php代码示例: $search_query = [ "bool" =&g ...
- vue-cli3 按需加载loading,服务的方式调用
安装 babel-plugin-component npm install babel-plugin-component -S 安装element-ui npm install element-ui ...
- egg.js 通过 form 和 ajax 两种方式上传文件并自定义目录和文件名
egg.js 通过 form 和 ajax 两种方式上传文件并自定义目录和文件名 评论:10 · 阅读:8437· 喜欢:0 一.需求 二.CSRF 校验 三.通过 form 表单上传文件 四.通过 ...
- P/Invoke 技术
.NET 互操作 首先推荐一本书<精通.NET 互操作> ,这本书是目前中文资料里讲 互操作最详尽的书了. 做系统集成项目的同学应该都和设备打过交道(如视频设备:海康.大华等),在大多数情 ...
- 【leetcode算法-简单】7.整数反转
[题目描述] 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123输出: 321 示例 2: 输入: -123输出: -321 示例 3: 输入: 12 ...
- MaskRCNN 奔跑自己的数据
import os import sys import random import math import re import time import numpy as np import cv2 i ...
- ABP中的本地化处理(下)
在上篇文章中我们的重点是讲述怎样通过在Domain层通过PreInitialize()配置ILocalizationConfiguration中的Sources(IList<ILocalizat ...
- pod宿主机挂载pv存储过程
1处的控制循环Control Loop应该是:VolumeManagerReconciler ----------------------------------------------------- ...
- Scala 面向对象编程之对象
此对象非彼java bean对象 是scala object的对象 Object // object,相当于class的单个实例,通常在里面放一些静态的field或者method // 第一次调用ob ...
- 【模拟】Clock
Clock 题目描述 wls有一个钟表,当前钟表指向了某一个时间.又有一些很重要的时刻,wls想要在钟表上复现这些时间(并不需要依次复现).我们可以顺时针转动秒针,也可以逆时针转动秒针,分针和时针都会 ...