• SpringMVC学习篇(十)


    springmvc拦截器之重复提交

    1 出现原因

    在新增和修改界面点击提交后(转发的方式跳转)
    再次刷新页面,如果不做处理的话,会造成重复提交,
    从而使得新增商品多次或者更改商品多次
    
    • 1
    • 2
    • 3

    2 解决方案

    2.1 准备工作

    导入servlet-api依赖和spring-webmvc依赖

     <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-webmvcartifactId>
                <version>5.3.22version>
    dependency>
    <dependency>
                <groupId>org.apache.tomcatgroupId>
                <artifactId>servlet-apiartifactId>
                <version>6.0.53version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.2 创建Token注解

    package com.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    /*ElementType.METHOD表示该注解只能使用在方法时*/
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)//运行时保留
    public @interface Token {
       //跳转页面时 使用
       boolean save() default false;
       //提交表单后 使用
       boolean remove() default false;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.3 创建EmpController类

    package com.controller;
    
    import com.annotation.Token;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.HttpSession;
    
    @Controller
    @RequestMapping("emps")
    public class EmpController {
        @RequestMapping("add01")
        @Token(remove = true)
        public String add01(String ename){
            System.out.println("添加员工 姓名:"+ename);
            return "index";
        }
        @RequestMapping("toadd01")
        @Token(save = true)
        public String a(){
            return "empadd";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2.4 创建empadd.jsp页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    
        Title
    
    
        
    员工姓名:
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.5 创建RepeatInterceptor拦截器,用于拦截重复提交请求

    package com.interceptor;
    
    import com.annotation.Token;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class RepeatInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //handler是控制器的方法
            if(handler instanceof HandlerMethod){
                // HandlerMethod表示控制器方法
                HandlerMethod method=(HandlerMethod) handler;
                //拿到方法上的token注解
                Token token = method.getMethodAnnotation(Token.class);
                //判断是否有使用该注解,若没有就直接放行
                if (token != null) {
                    //判断是否为save save表示跳转页面
                    if (token.save()) {
                        request.getSession().setAttribute("token", "");
                    }
                    //判断是否为remove 表示提交表单
                    if (token.remove()) {
                        //判断是否重复提交
                        if(isRepeat(request)){
                          /*只有这一种情况才会阻止*/
                          request.getRequestDispatcher("/WEB-INF/repeat.jsp").forward(request, response);
                          return false;
                        }
                        //如果不是重复提交,就要把其删除掉
                        request.getSession().removeAttribute("token");
                    }
                }
            }
            return true;
        }
    
        private boolean isRepeat(HttpServletRequest request) {
            //判断session里面是否有值
            Object token = request.getSession().getAttribute("token");
            return token==null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    2.6 在SpringMvc2.xml中配置拦截器

    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.interceptor.RepeatInterceptor">bean>
    mvc:interceptor>
    
    • 1
    • 2
    • 3
    • 4

    2.7 在WEB-INF目录下创建repeat.jsp界面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    
        Title
    
    
        

    请勿重复提交

    返回主页
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.8 运行截图

    2.8.1 添加用户前

    在这里插入图片描述

    2.8.2 点击添加按钮前

    在这里插入图片描述

    2.8.3 点击添加按钮后
    a 前台部分

    在这里插入图片描述

    b 控制台输出信息

    在这里插入图片描述

    2.8.4 点击刷新按钮

    在这里插入图片描述

    2.8.5 点击刷新按钮后

    在这里插入图片描述

    3 阻止重复提交的执行流程

    当/emps/toadd方式进入添加用户界面的时候,拦截器里头会在session域中设置进去一个key为token的值
    当/emps/add01方式进行表单数据提交时,会执行 if (token.remove())分支,然后此时经过验证知道token不为null,
    就不属于重复提交的情况,这时需要移除掉之前设置进去的token这个key
    当点击刷新的时候,就相当于再次执行/emps/add01方式,首先被拦截器拦截,发现此时token变量值==null,属于重复提交
    就会转发到错误提示界面(请勿重新提交),此时就已经阻止好了重复提交了
    注意:配上/**让所有页面都拦截,如果没有注解就可以放行,减低重复提交出现的可能性
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    【Python基础篇】运算符
    Oracle 安装及 Spring 使用 Oracle
    【我的C/C++语言学习进阶之旅】C/C++编程笔记:C语言使用宏定义#define来处理通用的可抽取的代码块
    【多服务场景化解决方案】AR虚拟技术助力智能家装
    Android-Studio与Python环境配置
    Android Studio制作简单登录界面
    多线程常见锁的策略
    Windows环境下的ELK——logstash+elasticsearch(3)
    实例解析Java反射
    Springboot、maven 打包瘦身,去除依赖的jar【springboot外置jar、配置文件】
  • 原文地址:https://blog.csdn.net/SSS4362/article/details/127912590