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}">
  • 相关阅读:
    HTML5结构
    HTML5新增的非主体元素header元素、footer元素、hgroup元素、adress元素
    CF GYM 100703G Game of numbers
    CF GYM 100703I Endeavor for perfection
    CF GYM 100703K Word order
    CF GYM 100703L Many questions
    CF GYM 100703M It's complicate
    HDU 5313 Bipartite Graph
    CF 560e Gerald and Giant Chess
    POJ 2479 Maximum sum
  • 原文地址:https://www.cnblogs.com/grefr/p/6088517.html
Copyright © 2011-2022 走看看