`
yufeng521000
  • 浏览: 6836 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

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

阅读更多

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/beans http://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}">生成页面唯一编号

 

分享到:
评论
10 楼 cq.ronadlo 2011-03-11  
那个我想问问高人  查询的时候都是Manager.getById(id);  那做登录的话不是要查 id和密码么  怎么办 我是freshman    cq.ronadlo@gmail.com
9 楼 魔力猫咪 2010-04-20  
slaser 写道
魔力猫咪 写道
一般重复提交都是提交完了,转到结果页面。然后又刷新页面。因为页面的URL其实是提交地址,造成重复提交。如果处理完提交后不是forward而是redirect,那么是否可以避免重复提交呢?

这个也未必的,有些系统你点下提交按钮,它会顿一下,这下有些用户就会狂点提交按钮。

这个倒好说。提交的时候锁定提交按钮就可以。刷新页面因为是查询页面的url,也不会造成重复提交。
8 楼 slaser 2010-04-20  
魔力猫咪 写道
一般重复提交都是提交完了,转到结果页面。然后又刷新页面。因为页面的URL其实是提交地址,造成重复提交。如果处理完提交后不是forward而是redirect,那么是否可以避免重复提交呢?

这个也未必的,有些系统你点下提交按钮,它会顿一下,这下有些用户就会狂点提交按钮。
7 楼 魔力猫咪 2010-04-19  
一般重复提交都是提交完了,转到结果页面。然后又刷新页面。因为页面的URL其实是提交地址,造成重复提交。如果处理完提交后不是forward而是redirect,那么是否可以避免重复提交呢?
6 楼 slaser 2010-04-19  
条件判断那边需要加一个同步锁。
5 楼 slaser 2010-04-19  
你这东西貌似不能完全避免重复提交啊。在你替换旧的token之前,可能第二次提交的线程已经过了条件判断。
4 楼 ssuupv 2010-04-19  
针对spring mvc里面的方法能拦截吗?
3 楼 fancyboy2050 2010-03-26  
兄弟能把你的帖子编辑下么?眼花缭乱。
2 楼 yufeng521000 2010-03-25  
希望大家回复一下,有不足的地方,请指出来! 谢谢
1 楼 yufeng521000 2010-03-24  
希望大家提出宝贵意见 谢谢!

相关推荐

    spring2.5 mvc 完整项目

    《Spring 2.5 MVC 完整项目:深入解析与实践》 在IT行业中,Spring框架作为Java领域的重要支柱,其MVC(Model-View-Controller)模块在Web应用程序开发中占据着举足轻重的地位。本文将针对“Spring 2.5 MVC 完整...

    spring2.5 mvc_ibatis2

    总结,Spring 2.5 MVC与iBatis 2的整合应用,既保留了Spring MVC的灵活控制,又充分利用了iBatis的SQL定制能力,是企业级开发中常见的技术栈。理解并掌握这两者的结合,能够提升开发效率,打造高性能的Web应用。

    Spring2.5MVC--基于注解的附件上传

    这篇博客"Spring2.5 MVC -- 基于注解的附件上传"详细介绍了如何在Spring MVC 2.5中实现这一功能。 首先,我们需要了解Spring MVC中处理文件上传的基本概念。文件上传主要涉及到两个组件:`MultipartResolver`和`@...

    spring2.0MVC+spring2.5MVC+portletMVC

    Spring MVC是Spring框架的核心部分,用于构建Web应用程序的模型-视图-控制器(MVC)架构。本主题将深入探讨Spring 2.0、2.5版本的MVC特性和Portlet MVC的相关知识。 首先,Spring 2.0在MVC方面引入了显著的改进,...

    Spring 2.5 mvc例子

    Spring MVC 是 Spring 框架的一个重要组成部分,它是一个用于构建 Web 应用程序的模型-视图-控制器(MVC)框架。在 Spring 2.5 版本中,这个框架已经相当成熟,为开发者提供了强大的功能和灵活的配置选项。 ### 1. ...

    spring webmvc struts 2.5 很难找的依赖包

    spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 ...

    Spring2.5 MVC 处理管道使用参考手册

    在Spring 2.5 MVC中,还可以利用拦截器(HandlerInterceptor)对请求进行预处理和后处理,实现如权限检查、日志记录等功能。拦截器通过实现HandlerInterceptor接口并配置在DispatcherServlet中,可以在请求处理前后...

    精通Spring2.5pdf书籍proSpring2.5

    《精通Spring2.5》是一本深度探讨Spring框架的权威指南,主要针对Spring 2.5版本进行深入解析。Spring是Java企业级应用开发中最受欢迎的框架之一,它以其轻量级、模块化的设计,以及对IoC(Inversion of Control,...

    Spring2.5-中文参考手册chm

    Spring2.5版本是该框架的一个重要里程碑,它在2008年发布,带来了许多新特性和改进,提升了开发者在构建应用程序时的灵活性和效率。 **依赖注入(DI)和控制反转(IoC)** Spring的核心特性之一是依赖注入(Dependency...

    spring2.5的所有jar包

    9. **事务管理**:Spring 2.5的事务管理支持包括编程式和声明式两种方式,可以在不侵入业务代码的情况下实现事务的控制。 10. **国际化(i18n)支持**:Spring 2.5提供了更好的国际化支持,使得应用可以轻松地根据...

    Spring2.5 MVC 处理管道使用参考手册V1.0.chm

    目前介绍springMVC的资料...本文根据笔者一年多对spring2.5 MVC的学习与实践,将平时的学习笔记进行了整理与完善,对springMVC中涉及到的绝大部分处理管道进行了详细的描述,其中所有列举的配置方式,笔者都做过测试。

    Spring2.5 源代码

    Spring 2.5在MVC方面有许多改进,包括对注解的支持,比如`@RequestMapping`、`@Controller`等,使得控制器的定义更加简洁。 7. **国际化(i18n)与本地化(l10n)**: Spring 2.5提供了强大的本地化支持,允许...

    Apache CXF2+Spring2.5轻松实现WebService

    Apache CXF和Spring提供了丰富的扩展点,可以集成如Spring Security来控制访问权限,使用Spring AOP来处理事务,以及通过CXF的拦截器机制来实现自定义的日志、验证等功能。 总结来说,Apache CXF 2与Spring 2.5的...

    spring2.5中文文档

    9. **JSR-303 Bean验证**:Spring 2.5开始支持JSR-303标准的bean验证,可以通过注解实现数据校验。 10. **Spring与其他框架的整合**:Spring 2.5增强了与其他框架的集成,如MyBatis、Quartz、EJB等,使得开发者可以...

    Spring2.5-中文参考手册chm.zip

    这个"Spring2.5-中文参考手册chm.zip"文件包含了关于Spring 2.5版本的详细中文指南,对于学习和理解Spring框架具有很高的价值。 Spring框架的核心特性包括依赖注入(Dependency Injection,DI)、面向切面编程...

    spring 2.5中文帮助文档

    通过阅读《Spring2.5-中文参考手册.chm》这份文档,开发者可以深入了解Spring 2.5的各种特性和用法,解决实际开发中遇到的问题,提升开发效率。文档不仅包含详细的API参考,还包含丰富的示例和最佳实践指导,是学习...

    Spring 2.5 基于注解驱动的Spring MVC

    Spring 2.5引入了一种基于注解的新方式来驱动Spring MVC框架,使得开发者能够更加简洁、直观地配置和管理控制器。这一变化显著提升了开发效率,减少了XML配置文件的复杂性,同时也使得代码更加模块化。 ### 1. 基于...

    spring 2.5框架图

    4. **Web包**:Spring 2.5的Web模块提供了一个全面的MVC框架,支持RESTful风格的Web服务。该模块还包括Servlet监听器、过滤器以及视图解析器等,帮助构建基于HTTP的Web应用。此外,Spring 2.5引入了...

    传智播客spring2.5源代码

    9. **Web应用增强**:Spring 2.5在MVC框架中引入了诸如`@RequestMapping`、`@RequestParam`等注解,简化了控制器方法的映射和参数绑定。 10. **数据访问增强**:Spring 2.5增强了对JDBC、Hibernate、JPA等数据访问...

Global site tag (gtag.js) - Google Analytics