Strut1.3+Sprin2.5+Hibernate3.3集成
1.添加jar文件
Hibernate3.3核心安装包下的
/-----------------------------------/hibernate3.jarlib\required\*.jarlib\optional\ehcache-1.2.3.jarhibernate注解安装包下的lib\test\slf4j-log4j12.jar/-----------------------------------/Spring安装包下的/-----------------------------------/dist\spring.jardist\modules\spring-webmvc-struts.jarlib\jakaarte-commons\commons-logging.jar、commons-dbcp.jar、commons-pool.jarlib\aspectj\aspectjweaver.jar 、 aspectjrt.jarlib\cglib\cglib-nodep-2.1.3.jarlib\j2ee\common-annoutations.jarlib\log4j\log4j-1.2.15.jar/------------------------------------/数据库驱动2. 配置beans.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:context="http://www.springframework.org/schema/context" 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/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <!--导入外部properties --> <context:property-placeholder location="classpath:jdbc.properties" /> <!--配置数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driverClassName}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> <!--连接池启动时的初始值 --> <property name="initialSize" value="${initialSize}" /> <!--连接池的最大值 --> <property name="maxActive" value="${maxActive}" /> <!--最大空闲值,当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释 放一部分一直减少到maxIdle为止 --> <property name="maxIdle" value="${maxIdle}" /> <!--最小空闲值,当经空闲的连接邵谊阀值时,连接池就会申请一些连接, 以免洪峰来时来不及申请 --> <property name="minIdle" value="${minIdle}" /> </bean><bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" /> <property name="mappingResources"> <list> <value>cn/soldier/bean/Person.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <!-- 指定数据库方言 --> <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLInnoDBDialect </prop> <!-- 是否根据需要每次自动创建数据库 --> <prop key="hibernate.hbm2ddl.auto">update</prop> <!-- 显示Hibernate持久化操作所生成的SQL --> <prop key="hibernate.show_sql">true</prop> <!-- 将SQL脚本进行格式化后再输出 --> <prop key="hibernate.format_sql">false</prop><!-- <prop key="hibernate.cache.use_second_level_cache">true</prop> -->
<!-- <prop key="hibernate.cache.use_query_cache">true</prop> --> <!-- <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> --> </props> </property> </bean><!--配置事务管理器 -->
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean><!--启用@Transaction注解的支持- -->
<tx:annotation-driven transaction-manager="txManager" /> <!--使用field方法注入依赖对象 --> <context:annotation-config /> <!-- --> <bean id="personService" class="cn.soldier.service.impl.PersonServiceBean"></bean></beans>3.新建实体bean Person
package cn.soldier.bean;Person.java public class Person { private Long id; private String name;public Person() {
}public Person(String name) {
this.name = name; }public Person(Long id, String name) {
this.id = id; this.name = name; }public Long getId() {
return id; }public void setId(Long id) {
this.id = id; }public String getName() {
return name; }public void setName(String name) {
this.name = name; }public String toString() {
return "Person [id=" + id + " name=" + name + "]"; }}
4.建立对应的数据库映射Person.hbm.xml<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.soldier.bean"><class name="Person" table="person">
<id name="id"> <generator class="native" /> </id> <property name="name" /> </class></hibernate-mapping>5.建立访问Person实体的Service接口
package cn.soldier.service;import java.util.List;
import cn.soldier.bean.Person;public interface PersonService {
public abstract void save(Person person);
public abstract void update(Person person);
public abstract void delete(Long id);
public abstract Person getPerson(Long id);
public abstract List<Person> getPersons();
}6.建立访问Person实体的Service实现方法
package cn.soldier.service.impl;import java.util.List;
import javax.annotation.Resource;
import org.hibernate.Session;
import org.hibernate.SessionFactory;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import cn.soldier.bean.Person;
import cn.soldier.service.PersonService;@Transactional //启用事务管理
public class PersonServiceBean implements PersonService { @Resource//使用filed注入SessionFactory对象 SessionFactory sessionFactory;public void save(Person person) {
// 得到容器里面正在被Transaction管理的Session // 如果使用opeSession(),获得的Session对象是不受Transaction管理的。 Session session = (Session) sessionFactory.getCurrentSession(); session.persist(person); }public void update(Person person) {
sessionFactory.getCurrentSession().merge(person);// SaveOrUpdate }public void delete(Long id) {
// load方法性能最佳,因为get方法有一个数据装配的过程 sessionFactory.getCurrentSession().delete( sessionFactory.getCurrentSession().load(Person.class, id)); }@Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)// 不启用事务管理,只读
public Person getPerson(Long id) { return (Person) sessionFactory.getCurrentSession() .get(Person.class, id); } @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true) @SuppressWarnings("unchecked") // 终止警告 public List<Person> getPersons() { return sessionFactory.getCurrentSession().createQuery("From Person").list(); }}7.测试开发好的PersonServiceBeanpackage junit.test;import org.junit.BeforeClass;
import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.soldier.bean.Person;
import cn.soldier.service.PersonService;public class PersonServiceBeanTest {
private static PersonService personService;@BeforeClass
public static void setUpBeforeClass() throws Exception { try { ApplicationContext ctx = new ClassPathXmlApplicationContext( "beans.xml"); personService = (PersonService) ctx.getBean("personService");} catch (Exception e) {
e.printStackTrace(); } }@Test
public void testSave() { for (int i = 0; i <10; i++) { Person person = new Person("逗比---"+i+"---号"); personService.save(person); } }@Test
public void testUpdate() { Person person = personService.getPerson(1L); person.setName("逗比2号"); personService.update(person); System.out.println(personService.getPerson(1L)); }@Test
public void testDelete() { personService.delete(2L); }@Test
public void testGetPersons() { for (Person person : personService.getPersons()) { System.out.println(person); } }} /************************************************以上步骤已经把Spring 和 Hibernate 集成好了,下面开始继承struts1.3********************************************************/a.导入jar
struts-1.3.8解压目录下的所有jar,jstl-1.0.2.jar和Standard-1.0.2.jar更换为1.1版本额。另外因为Spring中已经存在一个antlir-2.7.6.jar,所以struts中的antilr-2.7.2.jar应删除避免jar包冲突b.配置web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <!--在web容器中实例化Spring容器--> <!--指定spring的配置文件,默认是从web根目录下寻找配置文件。可以通过spring提供的classpath:前缀指定从类路径下寻找 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:beans.xml</param-value> </context-param> <!--对spring容器进行实例化 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--在web容器中配置struts--> <servlet> <!-- --> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <!--指定struts的配置文件 --> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <!--处理所有以.do后缀的请求--> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <!--index--> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list></web-app> c.配置Struts-config.xml<?xml version="1.0" encoding="utf-8" ?><!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd"><struts-config> <!--配置action--> <action-mappings> <action path="/person/list" type="cn.soldier.web.action.PersonAction" validate="false"> <forward name="list" path="/WEB-INF/page/personlist.jsp" /> </action> </action-mappings> <!--配置请求控制器--> <controller> <set-property property="processorClass" value="org.springframework.web.struts.DelegatingRequestProcessor" /> </controller></struts-config>d.编写Action,Action要继承org.apache.struts.action.Action,并重写execute方法
package cn.soldier.web.action;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionForward;import org.apache.struts.action.ActionMapping;import cn.soldier.service.PersonService;
public class PersonAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { /* 如果没有把action交给spring管理时,可以通过下面语句向spring获取容器实例 */ WebApplicationContext ctx = WebApplicationContextUtils .getWebApplicationContext(this.getServlet().getServletContext()); PersonService personService = (PersonService) ctx .getBean("personService"); request.setAttribute("persons", personService.getPersons()); return mapping.findForward("list"); }}e.上面步骤好了就可以访问这个Action了http://localhost:8080/SSH/person/list.dof.配置把action交给spring管理
首先:配置beans.xml<!--在struts配置文件中,添加进spring的请求控制器,该请求控制器会先根据action的path属性值到spring容器中寻找该属性名相同二代bean。如果找到该bean则处理用户请求--><!--将action注入业务层的bean,确保action的path属性与bean名称相同。--><!--例子如下:--><!--<action path="XXXXX" ...></action>--><!--<bean name="XXXXX" clas="cn.soldier.action.PersonAction" />--><bean name="/person/list" class=" cn.soldier.web.action.PersonAction"></bean>
然后在struts-config.xml下配置spring的求情控制器:
<controller> <set-property value="processorClass" property="org.springframework.web.struts.DelegatingRequestProcessor"/></controller>g.配置spring的二级缓存
1.首先在bean.xml配置的sessionFactory中配置开启二级缓存 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mappingResources"> <list><value>cn/soldier/bean/Person.hbm.xml</value></list> </property> <property name="hibernateProperties"> <props> <!-- 指定数据库方言 --> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop> <!-- 是否根据需要每次自动创建数据库 --> <prop key="hibernate.hbm2ddl.auto">update</prop> <!-- 显示Hibernate持久化操作所生成的SQL --> <prop key="hibernate.show_sql">true</prop> <!-- 将SQL脚本进行格式化后再输出 --> <prop key="hibernate.format_sql">false</prop> <!--启用Hibernate二级缓存 --> <prop key="hibernate.cache.use_second_level_cache">true</prop> <!--启用query查询缓存 --> <prop key="hibernate.cache.use_query_cache">false</prop> <!-- 指定缓存的供应商 --> <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> </props> </property> </bean>2.然后配置ehCache.xml,上面指定的缓存供应商是EhCache,EhCache的配置文件默认是classpath下的ehCache.xml<?xml version="1.0" encoding="UTF-8"?><ehcache> <!--缓存对象存储路径 --> <diskStore path="D:\temp\javawebe\cache" /> <!--defaultCache 节点为缺省的缓存策略 --> <!--maxElementsInMemory 内存中最大允许存在的对象数量 --> <!--eternal 设置缓存中的对象是否永不过期 --> <!--overflowToDisk 把溢出的对象存放到硬盘上 --> <!--timeToIdleSeconds 指定缓存对象空闲多长时间过期,过期的对象会被清除掉 --> <!--timeToLiveSeconds 指定缓存对象总的粗活时间 --> <!--diskPersistent 当jvm结束是否持久化对象 --> <!--diskExpiryThreadIntervalSeconds 指定专门用于清除过期对象的监听线程轮询时间 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskPersistent="false" diskExpiryThreadIntervalSeconds="60" /><cache name="sampleCache1" maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true" /><cache name="sampleCache2" maxElementsInMemory="1000" eternal="true"
timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="false" /></ehcache>3.配置Person.hbm.xml,指定需要使用缓存的bean的Hibernate映射文件中添加缓存配置
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="cn.soldier.bean"> <class name="Person" table="person"> <!--配置启用缓存 --> <!--usage:缓存策略--> <!--region:缓存的区域 --> <cache usage="read-write" region="cn.soldier.bean.Person"/> <id name="id"> <generator class="native" /> </id> <property name="name" /> </class></hibernate-mapping>4.可省略(针对某个缓存区域指定特定策略)
ehcache.xml下配置<!--针对某个缓存区域指定特定策略 --><Cache name="cn.soldier.bean.Person" maxElementsInMemory="100" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskPersistent="false"diskExpiryThreadIntervalSeconds="60" />5.可以使用了(下面是测试缓存是否启用)
PersonServiceBeanTest.java @Test public void testSecondLevelCache() { System.out.println("第一次请求getPerson()"); System.out.println(personService.getPerson(1L)); // try { System.out.println("请关闭数据库"); Thread.sleep(1000 * 15); } catch (InterruptedException e) { e.printStackTrace(); } // System.out.println("关闭数据库后第二次请求getPerson()"); System.out.println(personService.getPerson(1L)); }h.使用spring解决strut1.3的中文乱码问题
1.创建一个html表单 index.jap<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>Struts1.3+Sprin2.5+Hibernate3.3集成</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"></head>
<body> <html:form action="/person/manage" method="post"> 名称:<html:text property="name"></html:text> <br /> <input type="submit" value="提交" /> <input type="hidden" name="method" value="add" /> </html:form></body></html>2.定义请求Action PersonManageAction.javapackage cn.soldier.web.action;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionForward;import org.apache.struts.action.ActionMapping;import org.apache.struts.actions.DispatchAction;import cn.soldier.bean.Person;import cn.soldier.service.PersonService;import cn.soldier.web.form.PersonForm;public class PersonManageAction extends DispatchAction {
@Resource PersonService personService;public ActionForward add(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Exception {
//将form转为PersonForm PersonForm formbean = (PersonForm) form; //从formbean中获取数据 personService.save(new Person(formbean.getName())); // request.setAttribute("message", "添加成功"); // return mapping.findForward("message"); }}3.定义ActionForm
package cn.soldier.web.form;import org.apache.struts.action.ActionForm;
public class PersonForm extends ActionForm {
/** * 简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。 * 在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较, * 如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException) */ private static final long serialVersionUID = 1L;private Long id;
private String name;public Long getId() {
return id; }public void setId(Long id) {
this.id = id; }public String getName() {
return name; }public void setName(String name) {
this.name = name; }}
4.配置strut-config.xml
<action path="/person/manage" parameter="method" validate="false" scope="request" name="personForm"> <forward name="message" path="/WEB-INF/page/message.jsp"></forward></action>5.配置beans.xml
<bean name="/person/manage" class=" cn.soldier.web.action.PersonManageAction"></bean>6.这次一个form表单的提交就建立好了。这时可以测试一下。
测试的结果是如果提交的是中文,存进数据库中的是乱码。7.使用filter,通过spring解决中文乱码问题。配置web.xml
<!--使用spring解决strut1.3的中文乱码问题 --><filter> <filter-name>encoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf8</param-value> </init-param></filter><filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern></filter-mapping>i使用Spring解决hibernte因Session关闭导致的延迟加载例外问题。
测试步骤忽略<filter> <filter-name>OpenSessionViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class></filter><filter-mapping> <filter-name>OpenSessionViewFilter</filter-name> <url-pattern>/*</url-pattern></filter-mapping>