对于将Spring、Struts框架进行整合的WEB应用而言,首先需要理解一些基本的原理。
WEB应用程序的核心配置文件是web.xml文件,这个文件被WEB容器在启动时加载。为了让Spring容器随着WEB应用的启动而自动启动,可以借助于ServletContextListener监听器完成,该监听器可以在WEB应用启动时回调自定义方法—该方法就可以启动Spring容器。
Spring提供了一个ContextLoaderListener,该监听器类实现了ServletContextListener接口。该类可以作为Listener使用,它会在创建时自动查找WEB-INF目录下的applicationContext.xml文件;因此,如果只有一个配置文件,并且文件名为applicationContext.xml,则只需要在web.xml文件中增加如下配置即可:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
如果有多个配置文件需要载入,则考虑使用下面的配置方法:
<!-- 指定多个配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml,/WEB-INF/classes/daoContext.xml,/WEB-INF/classes/struts-module-config.xml</param-value>
</context-param>
<!-- 使用ContextLoaderListener初始化Spring容器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
如果没有使用contextConfigLocation指定的配置文件,则Spring自动查找applicationContext.xml配置文件;如果有contextConfigLocation,则利用该参数指定的配置文件。
如果没有找到适合的配置文件,则Spring将无法正常初始化,WEB服务器启动失败。
整合了Spring、Struts2和Hibernate框架的web.xml看上去如下:
web.xml文件自然部署在WEB-INF目录下。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<filter-name>hibernateFilter</filter-name>
<!--处理hibenate的session问题-->
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.chariot.utils.SessionListener</listener-class>
</listener>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>login.htm</welcome-file>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
SSH2整合的工程包和配置文件结构图如下所示:
有五个配置文件需要进行配置:
- applicationContext.xml
- hibernate.cfg.xml
- struts.xml
- init.properties
- log4j.properties
另外还有一个properties文件
- action.properties (这个文件后面再解释其作用)
下面分析一下Spring的配置文件: applicationContext.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: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-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<!-- 引入init.properties中属性 -->
<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:init.properties</value>
</property>
</bean>
<!-- 配置数据源,连接池使用c3p0,详细信息参见hibernate官方文档"基础配置章节"-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" dependency-check="none">
<!--链接数据库所需驱动-->
<property name="driverClass">
<value>${datasource.driverClassName}</value>
</property>
<!--链接数据库的url-->
<property name="jdbcUrl">
<value>${datasource.url}</value>
</property>
<!--链接数据库用户名-->
<property name="user">
<value>${datasource.username}</value>
</property>
<!--链接数据库密码-->
<property name="password">
<value>${datasource.password}</value>
</property>
<!--当连接池中的链接耗尽时c3p0一次同时获得的链接是,默认为 3-->
<property name="acquireIncrement">
<value>${c3p0.acquireIncrement}</value>
</property>
<!--初始化时一次获得3个连接池取值在minPoolSize和maxPoolSize之间,默认为 3-->
<property name="initialPoolSize">
<value>${c3p0.initialPoolSize}</value>
</property>
<!--连接池中保留的最小连接数,默认为 15-->
<property name="minPoolSize">
<value>${c3p0.minPoolSize}</value>
</property>
<!--连接池中保留的最大连接数,默认为 15-->
<property name="maxPoolSize">
<value>${c3p0.maxPoolSize}</value>
</property>
<!--最大空闲时间,60秒未使用则连接池被丢弃,若为0则永远不丢弃,默认为 0-->
<property name="maxIdleTime">
<value>${c3p0.maxIdleTime}</value>
</property>
<!--每秒检查连接池中的空闲链接数,默认为 0-->
<property name="idleConnectionTestPeriod">
<value>${c3p0.idleConnectionTestPeriod}</value>
</property>
<!--
JDBC的标准参数,用于控制数据源内加载的PreparedStatements的数量
但由于缓存中的Statemnts属于单个的connection而不是整个的连接池,所以设置
这个参数需要考虑多方面的因素,如果maxStatements为0怎连接池被关闭,默认为 0
-->
<property name="maxStatements">
<value>${c3p0.maxStatements}</value>
</property>
<!--
c3p0为异步操作,缓存的JDBC通过帮助进程来完成,扩展这些操作有利于提高系统功能, 通过线程实行多个操作同时被执行
-->
<property name="numHelperThreads">
<value>${c3p0.numHelperThreads}</value>
</property>
</bean>
<!-- 配置Hibernate中的SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 引入数据源 -->
<property name="dataSource">
<ref local="dataSource" />
</property>
<!-- 配置Hibernate对应的映射资源 -->
<property name="mappingDirectoryLocations">
<list>
<value>classpath:com/chariot/entity/</value>
</list>
</property>
<!-- 配置Hibernate的属性,包括断言(方言),show_sql等 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
${hibernate.dialect}
</prop>
<prop key="hibernate.jdbc.fetch_size">
${hibernate.jdbc.fetch_size}
</prop>
<prop key="hibernate.jdbc.batch_size">
${hibernate.jdbc.batch_size}
</prop>
<prop key="hibernate.connection.release_mode">
${hibernate.connection.release_mode}
</prop>
<prop key="hibernate.show_sql">
${hibernate.show_sql}
</prop>
</props>
</property>
</bean>
<!--事务管理
定义了一些用来让应用服务器管理事务的方法-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="get*" propagation="REQUIRED" />
<tx:method name="find*" propagation="REQUIRED" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<!--
切面和切点的配置,有关信息后续再讲)
-->
<aop:config>
<aop:pointcut id="allManagerMethod" expression="execution(* com.chariot.daoimpl.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" />
</aop:config>
<!--hibernate操作数据库的模板类-->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!--以上为公共配置不允许随意修改-->
<!--以下各个模块之间为数据访问层的配置-->
<bean id="bugManagerDaoImp" class="com.chariot.daoimpl.BugManagerDaoImp"
parent="hibernateTemplate" />
<bean id="projectManagerDaoImp" class="com.chariot.daoimpl.ProjectManagerDaoImp"
parent="hibernateTemplate" />
<bean id="sampleManagerDaoImp" class="com.chariot.daoimpl.SampleManagerDaoImp"
parent="hibernateTemplate" />
<bean id="studentManagerDaoImp" class="com.chariot.daoimpl.StudentManagerDaoImp"
parent="hibernateTemplate" />
<bean id="userManagerDaoImp" class="com.chariot.daoimpl.UserManagerDaoImp"
parent="hibernateTemplate" />
<!--以下各个模块之间为业务逻辑层的配置-->
<bean id="bugManagerServiceImp" class="com.chariot.serviceimpl.BugManagerServiceImp">
<property name="bugManagerDao" ref="bugManagerDaoImp" />
</bean>
<bean id="projectManagerServiceImp" class="com.chariot.serviceimpl.ProjectManagerServiceImp">
<property name="projectManagerDao" ref="projectManagerDaoImp" />
<property name="pager" ref="pager"/>
<property name="tbDel" ref="tbDel"/>
</bean>
<bean id="sampleManagerServiceImp" class="com.chariot.serviceimpl.SampleManagerServiceImp">
<property name="sampleManagerDao" ref="sampleManagerDaoImp" />
</bean>
<bean id="studentManagerServiceImp" class="com.chariot.serviceimpl.StudentManagerServiceImp">
<property name="studentManagerDao" ref="studentManagerDaoImp" />
</bean>
<bean id="userManagerServiceImp" class="com.chariot.serviceimpl.UserManagerServiceImp">
<property name="userManagerDao" ref="userManagerDaoImp" />
</bean>
<!--以下各个模块之间为数据展现层的配置-->
<bean id="bugManagerAction" class="com.chariot.action.BugManagerAction">
<property name="bugManagerService" ref="bugManagerServiceImp"></property>
<property name="quesManage" ref="quesManage"></property>
<property name="student" ref="student"></property>
<property name="user" ref="user"></property>
<property name="del" ref="del"></property>
<property name="item" ref="item"></property>
</bean>
<bean id="projectManagerAction" class="com.chariot.action.ProjectManagerAction">
<property name="projectManagerService" ref="projectManagerServiceImp" />
<property name="tbItem" ref="tbItem"/>
<property name="tbItemPerson" ref="tbItemPerson"/>
<property name="tbItemGroup" ref="tbItemGroup"/>
<property name="tbTask" ref="tbTask"/>
<property name="tbStudent" ref="tbStudent"/>
<property name="tbDel" ref="tbDel"/>
<property name="tbTaskScore" ref="tbTaskScore"/>
</bean>
<bean id="sampleManagerAction" class="com.chariot.action.SampleManagerAction">
<property name="sampleManagerService" ref="sampleManagerServiceImp" />
<property name="tbCases" ref="tbCase"/>
<property name="tbCases2" ref="tbCase"/>
<property name="download" ref="download"/>
</bean>
<bean id="studentManagerAction" class="com.chariot.action.StudentManagerAction">
<property name="studentManagerService" ref="studentManagerServiceImp" />
<property name="download" ref="download"/>
</bean>
<bean id="userManagerAction" class="com.chariot.action.UserManagerAction">
<property name="userManagerService" ref="userManagerServiceImp" />
<property name="tbUser" ref="tbUser"/>
<property name="tbDel" ref="tbDel"/>
<property name="tbStudent" ref="tbStudent"/>
</bean>
<!-- bean的配置 -->
<bean id="loginCheckInterceptor" class="com.chariot.utils.LoginCheckInterceptor">
<property name="admin" ref="tbUser"/>
<property name="student" ref="tbStudent"/>
<property name="teacher" ref="tbUser"/>
</bean>
<!-- bean的配置 -->
<!--Jean-->
<bean id="tbCase" class="com.chariot.entity.TbCase"/>
<bean id="quesManage" class="com.chariot.entity.TbQuesManage"></bean>
<bean id="user" class="com.chariot.entity.TbUser"></bean>
<bean id="student" class="com.chariot.entity.TbStudent"></bean>
<bean id="item" class="com.chariot.entity.TbItem"></bean>
<bean id="del" class="com.chariot.entity.TbDel"></bean>
<bean id="tbUser" class="com.chariot.entity.TbUser"/>
<bean id="tbDel" class="com.chariot.entity.TbDel"/>
<bean id="tbStudent" class="com.chariot.entity.TbStudent"/>
<!--文件下载的struts的Action配置-->
<!--Jean-->
<bean id="pager" class="com.chariot.utils.Pager"/>
<bean id="tbItem" class="com.chariot.entity.TbItem"/>
<bean id="tbItemPerson" class="com.chariot.entity.TbItemPerson"/>
<bean id="tbItemGroup" class="com.chariot.entity.TbItemGroup"/>
<bean id="tbTask" class="com.chariot.entity.TbTask"/>
<bean id="tbTaskScore" class="com.chariot.entity.TbTaskScore"/>
<!--文件上传的struts的Action配置-->
<bean id="upload" class="com.chariot.file.action.UploadAction" />
<!--文件下载的struts的Action配置-->
<bean id="download" class="com.chariot.file.action.DownloadAction" />
</beans>
init.properties文件配置
#MySQL Database
datasource.type=mysql
datasource.driverClassName=com.mysql.jdbc.Driver
datasource.url=jdbc\:mysql\://127.0.0.1/数据库名字
datasource.username=数据库用户名
datasource.password=数据库用户密码
datasource.maxActive=10
datasource.maxIdle=2
datasource.maxWait=120000
datasource.whenExhaustedAction=1
datasource.testOnBorrow=true
datasource.testOnReturn=false
c3p0.acquireIncrement=3
c3p0.initialPoolSize=3
c3p0.idleConnectionTestPeriod=900
c3p0.minPoolSize=2
c3p0.maxPoolSize=50
c3p0.maxStatements=100
c3p0.numHelperThreads=10
c3p0.maxIdleTime=600
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.jdbc.batch_size=25
hibernate.jdbc.fetch_size=50
hibernate.show_sql=true
hibernate.connection.release_mode=after_transaction
Hibernate的配置,配置文件为:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="connection.url">
jdbc:mysql://127.0.0.1:3306/manager_platform
</property>
<property name="connection.username">root</property>
<property name="connection.password">seagal890</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="myeclipse.connection.profile">mysql</property>
<mapping resource="com/chariot/entity/TbCase.hbm.xml" />
<mapping resource="com/chariot/entity/TbDel.hbm.xml" />
<mapping resource="com/chariot/entity/TbItem.hbm.xml" />
<mapping resource="com/chariot/entity/TbItemGroup.hbm.xml" />
<mapping resource="com/chariot/entity/TbItemPerson.hbm.xml" />
<mapping resource="com/chariot/entity/TbItemScore.hbm.xml" />
<mapping resource="com/chariot/entity/TbQuesManage.hbm.xml" />
<mapping resource="com/chariot/entity/TbStudent.hbm.xml" />
<mapping resource="com/chariot/entity/TbStuOpinion.hbm.xml" />
<mapping resource="com/chariot/entity/TbTask.hbm.xml" />
<mapping resource="com/chariot/entity/TbTaskScore.hbm.xml" />
<mapping resource="com/chariot/entity/TbUser.hbm.xml" />
</session-factory>
</hibernate-configuration>
Struts2配置文件为:struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<constant name="struts.i18n.encoding" value="GBK"/>
<include file="struts_BugManagerAction.xml"/>
<include file="struts_ProjectManagerAction.xml"/>
<include file="struts_SampleManagerAction.xml"/>
<include file="struts_StudentManagerAction.xml"/>
<include file="struts_UserManagerAction.xml"/>
<include file="struts_FileDownUpLoad.xml"/>
</struts>
log4j配置文件:log4j.properties
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.rootLogger=warn, stdout
action.properties配置文件
bugManagerAction=bugManagerAction
projectManagerAction=projectManagerAction
sampleManagerAction=sampleManagerAction
studentManagerAction=studentManagerAction
userManagerAction=userManagerAction
细节后续补充。