• Spring MVC防止数据重复提交


         现实开发中表单重复提交的例子很多,就包括手上这个门户的项目也有这种应用场景,用的次数多,但是总结,这还是第一次。

    一、基本原理

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

    二、代码

    2.1、注解Token代码:

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

    2.2、拦截器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;
        }
    }
    

    2.3、在Spring MVC的配置文件里加入:

        <!-- 拦截器配置 -->
        <mvc:interceptors>
            <!-- 配置Token拦截器,防止用户重复提交数据 -->
            <mvc:interceptor>
                <mvc:mapping path="/**"/>
                <bean class="com.cms.web.TokenInterceptor"/>
            </mvc:interceptor>
        </mvc:interceptors>
    

    2.4、使用:

      在需要生成token的controller上增加@Token(save=true),而在需要检查重复提交的controller上添加@Token(remove=true)就可以了。
    另外,你需要在view里在form里增加下面代码:

    <input type="hidden" name="token" value="${token}" />
    

      

  • 相关阅读:
    bzoj4864 [BeiJing 2017 Wc]神秘物质
    HNOI2011 括号修复
    bzoj2402 陶陶的难题II
    ZJOI2008 树的统计
    USACO09JAN 安全出行Safe Travel
    HAOI2015 树上操作
    hdu5126 stars
    BOI2007 Mokia 摩基亚
    SDOI2011 拦截导弹
    国家集训队 排队
  • 原文地址:https://www.cnblogs.com/geekdc/p/5773583.html
Copyright © 2020-2023  润新知