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)