zoukankan      html  css  js  c++  java
  • Spring MVC拦截器+注解方式实现防止表单重复提交

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt335

    原理:在新建页面中Session保存token随机码,当保存时验证,通过后删除,当再次点击保存时由于服务器端的Session中已经不存在了,所有无法验证通过。

    1.新建注解:

    ?

     
    /**
     * <p>
     * 防止重复提交注解,用于方法上<br/>
     * 在新建页面方法上,设置needSaveToken()为true,此时拦截器会在Session中保存一个token,
     * 同时需要在新建的页面中添加
     * <input type="hidden" name="token" value="${token}">
     * <br/>
     * 保存方法需要验证重复提交的,设置needRemoveToken为true
     * 此时会在拦截器中验证是否重复提交
     * </p>
     * @author: chuanli
     * @date: 2013-6-27上午11:14:02
     *
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AvoidDuplicateSubmission {
        boolean needSaveToken() default false;
        boolean needRemoveToken() default false;
    }

    2. 新建拦截器

    ?

     
    /**
     * <p>
     * 防止重复提交过滤器
     * </p>
     *
     * @author: chuanli
     * @date: 2013-6-27上午11:19:05
     */
    public class AvoidDuplicateSubmissionInterceptor extends HandlerInterceptorAdapter {
        private static final Logger LOG = Logger.getLogger(AvoidDuplicateSubmissionInterceptor.class);
     
        @Override
        public boolean preHandle(HttpServletRequest request,
                HttpServletResponse response, Object handler) throws Exception {
     
            User user = UserUtil.getUser();
            if (user != null) {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                Method method = handlerMethod.getMethod();
     

                AvoidDuplicateSubmission annotation = method.getAnnotation(

                                                            AvoidDuplicateSubmission.class);

                if (annotation != null) {
                    boolean needSaveSession = annotation.needSaveToken();
                    if (needSaveSession) {

                        request.getSession(false).setAttribute("token"

                              TokenProcessor.getInstance().generateToken());

                    }
     
                    boolean needRemoveSession = annotation.needRemoveToken();
                    if (needRemoveSession) {
                        if (isRepeatSubmit(request)) {
                            LOG.warn("please don't repeat submit,[user:" + user.getUsername() + ",url:"
                                    + request.getServletPath() + "]");
                            return false;
                        }
                        request.getSession(false).removeAttribute("token");
                    }
                }
            }
            return true;
        }
     
        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;
        }
     
    }
       

    3. 在Spring中配置

    ?

     
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
       <property name="interceptors">
          <list>
              <bean class="com.sohu.tv.crm.aop.UserLogInterceptor"/>
              <bean class="com.sohu.tv.crm.aop.AvoidDuplicateSubmissionInterceptor"/>
          </list>
       </property>
     
    </bean>

    4. 在相关方法中加入注解:

    ?

     
    @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 {
       

    5.在新建页面中加入

    1
         <input type="hidden" name="token" value="${token}">
  • 相关阅读:
    you must restart adb and eclipse的相关解决办法
    配有Tesla K40c的服务器新装Ubuntu16.04并安装CUDA8.0、Anaconda3、Matlab2016a、OPENCV3.1、CuDNN5.1、MXNet
    MXNet在64位Win7下的编译安装
    [Kinect]XBox One Kinect连接Windows
    64位Win7下编译Python3的计算机视觉库:OpenCV
    64位Win7下安装并配置Python3的深度学习库:Theano
    Noah的学习笔记之Python篇:命令行解析
    Noah的学习笔记之Python篇:函数“可变长参数”
    Noah的学习笔记之Python篇:装饰器
    linux下安装MySQL5.6记录
  • 原文地址:https://www.cnblogs.com/grefr/p/6088517.html
Copyright © 2011-2022 走看看