`

struts2之防止表单重复提交

 
阅读更多

struts.xml配置文件

 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	
	<!--  指定Web应用的默认编码集,相当于调用HttpServletRequest的setCharacterEncoding方法 --> 
  	<constant name="struts.i18n.encoding" value="UTF-8" />
  	
  	<!--  设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 --> 
  	<constant name="struts.serve.static.browserCache" value="false" />
  	
  	<!--  当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 --> 
  	<constant name="struts.configuration.xml.reload" value="true" /> 
	
    <!-- 开发模式下使用,这样可以打印出更详细的错误信息 -->
    <constant name="struts.devMode" value="true" />
    
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
   	
   	<!-- 默认的视图主题 -->
    <constant name="struts.ui.theme" value="simple" />
    <constant name="struts.objectFactory" value="spring" />
    
 	<package name="default" extends="struts-default,json-default,jfreechart-default,spring-default">
 		
 		<default-action-ref name="index" />
		
		<!-- 定义全局页面输出信息 -->
		<global-results>
			<result name="message">/WEB-INF/page/message.jsp</result>
		</global-results>
		
        <global-exception-mappings>
            <exception-mapping exception="java.lang.Exception" result="error"/>
        </global-exception-mappings>
 			        
        <!-- struts2在防止表单重复提交的拦截中有2个,分别是:token,tokenSession。tokenSession继承token而来。     
        	   通常情况下,使用tokenSession客户端感觉会比较友好。 -->    
        <action name="token" class="loginAction">
        	<interceptor-ref name="defaultStack" />
        	<interceptor-ref name="token" />
        	<!-- 如果重复提交,跳转到error.jsp页面 -->
        	<result name="invalid.token">/WEB-INF/page/error.jsp</result>
        	<result>/WEB-INF/page/message.jsp</result>
        </action>
        
        <action name="tokenSession" class="loginAction">
        	<interceptor-ref name="defaultStack" />
        	<interceptor-ref name="tokenSession" />
        	<!-- 如果重复提交,不会跳转到error.jsp页面 -->
        	<result name="invalid.token">/WEB-INF/page/error.jsp</result>
        	<result>/WEB-INF/page/message.jsp</result>
        </action>
    </package>

</struts>

 

 applicationContext.xml配置文件

 

<?xml version="1.0" encoding="UTF-8"?>

<beans  xmlns="http://www.springframework.org/schema/beans"
		xmlns:context="http://www.springframework.org/schema/context"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:aop="http://www.springframework.org/schema/aop"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="http://www.springframework.org/schema/beans
				http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
				http://www.springframework.org/schema/context
				http://www.springframework.org/schema/context/spring-context-3.1.xsd
				http://www.springframework.org/schema/tx
				http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
				http://www.springframework.org/schema/aop
				http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
	
	<!-- 添加对Annotation的支持 -->
	<context:annotation-config />
	
	<!-- 配置数据源 -->
    <context:property-placeholder location="classpath:database.properties"/>

	<!-- DataSource -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
		<property name="driverClass" value="${dataSource.driverClassName}" />
     	<property name="jdbcUrl" value="${dataSource.url}" />
     	<property name="user" value="${dataSource.username}" />
     	<property name="password" value="${dataSource.password}" />
     	
     	<!-- 当连接池中的连接用完时,C3P0一次性创建新连接的数目2 -->
	    <property name="acquireIncrement" value="5"></property>
	    <!-- 初始化时创建的连接数,必须在minPoolSize和maxPoolSize之间 -->
        <property name="initialPoolSize" value="10"></property>
        <property name="minPoolSize" value="5"></property>
        <property name="maxPoolSize" value="20"></property>
        <!-- 最大空闲时间,超过空闲时间的连接将被丢弃  
        [需要注意:mysql默认的连接时长为8小时(28800)【可在my.ini中添加 wait_timeout=30(单位秒)设置连接超时】,这里设置c3p0的超时必须<28800]   -->  
        <property name="maxIdleTime" value="300"></property>
        <!-- 每60秒检查连接池中的空闲连接 -->
        <property name="idleConnectionTestPeriod" value="60"></property>
        <!-- jdbc的标准参数  用以控制数据源内加载的PreparedStatement数量,但由于预缓存的Statement属 于单个Connection而不是整个连接 -->
        <property name="maxStatements" value="20"></property>
     </bean>

	<!-- SessionFactory -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
	     <property name="dataSource" ref="dataSource"/>
	     <!--ORM映射文件:mappingResources-->
	     <!-- ORM目录 -->
		 <property name="mappingResources">
		    <list>
		      <value>cn/itcast/bean/Person.hbm.xml</value>
		    </list>
		 </property>
	     <property name="hibernateProperties">
	     	<props>
	     		<prop key="hibernate.autoReconnect">true</prop>
	     		<!-- 数据库方言 -->
	     		<prop key="hibernate.dialect">${dataSource.dialect}</prop>
	     		<prop key="hibernate.hbm2ddl.auto">${dataSource.auto}</prop>
	     		<!-- 控制台是否打印SQL -->
	     		<prop key="hibernate.show_sql">${dataSource.show_sql}</prop>
				<!-- 控制台是否格式化SQL语句显示样式 -->
				<prop key="hibernate.format_sql">${dataSource.format_sql}</prop>
				
				<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
				<!-- 是否使用二级缓存 -->
				<prop key="hibernate.cache.use_second_level_cache">true</prop>
				<!-- 使用查询缓存 -->
				<prop key="hibernate.cache.use_query_cache">true</prop>
				
				<!-- QueryCacheFactory的实现类  -->
				<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
				
				<prop key="hibernate.cache.use_structured_entries">true</prop>
	     	</props>
	     </property>
	</bean>
	
	<!-- TransactionManager -->
	<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
	  	<property name="sessionFactory" ref="sessionFactory"/>
	</bean>
	<tx:annotation-driven transaction-manager="txManager"/>
	
	<bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"/>
	
	<bean id="loginAction" class="cn.itcast.web.PersonManageAction" scope="prototype"/>

</beans>

 

 PersonManageAction类

 

package cn.itcast.web;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

import cn.itcast.bean.Person;
import cn.itcast.service.PersonService;


public class PersonManageAction extends ActionSupport{
	/**
	 * @Controller("loginAction")
	 */
	private static final long serialVersionUID = -1625398401024059186L;
	@Resource PersonService personService;
	
	private String name;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String execute() throws Exception {
		HttpServletRequest request = ServletActionContext.getRequest();
		personService.save(new Person(getName()));
		request.setAttribute("message", "添加成功");
		return "message";
	}
}

 

index.jsp表单页面

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"  %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>    
    <!-- 防止表单重复提交,记得在form表单里填上<s:token></s:token>      -->
    <!-- action="token"、action="tokenSession" -->
    <s:form action="token" method="post">
    	名称:<s:textfield name="name" id="name" /><s:token></s:token>
    	<input type="submit" value="发送">
    </s:form>
    
    <s:form action="tokenSession" method="post">
    	名称:<s:textfield name="name" id="name" /><s:token></s:token>
    	<input type="submit" value="发送">
    </s:form>
  </body>
</html>

 

 error.jsp表单重复提交提示页面

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'error.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    	<font style="color: red;">您已经提交了表单,请不要重复提交。</font>
  </body>
</html>

 

这个例子是在“关于struts2.3.1.2_spring3.1.1_hibernate4.1.2整合总结”例子的基础上加的代码。

分享到:
评论

相关推荐

    struts2 防止表单重复提交的例子

    Struts2框架提供了一种解决方案,即使用Token机制来防止表单的重复提交。以下是对这个主题的详细说明: 1. **表单重复提交问题**:当用户在提交表单时,由于网络延迟或用户误操作,可能会导致同一个表单被多次提交...

    struts2利用token防止表单重复提交(源代码)

    struts2防止表单重复提交,利用struts的拦截器tokenSession,轻轻松松解决表单重复提交的问题。 附件为源代码,后台延迟了3秒,可直接在web服务器下部署运行,输入用户名和密码后,多点几次提交按钮,然后看控制台...

    Struts2解决表单重复提交

    Struts2作为一个流行的Java Web框架,为解决表单重复提交提供了多种方法。 首先,关于表单重复提交的原因,有以下几点: 1. 服务器或网络延迟导致用户多次点击提交按钮。 2. 用户在表单提交后刷新浏览器页面。 ...

    Struts2防止表单重复提交示例

    在Struts2中防止表单重复提交的过程主要包括以下几个步骤: 1. **生成Token**:当用户发起表单请求时,服务器会生成一个唯一的Token并将其存储在服务器的会话(Session)中,同时将这个Token作为隐藏字段放入到HTML...

    Struts2防止重复提交解决方案

    在Struts2中,防止重复提交是一个重要的问题,因为它可能导致数据不一致性和服务器资源的浪费。本文将详细介绍如何在Struts2中解决这个问题,以及相关的技术概念。 首先,我们要理解Struts2中的拦截器(Interceptor...

    struts2防止表单重复提交--重定向

    下面将详细解释Struts2如何通过重定向来防止表单重复提交。 首先,理解表单重复提交的场景:用户在提交表单后,由于网络延迟或其他原因,可能会无意中多次点击提交按钮。如果服务器没有处理这些重复请求,那么相同...

    防止表单重复提交

    本篇文章将深入探讨如何防止表单重复提交,主要关注于基于Struts2框架的解决方案。 首先,理解表单重复提交的原因。用户在点击提交按钮后,如果网络延迟或用户误操作导致页面刷新或再次点击提交,就可能发生重复...

    struts token机制解决表单重复提交

    Struts Token机制是一种防止表单重复提交的有效策略,尤其在处理关键操作时,如金融交易或数据修改,防止用户意外或恶意多次点击提交按钮导致的数据重复性问题。下面将详细介绍Struts Token的工作原理、实现方式及其...

    struts2令牌解决页面重复提交问题

    Struts2是一个流行的Java web框架,它...总的来说,Struts2的令牌机制是通过生成和验证令牌来防止重复提交和CSRF攻击的有效方式。开发者应当理解其工作原理,并在需要的地方正确使用,以提高应用程序的安全性和稳定性。

    Struts之Token解决表单那重复提交

    综上所述,Struts框架通过Token机制有效地解决了表单重复提交的问题,提供了更健壮的Web应用安全性。正确理解和应用这一机制对于Java Web开发者来说至关重要。在实际项目中,结合其他防御策略,如CSRF防护,可以...

    【原创】Struts2防止表单重复提交.doc

    ### Struts2防止表单重复提交的技术解析 #### 一、引言 在Web应用程序开发过程中,表单重复提交是一个常见的问题,特别是在网络环境不稳定或用户误操作的情况下。这种重复提交不仅可能导致数据冗余,还可能引起事务...

    Struts2 表单 重复提交

    "防止表单重复提交 token"是Struts2提供的一种解决方案,通过在请求中加入一个唯一的token来确保请求的唯一性和一致性。 首先,我们来看如何实现这个机制。在Struts2中,我们可以使用拦截器(Interceptor)来实现...

    Struts2文件上传下载和表单重复提交问题

    在实际应用中,文件上传和下载以及防止表单重复提交是两个常见的需求,同时也是开发者必须掌握的重要技能。 1. **文件上传** 文件上传功能在Struts2中通过`Struts2`提供的插件来实现,主要依赖于`Apache Commons ...

    Servlet、Struts、SpringMVC对于表单重复提交的解决方案

    总结来说,Servlet、Struts和SpringMVC都提供了各自的解决方案来防止表单重复提交,主要方法包括使用Session、令牌机制、重定向和拦截器等。开发者可以根据项目需求选择合适的方式来实现,确保应用的稳定性和数据...

    struts+token机制解决表单重复提交

    Struts是Java Web开发中的一款流行MVC框架,它简化了构建基于JSP的Web应用程序的过程。然而,Web应用在处理表单提交...通过对这些代码的学习和研究,开发者能够熟练地在自己的项目中应用Struts+Token防止表单重复提交。

    struts数据回显、模型驱动、防止表单重复提交

    本主题将深入探讨Struts框架中的数据回显、模型驱动以及如何防止表单重复提交,这些都是在实际开发中非常关键且实用的技术点。 1. 数据回显: 数据回显是指在用户提交表单后,服务器端处理数据并返回结果页面时,将...

    struts2防止重复提交

    Struts2提供了几种策略来防止表单的重复提交,确保请求的唯一性和事务的一致性。 一、令牌(Token)机制 Struts2的Token插件是防止重复提交的一种常见方法。这里的"Strut2Token"很可能是指这个插件的应用。它的...

Global site tag (gtag.js) - Google Analytics