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}">生成页面唯一编号
分享到:
相关推荐
spring2.5 mvc 错误信息配置 mysql数据库脚本 完整项目,是本人按照spring mvc文档一步步开发完成。
spring2.5 mvc_ibatis2
Spring 2.5 mvc例子 Spring 2.5 mvc例子
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 处理管道使用参考手册
讲述了spring2.0,2.5以及portlet的mvc的搭建以及怎样使用
目前介绍springMVC的资料...本文根据笔者一年多对spring2.5 MVC的学习与实践,将平时的学习笔记进行了整理与完善,对springMVC中涉及到的绝大部分处理管道进行了详细的描述,其中所有列举的配置方式,笔者都做过测试。
精通Spring2.5pdf书籍proSpring2.5
Spring 2.5 基于注解驱动的Spring MVC 开发参考文档
FLEX4+Gilead+BlazeDS+pureMVC+spring2.5 MVC+hibernate3.3+SLF4J+CXF2.3.0 以及相关插件
spring2.5 定时器任务 spring2.5 定时器任务 spring2.5 定时器任务 spring2.5 定时器任务
NULL 博文链接:https://hanqunfeng.iteye.com/blog/606089
Spring2.5的国际化配置 基于浏览器语言的国际化配置 使用Spring的MVC,并且配置中有配置Resource文件 <!-- 资源文件绑定器 --> <bean id="messageSource" class="org.springframework.context.support....
spring2.5的webmvc中的pdfview不支持改包名后的itext库。这是对应的修改版本。可以正常使用itext5.1以及以后版本
struts2+Spring2.5+Spring3.2)实现登录.struts2+Spring2.5+Spring3.2)实现登录.struts2+Spring2.5+Spring3.2)实现登录。
spring 2.5 spring 2.5帮助文档 spring 2.5中文帮助文档 spring帮助文档 spring文档
NULL 博文链接:https://chilongxph.iteye.com/blog/510707
Spring2.5中文框架开发手册Spring2.5中文框架开发手册Spring2.5中文框架开发手册
这是一个struts 1.2 + spring 2.5 + hibernate 3.2框架demo, 运行环境为eclipse 3.2 + tomcat 5.5 + oracle 11g
spring2.5是根据Sping2.5官方文档生成 chm格式