161116、springmvc自己实现防止表单重复提交(基于注解)
原理:在去某个页面直接生成一个随机数(这里使用的是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自己实现防止表单重复提交(基于注解)的更多相关文章
- Strusts2笔记9--防止表单重复提交和注解开发
防止表单重复提交: 用户可能由于各种原因,对表单进行重复提交.Struts2中使用令牌机制防止表单自动提交.以下引用自北京动力节点:
- spring boot 学习(七)小工具篇:表单重复提交
注解 + 拦截器:解决表单重复提交 前言 学习 Spring Boot 中,我想将我在项目中添加几个我在 SpringMVC 框架中常用的工具类(主要都是涉及到 Spring AOP 部分知识).比如 ...
- 大型运输行业实战_day05_1_登录+注销+表单重复提交+登录拦截器
1.登录 登录实现如下步骤: 1.在首页中添加登录按钮 html代码如下: <%@ page contentType="text/html;charset=UTF-8" la ...
- 12、Struts2表单重复提交
什么是表单重复提交 表单的重复提交: 若刷新表单页面, 再提交表单不算重复提交. 在不刷新表单页面的前提下: 多次点击提交按钮 已经提交成功, 按 "回退" 之后, 再点击 &qu ...
- java防止表单重复提交
用session防止表单重复提交 思路:在服务器端生成一个唯一的随机标识串Token,同时在当前用户的Session域中保存这个Token.然后将Token发送到客户端的Form表单中,在Form表单 ...
- java web学习总结(十三) -------------------使用Session防止表单重复提交
在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提 ...
- 使用Struts 2防止表单重复提交
用户重复提交表单在某些场合将会造成非常严重的后果.例如,在使用信用卡进行在线支付的时候,如果服务器的响应速度太慢,用户有可能会多次点击提交按钮,而这可能导致那张信用卡上的金额被消费了多次.因此,重复提 ...
- js阻止form表单重复提交
防止表单重复提交的方法总体来说有两种,一种是在js中阻止重复提交:另一种是在后台利用token令牌实现,大致思路是生成一个随机码放到session和form表单的隐藏输入框中,提交表单时两者对比,表单 ...
- PHP简单利用token防止表单重复提交
<?php /* * PHP简单利用token防止表单重复提交 * 此处理方法纯粹是为了给初学者参考 */ session_start(); function set_token() { $_S ...
随机推荐
- C#中override和overload的区别
重载应该叫overload,重写叫override:重载某个方法是在同一个类中发生的!重写是在子类中重写父类中的方法. 1.override: 父类:public virtual string T ...
- iOS发送短信
iPhone开发,发送短信的方法: iPhone开发中,发送短信方法有二: 1.URL Scheme,这样不可以设置短信内容 1 2 3 [[UIApplication sharedApplicati ...
- extjs form.load()加载服务端数据
formPanel.getForm().load({ url: 'getApproveRefundInf?refundIdDetail=${refundIdDetail}', waitMsg: '请稍 ...
- iOS 开发知识小集(1)
iOS 开发知识小集(1) 2015-05-15 iOS大全 (点击上方蓝字,快速关注我们) 一直想做这样一个小册子,来记录自己平时开发.阅读博客.看书.代码分析和与人交流中遇到的各种问题.之前有过 ...
- css实现元素居中
参见详细教程,该教程涵盖了所有居中的情况: https://css-tricks.com/centering-css-complete-guide/ css元素居中 1.水平居中 1)文本,图片等行 ...
- Collections的排序之一(Java)
package home.collection.arr; import java.util.ArrayList; import java.util.Collections; import java.u ...
- :before 和 :after 的内幕 以及伪类 ( 转 )
原文链接 http://www.cnblogs.com/zhujl/archive/2012/05/08/2489411.html ------------------------------- ...
- NLS_LANG参数说明
NLS_LANG参数说明 格式: NLS_LANG = language_territory.charset 它有三个组成部分(语言.地域和字符集),每个成分控制了NLS子集的特性.其中: Lang ...
- NSData
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) ...
- CSS文档流与块级元素和内联元素
CSS文档流与块级元素(block).内联元素(inline),之前翻阅不少书籍,看过不少文章, 看到所多的是零碎的CSS布局基本知识,比较表面.看过O'Reilly的<CSS权威指南>, ...