zoukankan      html  css  js  c++  java
  • Spring MVC防止数据重复提交(防止二次提交)

    SpringMvc使用Token 
    使用token的逻辑是,给所有的url加一个拦截器,在拦截器里面用java的UUID生成一个随机的UUID并把这个UUID放到session里面,然后在浏览器做数据提交的时候将此UUID提交到服务器。服务器在接收到此UUID后,检查一下该UUID是否已经被提交,如果已经被提交,则不让逻辑继续执行下去…

    首先要定义一个annotation:

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Token {
    
        boolean save() default false;
    
        boolean remove() default false;
    }

    定义拦截器TokenInterceptor:

    public class TokenInterceptor extends HandlerInterceptorAdapter {
    
        @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 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的配置文件里加入:

    <mvc:interceptors>  
            <!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->  
            <mvc:interceptor>  
                <mvc:mapping path="/**"/>  
                <!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->  
                <bean class="****包名****.TokenInterceptor"/>  
            </mvc:interceptor>  
        </mvc:interceptors>

    用法:

    1. 在新增或者修改前的编辑的controll方法上增加@Token(save=true)
    2. 在表单提交的controller的方法上增加@Token(remove=true)
    3. 在表单中增加<input type="hidden" name="token" value="${token}" />
  • 相关阅读:
    python
    python
    selenium
    性能测试分类
    大型网站架构演化(总)
    网站性能测试的方法
    大型网站架构演化(十)——分布式服务
    大型网站架构演化(九)——业务拆分
    大型网站架构演化(八)——使用NoSQL和搜索引擎
    大型网站架构演化(七)——使用分布式文件系统和分布式数据库系统
  • 原文地址:https://www.cnblogs.com/austinspark-jessylu/p/7793335.html
Copyright © 2011-2022 走看看