原理:在新建页面中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拦截器+注解方式实现防止表单重复提交的更多相关文章

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

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

  2. Spring MVC实现防止表单重复提交(转)

    Spring MVC拦截器+注解方式实现防止表单重复提交  

  3. 写的太细了!Spring MVC拦截器的应用,建议收藏再看!

    Spring MVC拦截器 拦截器是Spring MVC中强大的控件,它可以在进入处理器之前做一些操作,或者在处理器完成后进行操作,甚至是在渲染视图后进行操作. 拦截器概述 对于任何优秀的MVC框架, ...

  4. SSM(spring mvc+spring+mybatis)学习路径——2-2、spring MVC拦截器

    目录 2-2 Spring MVC拦截器 第一章 概述 第二章 Spring mvc拦截器的实现 2-1 拦截器的工作原理 2-2 拦截器的实现 2-3 拦截器的方法介绍 2-4 多个拦截器应用 2- ...

  5. spring mvc 拦截器的使用

    Spring MVC 拦截器的使用 拦截器简介 Spring MVC 中的拦截器(Interceptor)类似于 Servler 中的过滤器(Filter).用于对处理器进行预处理和后处理.常用于日志 ...

  6. Spring Boot 2.X(九):Spring MVC - 拦截器(Interceptor)

    拦截器 1.简介 Spring MVC 中的拦截器(Interceptor)类似于 Servlet 开发中的过滤器 Filter,它主要用于拦截用户请求并作相应的处理,它也是 AOP 编程思想的体现, ...

  7. Spring MVC拦截器浅析

    Spring MVC拦截器 重点:Spring MVC的拦截器只会拦截控制器的请求,如果是jsp.js.image.html则会放行. 什么是拦截器 运行在服务器的程序,先于Servlet或JSP之前 ...

  8. Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法

    Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法 在Action中方法的返回值都是字符串行,一般情况是返回某个JSP,如: return "xx" ...

  9. 【Java Web开发学习】Spring MVC 拦截器HandlerInterceptor

    [Java Web开发学习]Spring MVC 拦截器HandlerInterceptor 转载:https://www.cnblogs.com/yangchongxing/p/9324119.ht ...

随机推荐

  1. mybatis入门基础(四)----输入映射和输出映射

    一:输入映射 通过parameterType指定输入参数的类型,类型可以是简单类型.hashmap.pojo的包装类型. 1.1.传递pojo的包装对象 1.1.1.需求描述 完成用户信息的综合查询, ...

  2. React Native at first sight

    what is React Native? 跟据官方的描述, React Native是一套使用 React 构建 Native app 的编程框架. 推出不久便引发了广泛关注, 这也得益于 Java ...

  3. Nancy之基于Nancy.Hosting.Self的小Demo

    继昨天的Nancy之基于Nancy.Hosting.Aspnet的小Demo后, 今天来做个基于Nancy.Hosting.Self的小Demo. 关于Self Hosting Nancy,官方文档的 ...

  4. 关系数据库SQL之可编程性事务

    前言 前面关系数据库SQL之可编程性函数(用户自定义函数)一文提到关系型数据库提供了可编程性的函数.存储过程.事务.触发器及游标,前文已介绍了函数.存储过程,本文来介绍一下事务的使用.(还是以前面的银 ...

  5. mvc实现上传视频预览

    上个项目中用到了上传视频,本来打算用百度的webuploader做的,但是webuploader可能有个毛病就是不能上传太大的东西. 于是乎,只能换个方法做了啊,看了半天最终决定用传统的uploade ...

  6. Windows Server 2008 R2 安装 media Service 部分更新没有安装 KB963697

    1.下载安装包 Windows6.1-KB963697-x64.msu 2.安装过程失败,提示未安装更新 我是阿里云的服务器,一直出现下面提示 经过反复研究,确定系统问题,重新恢复了初始系统,再进行安 ...

  7. Git避免输入用户名和密码

    1. 在系统盘/用户/用户名目录下新建名为 _netrc 的文件: 2. 修改 _netrc 文件内容为“  machine git.mangning.comlogin xxxpassword xxx ...

  8. 如何在windows下的Python开发工具IDLE里安装其他模块?

    以安装Httplib2模块为例 1 下载模块 到 “https://code.google.com/p/httplib2/” 下载一款适合你的压缩包“httplib2-0.4.0.zip” 2 解压下 ...

  9. fastq-dump 报错 解决方案

    命令行: ~/tools/sratoolkit/sratoolkit.2.3.2-5-centos_linux64/bin/fastq-dump --split-spot --gzip rhesus_ ...

  10. python基础之函数

    python 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也 ...