Spring2.5MVC实现控制重复提交

转载 2012年03月28日 10:39:17

1.实现原理:

  提交表单时,从session中取出当前的token值与保存在页面上token值进行比较,如果相等,可以保存表单数据,并将新生成的token保存到session中,如果不相等,则判断为重复提交。

本例采用spring的HandlerInterceptorAdapter拦截器来实现控制重复提交。

 

2.spring 配置:spring-servlet.xml

  <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
    
    <!--
        - The controllers are autodetected POJOs labeled with the @Controller annotation.
    -->
 <context:component-scan base-package="com.allwin" use-default-filters="false" >  
  <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
 </context:component-scan>
 
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
     <property name="webBindingInitializer">   
         <bean class="com.allwin.erp.web.action.common.WebBindingObjectRegister" />   
     </property> 
    </bean>

    <!--
        - This bean configures the 'prefix' and 'suffix' properties of 
        - InternalResourceViewResolver, which resolves logical view names 
        - returned by Controllers. For example, a logical view name of "vets" 
        - will be mapped to "/WEB-INF/jsp/vets.jsp".
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
       p:prefix="/WEB-INF/jsp/" 
       p:suffix=".jsp" />
       
    <context:annotation-config/>
 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
        <property name="defaultEncoding"><value>UTF-8</value></property>    
        <property name="maxUploadSize">
            <value>52428800</value>  
        </property>  
 </bean>
 <!--
        - This bean controller double submit
    -->
 <bean id="doubleSubmitInterceptor" class="com.allwin.erp.web.action.common.DoubleSubmitInterceptor">  
 <!--
        - 配置要拦截的url
    -->

    

 <property name="mappingURL" value=".*/(save|approve|active)\.do" /> 
     <property name="viewURL" value=".*/(view|copy)\.do" />   
 </bean>  
 <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">  
     <property name="interceptors">  
         <list>  
             <ref bean="doubleSubmitInterceptor"/>  
         </list>  
      </property>  
 </bean>  
</beans>

红色字体部分是配置判断重复提交的拦截器

 

3.java类HandlerInterceptorAdapter.java

 

public class DoubleSubmitInterceptor extends HandlerInterceptorAdapter {
 
 // matches URL
 private String mappingURL;
 private String viewURL;
 // page number
 private static long pageNum = 0l;
 /**
  * summary: filter request(view/save/approve/active method)
  * 
  * @param : request HttpServletRequest
  * @param : response HttpServletResponse
  * @param : handler Object
  *
  * @return boolean true:normal false:double submit 
  */
 @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {   
  String url=request.getRequestURL().toString();   
  // 设置页面编号
  if(url.matches(viewURL)){
   if(Strings.isEmpty(request.getParameter("pageNum"))){
    request.getSession().setAttribute("pageNum",++pageNum);
   }
  }
        if(url.matches(mappingURL)){
         // 设置当前token名称(即session中存放token数据的key值)
         String tokenName = handler.getClass().getSimpleName() + request.getParameter("pageNum");
         // 取得当前session中的token值
         String sessionToken = (String)request.getSession().getAttribute(tokenName);
         if(sessionToken == null || sessionToken.equals("")){
          // 生成新的token
          long date = new Date().getTime();
          request.getSession().setAttribute(tokenName, request.getSession().getId() + String.valueOf(date));
          request.getSession().setAttribute("token", request.getSession().getId() + String.valueOf(date));
          request.getSession().setAttribute("pageNum",request.getParameter("pageNum"));
          return true;
         } else { // 判断是否重复提交(如果session中的token值与request中的token值不一致则判定重复提交)
    String requestToken = (String)request.getParameter("token");
          if(requestToken == null || !requestToken.equals(sessionToken)){           
           request.getRequestDispatcher("/front/doubleSubmit.jsp").forward(request, response);   
           return false;
          } else {
           // 替换旧的token
           long date = new Date().getTime();
           request.getSession().setAttribute(tokenName, request.getSession().getId() + String.valueOf(date));
           request.getSession().setAttribute("token", request.getSession().getId() + String.valueOf(date));
           request.getSession().setAttribute("pageNum",request.getParameter("pageNum"));
           return true;
          }
         }
        } else {
         return true;
        }
    }   
 /**
  * @param mappingURL the mappingURL to set
  */
 public void setMappingURL(String mappingURL) {
  this.mappingURL = mappingURL;
 }
 /**
  * @param viewURL the viewURL to set
  */
 public void setViewURL(String viewURL) {
  this.viewURL = viewURL;
 }
}

 

4.jsp

在保存数据表单的jsp中加如两个隐藏变量

<input type="hidden" name="token" id="token" value="${token}"> session中的token值
<input type="hidden" name="pageNum" id="pageNum" value="${pageNum}">生成页面唯一编号

 




你这东西貌似不能完全避免重复提交啊。在你替换旧的token之前,可能第二次提交的线程已经过了条件判断。

条件判断那边需要加一个同步锁。



Spring MVC 学习笔记(二) 基于spring2.5注解实现的spring MVC项目

建立web项目 导入jar包(spring.jar, spring-webmvc.jar, commons-logging.jar。其他jar包为hibernate相关jar包) 3 . 修改web....

Spring MVC 学习笔记(二) 基于spring2.5注解实现的spring MVC项目

建立web项目导入jar包(spring.jar, spring-webmvc.jar, commons-logging.jar。其他jar包为hibernate相关jar包) 3 . 修改we...

Spring MVC 学习笔记(一) 基于spring2.5的纯xml配置

写在前面的小尾巴 其实这个还有spring都是看尚学堂的视频 基本差不离 人家交的就是好 恩 这个就是做个学习笔记什么的 以上 常见MVC框架比较 运行性能上: Jsp+servlet>s...

spring2.5 mvc 以及spring3.0 mvc ajax+json

闲来无事学习了一下spring mvc 以及2.5、3.0

DWR3.0+Spring2.5实现Comet服务器到浏览器的消息推送

网上找到不少相关例子,不过大部分是dwr2的例子,效果一般,研究了一下dwr3.0相关内容,做了个DEMO,实现了向一个或多个精确目标推送内容。重点在于向ScriptSessionManager中加入...

使用Spring2.5的Autowired实现注释型的IOC

使用Spring2.5的新特性——Autowired可以实现快速的自动注入,而无需在xml文档里面添加bean的声明,大大减少了xml文档的维护。(偶喜欢这个功能,因为偶对xml不感冒)。      ...
  • wsm106
  • wsm106
  • 2011年08月22日 09:18
  • 400

ActiveMQ5.4.2+Spring2.5实现异步邮件

(1)applicationContext.xml 添加命名空间xmlns:amq及对应的schemaLocation

spring2.5 mvc_ibatis2

  • 2015年10月29日 11:24
  • 9.83MB
  • 下载

使用Spring2.5的Autowired实现注释型的IOC

 使用Spring2.5的新特性——Autowired可以实现快速的自动注入,而无需在xml文档里面添加bean的声明,大大减少了xml文档的维护。(偶喜欢这个功能,因为偶对xml不感冒)。     ...

Apache CXF2+Spring2.5轻松实现WebService

点击打开链接 1.概述 CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Trans...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Spring2.5MVC实现控制重复提交
举报原因:
原因补充:

(最多只允许输入30个字)