`

十七 Spring2.5+JPA+Struts1.3整合开发

 
阅读更多
十七 Spring2.5+JPA+Struts1.3整合开发

第一步 加入spring的jar包 
Spring安装包下的
dist\spring.jar
dist\modules\spring-webmvc-struts.jar
lib\jakarta-commons\commons-logging.jar、commons-dbcp.jar、commons-pool.jar
lib\aspectj\aspectjweaver.jar、aspectjrt.jar
lib\cglib\cglib-nodep-2.1_3.jar
lib\j2ee\common-annotations.jar
lib\log4j\log4j-1.2.15.jar

加入jpa的hibernate的实现包

这里JPA的实现采用hibernate,需要使用到下面的jar文件

Hiberante核心包(8个文件)
hibernate-distribution-3.3.1.GA
---------------------------------------------
hibernate3.jar
lib\bytecode\cglib\hibernate-cglib-repack-2.1_3.jar
lib\required\*.jar

Hiberante注解包(3个文件):hibernate-annotations-3.4.0.GA
------------------------------------------------------------------------------------
hibernate-annotations.jar
lib\ejb3-persistence.jar、hibernate-commons-annotations.jar

Hibernate针对JPA的实现包(3个文件):hibernate-entitymanager-3.4.0.GA
------------------------------------------------------------------------------------------------------
hibernate-entitymanager.jar
lib\test\log4j.jar、slf4j-log4j12.jar


第二步 加入spring的配置文件 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/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
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- 启动注解依赖注入 -->
	 <context:annotation-config/>
	 <!-- 作用:跟hibernate的sessionFactory的作用是一样的,是一个连接工厂的对象,使用的是spring的jap的连接工厂 -->
	 <!-- persistenceUnitName 持久化单元名称 这个是要在src的META-INF配置 -->
 <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
      <property name="persistenceUnitName" value="itcast"/>
 </bean>
  <!-- 配置jpa的事务管理容器 -->
 <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  	<property name="entityManagerFactory" ref="entityManagerFactory"/>
  </bean>
  <!-- 开启注解方式启动事务管理 -->
 <tx:annotation-driven transaction-manager="txManager"/>
	
</beans>


第三步:在src的META-INF配置 META-INF目录下放置persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
  <!--persistence-unit 这里就是持久化单元的配置 单元的名称是 itcast  -->
  <persistence-unit name="itcast" transaction-type="RESOURCE_LOCAL">
      <properties>
         <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
         <property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver"/>
         <property name="hibernate.connection.username" value="root"/>
         <property name="hibernate.connection.password" value="root"/>
         <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/itcast?useUnicode=true&amp;characterEncoding=UTF-8"/>
         <property name="hibernate.max_fetch_depth" value="3"/>
         <property name="hibernate.hbm2ddl.auto" value="update"/>
      </properties>
  </persistence-unit>
</persistence>


第四步 建立实体bean
package cn.itcast.bean;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
 * 利用注解  表明当前的Person是一个实体bean 
 * @author Administrator
 *
 */
@Entity
public class Person implements Serializable {
   private Integer id;
   private String name;
   
   public Person(){}
   public Person(String name){
	   this.name=name;
   }
  /**
   * Id 实体标识 
   * GeneratedValue 指定主键生成策略
   * @return
   */
@Id @GeneratedValue
public Integer getId() {
	return id;
}
public void setId(Integer id) {
	this.id = id;
}
/**
 * Column 指定获取name的映射的列名 并指定列值长度 并指定其列值是否允许为空
 * @return
 */
@Column(length=10,nullable=false)
public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}
@Override
public int hashCode() {
	final int prime = 31;
	int result = 1;
	result = prime * result + ((id == null) ? 0 : id.hashCode());
	return result;
}
@Override
public boolean equals(Object obj) {
	if (this == obj)
		return true;
	if (obj == null)
		return false;
	if (getClass() != obj.getClass())
		return false;
	Person other = (Person) obj;
	if (id == null) {
		if (other.id != null)
			return false;
	} else if (!id.equals(other.id))
		return false;
	return true;
}
}


第五步 建立服务bean PersonServiceBean
package cn.itcast.service.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cn.itcast.bean.Person;
import cn.itcast.service.PersonService;
/**
 * @Transactional 这个注解用来为这个服务开启事务
 * @author Administrator
 *
 */
@Transactional 
public class PersonServiceBean implements PersonService {
	/**
	 * @PersistenceContext 用来注入EntityManager对象
	 * 原理:要这个注入 到这个service spring会从spring的配置文件中的entityManagerFactory
	 * 得到EntityManager对象
	 */
@PersistenceContext EntityManager em;

public void save(Person person){
	   em.persist(person);
   }
public void update(Person person){
	   em.merge(person);
   }

public void delete(Integer id){
	   em.remove(em.getReference(Person.class, id));
   }
/**
 * 指定当前的方法不需要开启事务 并且设定为只读
 */
@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
public Person getPerson(Integer personid){
	     return em.find(Person.class, personid);
   }

@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
@SuppressWarnings("unchecked")
public List<Person> getPersons(){
        //这里的查询语句的from 后 必须是实体类名
	   return em.createQuery("select o from Person o").getResultList();
   }
}

第六步 建立相应的接口
package cn.itcast.service;

import java.util.List;

import cn.itcast.bean.Person;

public interface PersonService {

	public void save(Person person);

	public void update(Person person);

	public void delete(Integer id);

	public Person getPerson(Integer personid);

	@SuppressWarnings("unchecked")
	public List<Person> getPersons();

}

做测试类
package junit.test;

import static org.junit.Assert.*;

import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

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

public class PersonServiceBeanTest {
    private static PersonService personservice;
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		  try {
			AbstractApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
			  personservice=(PersonService)context.getBean("personService");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Test
	public void testSave() {
		personservice.save(new Person("小叶"));
	}

	@Test
	public void testUpdate() {
		fail("Not yet implemented");
	}

	@Test
	public void testDelete() {
		fail("Not yet implemented");
	}

	@Test
	public void testGetPerson() {
		fail("Not yet implemented");
	}

	@Test
	public void testGetPersons() {
		fail("Not yet implemented");
	}

}


到这里spring+jpa的集成方式就已经完成了

现在我们来集成struts

第七步:集成struts 
加入struts的jar包到lib目录下 除struts中的antlr-2.7.2.jar这个包不能加入外 因为这个包在spring中已经加入了
为避免冲突,不需要加入进来

第八步 添加spring到web容器中,让web容器去实例化这个spring 
同时指定实例化的spring添加到action范围中,以后我们的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>struts</servlet-name>
	<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
	<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>
<servlet-mapping>
	<servlet-name>struts</servlet-name>
	<url-pattern>*.do</url-pattern>
</servlet-mapping>



在struts配置文件中添加进spring的请求控制器,该请法语控制器会先根据action的path属性值到spring容器中寻找跟该属性值同名的bean。如果寻找到即使用该bean处理用户请求
<controller>
 <set-property property="processorClass" value="org.springframework.web.struts.DelegatingRequestProcessor"/>
</controller> 

第九步 现在我们来做一个action 测试一下 
package cn.itcast.action;

import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
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.itcast.service.PersonService;

public class PersonAction extends Action {
    @Resource PersonService personService;
	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		 request.setAttribute("persons", personService.getPersons());
		 return mapping.findForward("list");
	}


}

并把这个action中交给spring管理 同时也配置到struts-config.xml
<bean name="/person/list" class="cn.itcast.action.PersonAction"/>

现在把这个配置到struts-config.xml
 <action-mappings>
 <action path="/person/list" validate="false">
 <forward name="list" path="/WEB-INF/page/personlist.jsp"></forward>
 </action>
 </action-mappings>  

 在浏览器中输入 http://localhost:8808/SSJ/person/list.do 


现在我们来利用web页面 插入数据会有乱码问题 

解决方法 
配置spring的过滤器,解决乱码
<filter>
	<filter-name>encoding</filter-name>
	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	<init-param>
		<param-name>encoding</param-name>
		<param-value>UTF-8</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>encoding</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>


好了 jpa是用EntityManager类进行数据的操作的,如果这个EntityManager对象关闭 会出现延迟加载例外
怎么解决呢?

使用spring解决JPA因EntityManager关闭导致的延迟加载例外问题。

<filter>
        <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
 </filter>
 <filter-mapping>
        <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
 </filter-mapping>

 怎么解决struts1的单例模式 因为struts1是线程不安全的,所以要解决这个问题 
 当struts1的action交给spring管理后,就可以解决这个问题 
 只需要在spring 管理的action配置中指定其请求范围即可 
<bean name="/person/pmessage" class="cn.itcast.action.PersonMessageAction" scope="prototype"></bean>

这个scope指定的范围:request prototype session singleton 四种模式

现在到这里Spring2.5+JPA+Struts1.3整合就已经全部完成了
现在我们来看其配置文件 
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
	xmlns="http://java.sun.com/xml/ns/j2ee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	
<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页面中插入到数据库中会有乱码的出现 所以利用 spring提供的过滤器 可以解决乱码问题-->
<filter>
	<filter-name>encoding</filter-name>
	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	<init-param>
		<param-name>encoding</param-name>
		<param-value>UTF-8</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>encoding</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- jpa是用EntityManager进行数据操作的,如果这个对象关闭,将会出现延迟加载例外 解决方法  -->
<filter>
        <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
 </filter>
 <filter-mapping>
        <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
 </filter-mapping>
 
<!-- 把struts添加到web容器中  -->	
<servlet>
	<servlet-name>struts</servlet-name>
	<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
	<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>
<servlet-mapping>
	<servlet-name>struts</servlet-name>
	<url-pattern>*.do</url-pattern>
</servlet-mapping>
	
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>





jpa的配置文件 persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
  <!--persistence-unit 这里就是持久化单元的配置 单元的名称是 itcast  -->
  <persistence-unit name="itcast" transaction-type="RESOURCE_LOCAL">
      <properties>
         <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
         <property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver"/>
         <property name="hibernate.connection.username" value="root"/>
         <property name="hibernate.connection.password" value="root"/>
         <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=UTF-8"/>
         <property name="hibernate.max_fetch_depth" value="3"/>
         <property name="hibernate.hbm2ddl.auto" value="update"/>
      </properties>
  </persistence-unit>
</persistence>


spring的配置文件 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/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
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- 启动注解依赖注入 -->
	 <context:annotation-config/>
	 <!-- 作用:跟hibernate的sessionFactory的作用是一样的,是一个连接工厂的对象,使用的是spring的jap的连接工厂 -->
	 <!-- persistenceUnitName 持久化单元名称 这个是要在src的META-INF配置 -->
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
      <property name="persistenceUnitName" value="itcast"/>
  </bean>
  <!-- 配置jpa的事务管理容器 -->
 <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  	<property name="entityManagerFactory" ref="entityManagerFactory"/>
  </bean>
  <!-- 开启注解方式启动事务管理 -->
 <tx:annotation-driven transaction-manager="txManager"/>
<bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"/>
<bean name="/person/list" class="cn.itcast.action.PersonAction"/>
<bean name="/person/pmessage" class="cn.itcast.action.PersonMessageAction" scope="prototype"></bean>
</beans>


struts1的配置文件 
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE struts-config PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
        "http://struts.apache.org/dtds/struts-config_1_3.dtd">

<struts-config>

<form-beans>
 <form-bean name="PersonForm" type="cn.itcast.formbean.PersonForm"/>
</form-beans>
  
 <global-forwards>
<forward name="message" path="/WEB-INF/page/message.jsp"></forward>
</global-forwards>

 <action-mappings>
 <action path="/person/list" validate="false">
 <forward name="list" path="/WEB-INF/page/personlist.jsp"></forward>
 </action>
 
 <action path="/person/pmessage" validate="false" parameter="method" 
scope="request" name="PersonForm"></action>

 </action-mappings>  
   
<!-- 在struts配置文件中添加进spring的请求控制器,该请法语控制器会先根据action的path-->
<!-- 属性值到spring容器中寻找跟该属性值同名的bean。如果寻找到即使用该bean处理用户请求 -->
<controller>
 <set-property property="processorClass" value="org.springframework.web.struts.DelegatingRequestProcessor"/>
</controller> 

</struts-config>


end 完毕!

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics