Terry.Li-彬

虚其心,可解天下之问;专其心,可治天下之学;静其心,可悟天下之理;恒其心,可成天下之业。

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  143 随笔 :: 344 文章 :: 130 评论 :: 0 Trackbacks
Struts+Spring+Hibernate的完美融合

 

第一篇 struts与spring的融合

第一步:配置环境与技术支持

1、环境:tomcat5.0 + eclipse3.2.2 + myEclipse5.5 + jdk1.5

2、技术:struts1.1+spring2.0

分析:经过多次实验,(初建struts+spring)项目中出现的问题和工具及技术版本没有根本关系,只要在(其他项目运行)已经配置成功的环境下运行就好。这里要注意的是:myEclipse5.0以下的版本不支持spring2.0。小小提示:本人初次在该环境下操作时,多次不成功,最后从新安装配置环境后,struts+spring项目才正常运行,疑与myEclipse有关。

第二步:新建工程SSHProject

1、新建工程

分析:不同版本的eclipse新建项目对话框不同,3.2.2以下版本没有java EE 5.0。这里我们选择J2EE1.4!

2、导入struts包

 

3、导入spring包

导入spring 包

分析:这里我们使用的是spring2.0,如果你的版本不支持2.0,就使用spring1.2版本。spring1.2与struts1.1同样兼容,但spring1.2只支持hibernate3.0以下的版本。如果你选择spring1.2,就不得不使用hibernate3.0或者2.1。小小提示:对于初学者来说,最好把所有的spring包导入项目。提醒:applicationContext.xml我们放在src下,但我们要知道编译部署后,默认在classes文件夹,所以我们在以后的配置中,一定要注意路径问题。

3、新建com.ssh.beans.po和com.ssh.beans.dao两个包已做备用。

好了,工程框架已经搭好,现在我们就可以往里面放东西了。

第三步 创建action和bean

1、在com.ssh.beans.po中创建Customer.java。内容如下:

package com.ssh.beans.po;

public class Customer {
 
 String custId;
 String custName;
 
 public Customer(){
  
 }
 
 public Customer(String custId,String custName){
  this.custId=custId;
  this.custName=custName;
 }
 
 public void setCustId(String custId){
  this.custId=custId;
 }
 
 public String getCustId(){
  return this.custId;
 }
 
 public void setCustName(String custName){
  this.custName=custName;
 }
 
 public String getCustName(){
  return this.custName;
 }
}

2、在com.ssh.beans.dao中创建CustomerDAO.java及其接口ICustomerDAO.java。内容如下:

package com.ssh.beans.dao;

import java.util.ArrayList;
import java.util.List;

import com.ssh.beans.po.Customer;

public class CustomerDAO implements ICustomerDAO {
public List getALLCustomer(){
 List list=new ArrayList();
 Customer c1=new Customer("1","zhang");
 Customer c2=new Customer("2","xiaoling");
 list.add(c1);
 list.add(c2);
 return list;
}
}

 

package com.ssh.beans.dao;

import java.util.List;

public interface ICustomerDAO {
 public List getALLCustomer();
}

 3、创建CustomerAction.java

分析:这里action的创建与我们以前创建action一样,但我们要注意的是,你导入什么版本的struts就要生成什么版本的action,这里是struts1.1。

接下来我们看看struts-config.xml里面的内容:

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

<struts-config>
  <data-sources />
  <form-beans />
  <global-exceptions />
  <global-forwards />


  <action-mappings >
    <action path="/customer" type="com.ssh.struts.action.CustomerAction">
      <forward name="success" path="/index.jsp" />
    </action>

</action-mappings>

  <message-resources parameter="com.ssh.struts.ApplicationResources" />
</struts-config>

没错,内容和我们以前的东东一样。

我们再给CustomerAction.java一些内容:

package com.ssh.struts.action;

import java.util.ArrayList;
import java.util.List;

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 com.ssh.beans.dao.CustomerDAO;
import com.ssh.beans.dao.ICustomerDAO;
import com.ssh.beans.po.Customer;

public class CustomerAction extends Action {
 
 ICustomerDAO customerDAO=null;
 public void setCustomerDAO(ICustomerDAO customerDAO){
  this.customerDAO=customerDAO;
 }
 
 public ActionForward execute(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response) {
  List list=new ArrayList();
  Customer customer=null;
  setCustomerDAO(new CustomerDAO());
  if(customerDAO!=null){
   list=customerDAO.getALLCustomer();
   for(int i=0;i<list.size();i++){
    customer=(Customer)list.get(i);
    System.out.println("OK:"+customer.getCustName());
   }
  }else{
   System.out.println("ERROR or NULL");
  }
  return mapping.findForward("success");
 }
}

 

好的,我们现在测试一下!如果访问http://localhost:8080/SSHProject/customer.do能顺利进入index.jsp页面,并输出用户custName值,说明以上我们的工作是正确的!

第四步 配置stuts-config.xml和applicationContext.xml文件

看到这里,大家可能会认为,这和以前的web工程的创建没有什么两样,和struts与spring融合没有什么关系,不用着急,奥妙就在sturts-config.xml与applicationContext.xml文件配置中。

1、配置stuts-config.xml文件

在这里,我们要做两个工作:第一,将CustomerAction替换成DelegatingActionProxy代理。第二,添加代理插件ContextLoaderPlugIn。修改后的内容如下:

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

<struts-config>
  <data-sources />
  <form-beans />
  <global-exceptions />
  <global-forwards />
 
  <action-mappings >
    <action path="/customer"  type="org.springframework.web.struts.DelegatingActionProxy">
      <forward name="success" path="/index.jsp" />
    </action>
  </action-mappings>

  <message-resources parameter="com.ssh.struts.ApplicationResources" />
 
  <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
     <set-property property="contextConfigLocation"
         value="/WEB-INF/classes/applicationContext.xml"/>
  </plug-in>
 
</struts-config>

注:粗体字为修改的内容

分析:你一定要做到:1、确保spring-struts.jar导入项目。2、保证applicationContext.xml文件路径正确。我们在导入spring包时就提到,applicationContext.xml文件放在src下,编译部署后,文件默认存放在WEB-INF/classes下。所以上面的配置为:value="/WEB-INF/classes/applicationContext.xml"/>

2、配置applicationContext.xml

在这个文件中,我们的任务是加入我们需要的bean。到目前为止,我们要加入两个bean,即:CustomerDAO与CustomerAction。修改后的内容为:

<?xml version="1.0" encoding="UTF-8"?>
<beans
 xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
 
 <bean name="/customer" class="com.ssh.struts.action.CustomerAction" >
      <property name="customerDAO"><ref bean="customerDAO"/></property>
 </bean>   
 <bean name="customerDAO" class="com.ssh.beans.dao.CustomerDAO" />

</beans>

注:粗体字为添加的内容

分析:在这个文件中你要确保:第一,CustomerAction bean中<bean>标签的属性name值(name="/customer")一定与struts-config.xml中属性path的值(path="/customer")一致。第二、<property>标签的属性name值在CustomerAction中一定有对应的属性。第三、<ref>标签的属性bean值一定与CustomerDAO bean的<bean>标签的属性name值一致(注:这就是注入目标对象)。第四、CustomerDAO bean中<bean>标签的属性class值一定是一个实现类(不能为接口)。

3、修改CustomerAction.java

这一步很简单,只要把setCustomerDAO(new CustomerDAO());这条语句去掉就好。因为我们已经在applicationContext.xml给customerDAO进行了setter注入。(呵呵,至于什么是setter注入,不了解的朋友先看看spring的IOC)。

好的,到现在为止,我们已经对struts和spring进行了融合。再来测试一下,如果输入同样的内容,就OK!

如果以上操作大家都没有问题,我们就向下看。来吧,一起融合spring与hibernate

 

第二篇 Spring与Hibernate的融合

有的朋友可能只希望知道spring与hibernate的融合。所以在讲struts+spring+hibernate之前,我们跳过使用stuts,先说一下spring+hibernate的融合。如果仍然用SSHProject这个项目,需要把po和dao包下面的类删除,因为我们在生成影射文件和DAO时可能会出现重名文件。还有applicationContext.xml中的bean同样删除。

第一步 配置数据环境

既然我们用到hibernate,就要给他配置数据库,这里我们使用的是mysql5.0。eclipse3.2.2一下的版本与3.2.2版本数据库的配置是不同的,这里我们只讲3.2.2的配置。

1、打开DB Brower

2、新建数据库连接

在DB Brower中右键>新建打开下面对话框,选择输入正确的配置。提示:注意你的数据库名、密码、和驱动器。

单击“完成”,测试如果连接到数据库,就OK。

第二步 选择hibernate与包的导入

1、hibernate的选择

上面我们已经提到,spring1.2只支持hibernate3.0以下的版本,所以如果你选择的是spring1.2一定要注意这个问题。这里我使用的是hibernate3.1

2、包的导入

 

 

单击“完成”OK。

分析:在导入包时出现几个问题:1、在找spring建好的applicationContext.xml文件时没有找到路径,被迫把其他项目的数据库连接bean考到该文件内((注:仅仅是我存在的问题)。2、把自动生成的sessionFactory删除。3、最后可能会出现找不到包,所以你要手动添加几个包。

现在我们看看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"
 xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
 
 <bean id="dataSource"
  class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName"
   value="com.mysql.jdbc.Driver">
  </property>
  <property name="url"
   value="jdbc:mysql://localhost:3306/pullhand">
  </property>
  <property name="username" value="root"></property>
  <property name="password" value="815241"></property>
 </bean>
 <bean id="sessionFactory"
  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource">
   <ref bean="dataSource" />
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">
     org.hibernate.dialect.MySQLDialect
    </prop>
   </props>
  </property>
 </bean>

</beans>

注:粗体字为自动加入的内容。

第三步 创建影射文件po及dao

1、创建影射文件

首先你要确定所需要的包都导入classpath路径中,否则在创建影射文件中会出现一些不能操作的对象。如果出现问题,建议大家多重复做几次。

单击"完成",就OK。

在包资源管理器中我们可以看到,自动生成四个文件,包括CustomerDAO。

为了方便操作我们包CustomerDAO放在dao包下。如果你没有删除ICustomerDAO接口,那我们就使用它了(因为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"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
 
 <bean id="dataSource"
  class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName"
   value="com.mysql.jdbc.Driver">
  </property>
  <property name="url"
   value="jdbc:mysql://localhost:3306/pullhand">
  </property>
  <property name="username" value="root"></property>
  <property name="password" value="815241"></property>
 </bean>
 <bean id="sessionFactory"
  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource">
   <ref bean="dataSource" />
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">
     org.hibernate.dialect.MySQLDialect
    </prop>
   </props>
  </property>
  <property name="mappingResources">
   <list>
    <value>com/ssh/beans/po/Customer.hbm.xml</value></list>
  </property>
  </bean>
  
  <bean id="CustomerDAO" class="com.ssh.beans.dao.CustomerDAO">
   <property name="sessionFactory">
    <ref bean="sessionFactory" />
   </property>
  </bean>

   
 </beans>

注:粗体字为新内容。提醒:如果你没有改CustomerDAO的路径,它应该在po包下。

2、创建dao。

CustomerDAO.java我们使用hibernate自动生成,ICustomerDAO.java接口使用我们以前建好的。

3、创建测试类

既然我们不使用action,那么我们就新建一个类Test.java用于测试。内容如下:

package com.ssh.struts.action;

import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ssh.beans.dao.CustomerDAO;

public class Test{
 
 private ApplicationContext context;
 

 
 private void test(){
  CustomerDAO customerDAO=(CustomerDAO)context.getBean("customerDAO");
  List list=customerDAO.findAll();
  if(list!=null&&list.size()>0){
   System.out.println("list.size():"+list.size());
  }else{
   System.out.println("ERROR or NULL");
  }
 }
 private void run(){
  context=new ClassPathXmlApplicationContext("applicationContext.xml");
  test();
 }
 public static void main(String[] args){
  new Test().run();
 }
}

分析:在测试中可能出现两个异常:

异常一、java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool。如果出现这个异常说明缺少commons-pool-1.2.jar包。

异常二、org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class 'com.mysql.jdbc.Driver';;;Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver。如果出现这个异常,说明在构建路径中没有驱动包。

好的,我们现在测试一下,如果System.out.println("list.size():"+list.size());执行,说明我们对spring与hibernate的融合成功了。

 

第三篇 整合struts+spring+hibernate

我们在上两篇的基础只要再对applicationContext.xml文件进行修改,就可以达到我们整合的目地。

第一步 完善applicationContext.xml内容

1、添加事务处理。内容如下:

  <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory">
     <ref local="sessionFactory" />
    </property>
   </bean>
   <bean id="customerDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager">
     <ref bean="transactionManager" />
    </property>
    <property name="target">
     <ref local="customerDAO" />
    </property>
    <property name="transactionAttributes">
     <props>
      <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
     </props>
    </property>
   </bean>

2、CustomerAction Bean注入事务处理。内容如下:

  <bean name="/customer" class="com.ssh.struts.action.CustomerAction" >
      <property name="customerDAO"><ref bean="customerDAOProxy"/></property>
  </bean>

 3、最终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"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
 
 <bean id="dataSource"
  class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName"
   value="com.mysql.jdbc.Driver">
  </property>
  <property name="url"
   value="jdbc:mysql://localhost:3306/pullhand">
  </property>
  <property name="username" value="root"></property>
  <property name="password" value="815241"></property>
 </bean>
 
 <bean id="sessionFactory"
  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource">
   <ref bean="dataSource" />
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">
     org.hibernate.dialect.MySQLDialect
    </prop>
   </props>
  </property>
  <property name="mappingResources">
   <list>
    <value>com/ssh/beans/po/Customer.hbm.xml</value></list>
  </property>
  </bean>
  
  <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory">
     <ref local="sessionFactory" />
    </property>
   </bean>
   <bean id="customerDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager">
     <ref bean="transactionManager" />
    </property>
    <property name="target">
     <ref local="customerDAO" />
    </property>
    <property name="transactionAttributes">
     <props>
      <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
     </props>
    </property>
   </bean>
  
  <bean id="customerDAO" class="com.ssh.beans.dao.CustomerDAO">
   <property name="sessionFactory">
    <ref bean="sessionFactory" />
   </property>
  </bean>
  
  <bean name="/customer" class="com.ssh.struts.action.CustomerAction" >
      <property name="customerDAO"><ref bean="customerDAOProxy"/></property>
  </bean> 
   
 </beans>

第二步,修改CustomerAction

最后内容如下:


package com.ssh.struts.action;

import java.util.ArrayList;
import java.util.List;

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 com.ssh.beans.dao.ICustomerDAO;
import com.ssh.beans.po.Customer;


public class CustomerAction extends Action {
 ICustomerDAO customerDAO=null;
 public void setCustomerDAO(ICustomerDAO customerDAO){
  this.customerDAO=customerDAO;
 }
 
 public ActionForward execute(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response) {
  List list=new ArrayList();
  Customer customer=null;
  if(customerDAO!=null){
   list=customerDAO.getALLCustomer();
   for(int i=0;i<list.size();i++){
    customer=(Customer)list.get(i);
    System.out.println("OK:"+customer.getCustName());
   }
  }else{
   System.out.println("ERROR or NULL");
  }
  return mapping.findForward("success");
 }
}

第三步 解决找不到Action问题

初学者会经常遇到下面这个问题:

HTTP Status 404 - Servlet action is not available


type Status report

message Servlet action is not available

description The requested resource (Servlet action is not available) is not available.


Apache Tomcat/5.0.28

就是找不到我们的action。

当你努力去解决这个问题时,会发现去掉applicationContext.xml下面这个<property>标签,一切正常:

  <property name="mappingResources">
   <list>
    <value>
     com/ssh/beans/po/Customer.hbm.xml
    </value>
   </list>
  </property>

那是什么原因呢?我想大家都会首先想到下面两个问题:

1、路径是否正确:即com/ssh/beans/po/Customer.hbm.xml的路径正确么?

2、文件是否正确:即Customer.hbm.xml的文件内容对么?

当你费了一身力气发现一切OK,到底什么原因???

问题在于构件路径(lib)内的包重叠(提示:前提是你要保证这个问题出现之前都正常),所以你要确定构建路径里的包不能重复!

建议:大家在导入包时,按照默认导入,不要把所有的包都导进工程,在操作中在把需要的jar包导进去(最好不要把整个liberaries导进去),这样即可以减小工程的大小,又能确保struts\spring\hibernate之间的包不会重叠或者被替换。

 

好了,我的任务完成了,大家删包去吧!祝你好运!

posted on 2007-11-09 22:36 礼物 阅读(2647) 评论(3)  编辑  收藏 所属分类: SSH

评论

# re: Struts+Spring+Hibernate的完美融合 2007-11-12 15:52 小数
呵呵
谢谢  回复  更多评论
  

# re: Struts+Spring+Hibernate的完美融合 2007-11-12 15:57 小数
但是怎么删了还是那样阿
郁闷  回复  更多评论
  

# re: Struts+Spring+Hibernate的完美融合 2007-11-28 01:04 hitman
感激啊,困扰我三天三夜的问题终于在这里找到解决方法,除了拜谢以外没什么好说的了!!!!  回复  更多评论