Spring MVC拦截器+注解方式实现防止表单重复提交
原理:在新建页面中Session保存token随机码,当保存时验证,通过后删除,当再次点击保存时由于服务器端的Session中已经不存在了,所有无法验证通过。 注,如果是集群的方式,则需要将token放入到缓存中即可。 注解Token代码:java源码 Java代码 复制代码 收藏代码
.@Target(ElementType.METHOD)
.@Retention (RetentionPolicy.RUNTIME)
.public @interface Token {
.
. boolean needSaveToken () default false ;
.
. boolean needRemoveToken () default false ;
.} 拦截器TokenInterceptor代码: Java代码 复制代码 收藏代码
.public class TokenInterceptor extends HandlerInterceptorAdapter {
.
. @Override
. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throwsException {
. if (handler instanceof HandlerMethod) {
. HandlerMethod handlerMethod = (HandlerMethod) handler;
. Method method = handlerMethod.getMethod();
. Token annotation = method.getAnnotation(Token. class );
. if (annotation != null ) {
. boolean needSaveSession = annotation.save();
. if (needSaveSession) {
. request.getSession( false ).setAttribute( "token" , UUID.randomUUID().toString());
. }
. boolean needRemoveSession = annotation.remove();
. if (needRemoveSession) {
. 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" );
. if (serverToken == null ) {
. return true ;
. }
. String clinetToken = request.getParameter( "token" );
. if (clinetToken == null ) {
. return true ;
. }
. if (!serverToken.equals(clinetToken)) {
. return true ;
. }
. return false ;
. }
.} 然后在Spring MVC的配置文件里加入: Xml代码 复制代码 收藏代码
.<!-- 拦截器配置 -->
.< mvc:interceptors >
. <!-- 配置Shiro拦截器,实现注册用户的注入 -->
. < mvc:interceptor >
. < mvc:mapping path = "/**" />
. < bean class = "com.storezhang.video.shiro.ShiroInterceptor" />
. </ mvc:interceptor >
. <!-- 配置Token拦截器,防止用户重复提交数据 -->
. < mvc:interceptor >
. < mvc:mapping path = "/**" />
. < bean class = "com.storezhang.web.spring.TokenInterceptor" />
. </ mvc:interceptor >
.</ mvc:interceptors > 相关代码已经注释,相信你能看懂。
关于这个方法的用法是:在需要生成token的controller上增加@Token(save=true),而在需要检查重复提交的controller上添加@Token(remove=true)就可以了。
另外,你需要在view里在form里增加下面代码: Html代码 复制代码 收藏代码
.< input type = "hidden" name = "token" value = "${token}" /> 在相关方法中加入注解 Java代码 复制代码 收藏代码
.@RequestMapping("/save")
. @AvoidDuplicateSubmission(needRemoveToken = true)
. public synchronized ModelAndView save(ExecutionUnit unit, HttpServletRequest request, HttpServletResponse response)
. throws Exception {
.
.@RequestMapping("/edit")
. @AvoidDuplicateSubmission(needSaveToken = true)
. public ModelAndView edit(Integer id, HttpServletRequest request) throws Exception { 已经完成了,去试试看你的数据还能重复提交了吧。
Spring MVC拦截器+注解方式实现防止表单重复提交的更多相关文章
- spring boot 学习(七)小工具篇:表单重复提交
注解 + 拦截器:解决表单重复提交 前言 学习 Spring Boot 中,我想将我在项目中添加几个我在 SpringMVC 框架中常用的工具类(主要都是涉及到 Spring AOP 部分知识).比如 ...
- Spring MVC实现防止表单重复提交(转)
Spring MVC拦截器+注解方式实现防止表单重复提交
- 写的太细了!Spring MVC拦截器的应用,建议收藏再看!
Spring MVC拦截器 拦截器是Spring MVC中强大的控件,它可以在进入处理器之前做一些操作,或者在处理器完成后进行操作,甚至是在渲染视图后进行操作. 拦截器概述 对于任何优秀的MVC框架, ...
- SSM(spring mvc+spring+mybatis)学习路径——2-2、spring MVC拦截器
目录 2-2 Spring MVC拦截器 第一章 概述 第二章 Spring mvc拦截器的实现 2-1 拦截器的工作原理 2-2 拦截器的实现 2-3 拦截器的方法介绍 2-4 多个拦截器应用 2- ...
- spring mvc 拦截器的使用
Spring MVC 拦截器的使用 拦截器简介 Spring MVC 中的拦截器(Interceptor)类似于 Servler 中的过滤器(Filter).用于对处理器进行预处理和后处理.常用于日志 ...
- Spring Boot 2.X(九):Spring MVC - 拦截器(Interceptor)
拦截器 1.简介 Spring MVC 中的拦截器(Interceptor)类似于 Servlet 开发中的过滤器 Filter,它主要用于拦截用户请求并作相应的处理,它也是 AOP 编程思想的体现, ...
- Spring MVC拦截器浅析
Spring MVC拦截器 重点:Spring MVC的拦截器只会拦截控制器的请求,如果是jsp.js.image.html则会放行. 什么是拦截器 运行在服务器的程序,先于Servlet或JSP之前 ...
- Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法
Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法 在Action中方法的返回值都是字符串行,一般情况是返回某个JSP,如: return "xx" ...
- 【Java Web开发学习】Spring MVC 拦截器HandlerInterceptor
[Java Web开发学习]Spring MVC 拦截器HandlerInterceptor 转载:https://www.cnblogs.com/yangchongxing/p/9324119.ht ...
随机推荐
- 2.Java基础之Runtime对象
毕向东老师Java基础学习笔记——Runtime对象 今天学习Java中的Runtime对象后,感觉这个对象对我们主要有以下几点用处. 1.使用java代码打开本地可执行文件,比如打开一个计算器. 2 ...
- Android测试提升效率批处理脚本
前言: APP测试过程中,经常需要用的一些命令,如adb,每次敲命令,虽可以加深印象,但个人认为那即繁琐又浪费时间.本文贴出一些我使用的批处理,以及一点点小小技巧. 目录 1.[查看APK文件信息.b ...
- T4 模板自动生成带注释的实体类文件 - 只需要一个 SqlSugar.dll
生成实体就是这么简单,只要建一个T4文件和 文件夹里面放一个DLL. 使用T4模板教程 步骤1 创建T4模板 ,一定要自已新建,把T4代码复制进去,好多人因为用我现成的T4报错(原因不明) 点击添加文 ...
- 7.11 数据注解特性--InverseProperty
我们已经知道了,Code--First默认的约定,如果你没有包含外键属性在父类中,那么他会为我们创建{Class Name}_{primary Key}外键.这个InverseProperty特性用在 ...
- Rafy 领域实体框架 - 树型实体功能(自关联表)
在 Rafy 领域实体框架中,对自关联的实体结构做了特殊的处理,下面对这一功能进行讲解. 场景 在开发数据库应用程序时,往往会遇到自关联表的场景.例如,分类信息.组织架构中的部门.文件夹信息等,都 ...
- Effective java笔记(六),方法
38.检查参数的有效性 绝大多数方法和构造器对于传递给它们的参数值都会有限制.如,对象引用不能为null,数组索引有范围限制等.应该在文档中指明所有这些限制,并在方法的开头处检查参数,以强制施加这些限 ...
- ASP.NET Core中间件(Middleware)实现WCF SOAP服务端解析
ASP.NET Core中间件(Middleware)进阶学习实现SOAP 解析. 本篇将介绍实现ASP.NET Core SOAP服务端解析,而不是ASP.NET Core整个WCF host. 因 ...
- Andriod小项目——在线音乐播放器
转载自: http://blog.csdn.net/sunkes/article/details/51189189 Andriod小项目——在线音乐播放器 Android在线音乐播放器 从大一开始就已 ...
- Git 获取文件操作
1. 在本地新建存放源代码的文件夹: 2. 进入文件夹下,右击选择 Git Bash Here ,弹出git命令行窗口: 3. 运行指定 git init,初始化git: 4. git remote ...
- 疯狂Android讲义 - 学习笔记(五)
第五章 Android使用统一的Intent对象来封装“启动意图”,不管是启动Activity.Service组件.或者BroadcastReceiver等,提供了一致的编程模型.Intent设计有点 ...