SSH项目

       做一个网上商城的项目,首先从搭建环境开始,一步步整合S2SH。这篇博文主要总结一下如何整合Struts2、Hibernate4.3和Spring4.2。

        整合三大框架得先从搭建各部分环境开始,也就是说首先得把spring,hibernate和Struts2的环境搭建好,确保它们没有问题了,再做整合。这篇博文遵从的顺序是:先搭建Spring环境-->然后搭建Hibernate环境--> 整合Spring和Hibernate --> 搭建Struts2环境 --> 整合Spring和Struts2。


1. 整个项目jar包的管理

        Spring的jar包很多,开发的时候建议将它们分个类,然后依次添加到User Library,方便管理,也一目了然。这里我总结一下整个SSH所需要的基本jar包,看下图:

SSH项目_第1张图片


从图中可以看出,首先将Spring的jar分为四类:spring-4.2.4-core、spring-4.2.4-aop、spring-4.2.4-persistence以及spring-4.2.4-web。将spring的核心包都放到core中,与aop相关的都放到aop中,与持久化(与Hibernate整合)相关的放到persistence中,与web(与struts2整合)相关的放到web中。每个部分都有哪些jar包呢?请看下面的截图:

SSH项目_第2张图片  SSH项目_第3张图片

        注:以上每个分类的包中,并非包含原来包中所有的jar,有些jar文件并没有用到,等具体项目需要的时候再往里加就行了,上图是保证项目的环境可以搭建所需要的的最基本的jar包。


2.搭建Spring环境

       上面的jar包截图是最后整合好的所有jar包,刚开始搭建环境的时候不需要一次性全部加进来,可以一点一点的加,这样也更利于理解每个部分的jar包都有什么作用,当然,一次都加进来也是可以的。

2.1 添加配置文件beans.xml和相应的jar包

        新建一个工程,然后添加在User Library中添加自己的库,这里主要添加两个,即spring-4.2.4-core和spring4.2.4-aop,添加jar包不再赘述。添加完了后,在src目录下添加beans.xml文件,这个文件的模板网上很多,Spring自带的例子里也有,考一份过来就行,见下图:

SSH项目_第4张图片

2.2 测试Spring的IoC环境

        我们写一个普通的Java类java.util.Date类来测试一下Spring IoC是否正常,如果在测试程序中能正常注入,则说明Spring的IoC环境搭建成功,下面我们写一个测试用例:

[java] view plain copy
  1. /** 
  2.  * @Description TODO(采用Spring的注解调试,仅仅支持Spring3.1及以上) 
  3.  * @author Ni Shengwu 
  4.  * 
  5.  */  
  6. /* 
  7.  * Spring3.1后多了个spring-test-4.2.4.RELEASE.jar包,这个jar包专门用来支持JUnit基于注解的测试的,该jar包在spring-4.2.4-core中 
  8.  * 该jar包里有个SpringJUnit4ClassRunner.class,用@RunWith注解加进来即可 
  9.  *  
  10.  * 注解@ContextConfiguration表示将ApplicationContext对象注入进来,就不用像以往那样在测试程序里先new了,直接使用 
  11.  */  
  12. @RunWith(SpringJUnit4ClassRunner.class)  
  13. @ContextConfiguration(locations="classpath:beans.xml")  
  14. public class SSHTest {  
  15.       
  16.     @Resource  
  17.     private Date date;  
  18.       
  19.     @Test //测试Spring IOC的开发环境  
  20.     public void springIoc() {  
  21.         System.out.println(date);  
  22.     }  
  23. }  
        最后能正常输出:Thu Apr 28 22:45:13 CST 2016。说明Date对象已经被Spring给注入进来了,从而验证了Spring IoC功能正常,为此,Spring的环境搭建完成。

3. 搭建Hibernate环境

        Hibernate的环境搭建相比于Spring要复杂一些,因为用到了MyEclipse中的逆向工程。我们按以下步骤来搭建Hibernate开发环境:

3.1 添加相应的jar包

        这里主要是向User Library中添加两项jar包:hibernate4.3.11和MySQL驱动包mysql-connector-java-5.1.26,不再赘述。

3.2 新建数据库和表

[sql] view plain copy
  1. drop database if exists shop;  
  2. create database shop default character set utf8;  
  3. use shop;  
  4. drop table if exists category;  
  5. create table category  
  6. (  
  7.    /* 类别编号,自动增长 */  
  8.    id  int not null auto_increment,  
  9.    /* 类别名称 */  
  10.    type varchar(20),  
  11.    /* 类别是否为热点类别,热点类别才有可能显示在首页*/  
  12.    hot  bool default false,  
  13.    /* 设置类别编号为主键*/  
  14.    primary key (id)  
  15. );  

3.3 DB浏览器连接到Mysql数据库

        DB浏览器指的是MyEclipse中的一个视图窗口,可以很直观的看到MySQL中都有哪些数据库和表,打开DB浏览器的方法:Window->Open Perspective->DB Browser打开DB浏览器工作窗口。如果没有DB Browser,按照下面:Window->Show View->other->输入DB Browser,找到打开即可。

        打开后,我们开始连接到MySQL数据库了,在DB Browser窗口的空白处右键->new,就会弹出下面的对话框:

SSH项目_第5张图片

        填好后,点击Test Driver测试一下,测试通过表示DataBase connection Driver已经配置好,然后finish即可,这样我们就能在DB浏览器窗口中看到数据库MySQL5.6了,右键打开就能看到数据库中已有的库和表了,如下:

SSH项目_第6张图片

3.4 创建xml映射文件和sessionFactory

        sessionFactory是用来创建session的,我们通过如下方式创建:工程名右键->myeclipse->Add Hibernate Capabilities,如果没有Add Hibernate Capabilities,就点击project facets->Install Hibernate Facets,会弹出如下窗口:

SSH项目_第7张图片

        下一步,在MyEclipse中添加Hibernate Support,即hibernate.cfg.xml映射文件和sessionFactory。这里主要是给sessionFactory建个包,默认包不行。

SSH项目_第8张图片

        下一步,添加驱动,由于我们之前已经配置好了一个驱动了,所以在这里直接选择刚刚配置好的即可。

SSH项目_第9张图片

        下一步,由于之前我们已经添加过自己的jar保留,这里不用选择,直接finish。

SSH项目_第10张图片

        这样我们就完成了Hibernate配置文件和sessionFactory的创建。下面我们简单看一下MyEclipse创建的sessionFactory里面都有啥:

[java] view plain copy
  1. public class HibernateSessionFactory {  
  2.   
  3.     private static final ThreadLocal threadLocal = new ThreadLocal(); //sessionFactory中用的是线程池技术  
  4.     private static org.hibernate.SessionFactory sessionFactory; //sessionFactory:创建session的工厂  
  5.       
  6.     private static Configuration configuration = new Configuration();  
  7.     private static ServiceRegistry serviceRegistry;   
  8.   
  9.     static { //类加载时初始化sessionFactory  
  10.         try {  
  11.         configuration.configure();  
  12.         serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();  
  13.         sessionFactory = configuration.buildSessionFactory(serviceRegistry); //Hibernate4中创建sessionFactory的方法  
  14.     } catch (Exception e) {  
  15.         System.err.println("%%%% Error Creating SessionFactory %%%%");  
  16.         e.printStackTrace();  
  17.     }  
  18.     }  
  19.     private HibernateSessionFactory() { //私有构造方法阻止new出对象,保证sessionFactory的单例  
  20.     }  
  21.       
  22.     public static Session getSession() throws HibernateException {  
  23.         Session session = (Session) threadLocal.get();  //从线程池中拿session  
  24.   
  25.         if (session == null || !session.isOpen()) { //如果线程池是空的,或者session打开失败  
  26.             if (sessionFactory == null) {  
  27.                 rebuildSessionFactory(); //如果sessionFactory是空的,那就再创建一次,和static部分一样的  
  28.             }  
  29.             session = (sessionFactory != null) ? sessionFactory.openSession() : null//sessionFactory不为空就创建一个session  
  30.             threadLocal.set(session); //然后把这个session放到线程池中,下次再拿  
  31.         }  
  32.   
  33.         return session;  
  34.     }  
  35.   
  36.     public static void rebuildSessionFactory() {  
  37.     try {  
  38.         configuration.configure();  
  39.         serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();  
  40.         sessionFactory = configuration.buildSessionFactory(serviceRegistry);  
  41.     } catch (Exception e) {  
  42.         System.err.println("%%%% Error Creating SessionFactory %%%%");  
  43.         e.printStackTrace();  
  44.     }  
  45.     }  
  46.   
  47.     public static void closeSession() throws HibernateException {  
  48.         Session session = (Session) threadLocal.get();  
  49.         threadLocal.set(null);  
  50.   
  51.         if (session != null) {  
  52.             session.close();  
  53.         }  
  54.     }  
  55.   
  56.     public static org.hibernate.SessionFactory getSessionFactory() {//提供一个公共接口让外界获得这个单例sessionFactory  
  57.     return sessionFactory;  
  58.     }  
  59.   
  60.     public static Configuration getConfiguration() {  
  61.     return configuration;  
  62.     }  
  63.   
  64. }  
        从创建的HibernateSessionFactory中可以看出,主要用到了单例模式和线程池技术。也不难理解。

3.5 通过逆向工程生成model、orm映射文件

        下面开始使用逆向工程创建实例对象了,也就是数据库的表对应的model。在DB Browsera窗口右击我们刚刚创建的表shop,选择Hibernate Reverse Engineering开始创建:

SSH项目_第11张图片

        创建的时候有两种方式,基于配置文件的和基于注解的,具体的看开发人员心情了,可以选择:

SSH项目_第12张图片

        然后下一步,选择一下native主键自增方式,然后便完成了逆向工程创建model和orm映射了。

SSH项目_第13张图片

        完成后,会有Category的model生成,同时在hibernate.cfg.xml文件中也会生成相应的映射,前面基于配置文件的和基于注解的在hibernate.cfg.xml中生成的映射时不同的。

3.6 测试Hibernate持久化数据库

        因为这里还没有与Spring整合,只是单纯的搭建Hibernate开发环境,所以我们没有必要使用注解,我们通过直接new一个service的方式执行数据入库。

        先写CategoryService接口和实现类:

[java] view plain copy
  1. public interface CategoryService {  
  2.     public void save(Category category); //用来测试Hibernate环境  
  3. }  
  4.   
  5. public class CategoryServiceImpl implements CategoryService {  
  6.   
  7.     @Override //没有和Spring整合的情况  
  8.     public void save(Category category) {  
  9.         //通过刚刚生成的sessionFactory获取session  
  10.         Session session = HibernateSessionFactory.getSession();  
  11.         try {  
  12.             //手动事务  
  13.             session.getTransaction().begin();  
  14.             //执行业务逻辑  
  15.             session.save(category);  
  16.             //手动提交  
  17.             session.getTransaction().commit();  
  18.         } catch(Exception e) {  
  19.             session.getTransaction().rollback();  
  20.             throw new RuntimeException(e);  
  21.         } finally {  
  22.             HibernateSessionFactory.closeSession();  
  23.         }         
  24.     }  
  25. }  
        下面在刚刚的测试用例中添加对Hibernate的测试:
[java] view plain copy
  1. @RunWith(SpringJUnit4ClassRunner.class)  
  2. @ContextConfiguration(locations="classpath:beans.xml")  
  3. public class SSHTest {  
  4.       
  5.     @Resource  
  6.     private Date date;    
  7.       
  8.     @Test //测试Spring IOC的开发环境  
  9.     public void springIoc() {  
  10.         System.out.println(date);  
  11.     }  
  12.       
  13.     @Test  //测试Hibernate的开发环境,因为没有整合,可以直接new  
  14.     public void hihernate() {  
  15.         CategoryService categoryService = new CategoryServiceImpl();  
  16.         Category category = new Category("男士休闲"true);  
  17.         categoryService.save(category);  
  18.     }  
  19. }  

        我们查看数据库,发现多了刚刚插入的这项,说明Hibernate环境没有问题。至此,Hibernate的开发环境我们就搭建好了

4. 整合Spring和Hibernate

        搭建好了Spring和Hibernate的开发环境后,我们开始整合这两者。整合Spring和Hibernate后就可以使用AOP让Spring来管理Hibernate的事务了。整合Spring和Hibernate主要从两大方面入手,一是导入必要的jar包,二是配置beans.xml文件。下面我们一步步整合Spring和Hibernate。

4.1 导入相应的jar包

        整合Spring和Hibernate时需要导入的jar包有两大块,spring4.2.4-persistence和c3p0-0.9.5.1,每一块jar包中的具体jar文件请参见上面的截图,这里不再赘述。下面开始配置beans.xml文件了。

4.2 配置数据源dataSource

        首先配置一下dataSource,然后hibernate.cfg.xml中相应的部分可以干掉了。因为在Spring中配置好了,Spring会去初始化这个dataSource,也就是说这就交给Spring来完成了,hibernate.cfg.xml中的相应部分可以删掉了。如下:

[html] view plain copy
  1.   
  2. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">  
  3.     <property name="driverClass" value="com.mysql.jdbc.Driver" />  
  4.     <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/shop" />  
  5.     <property name="user" value="root" />  
  6.     <property name="password" value="root" />  
  7. bean>  

        hibernate.cfg.xml中需要干掉的部分:

SSH项目_第14张图片

4.3 配置sessionFactory

        配置sessionFactory是用来产生一个session的,另外HibernateTemplate也可以,但是这里采用sessionFactory而不用HibernateTemplate,是因为HibernateTemplate是Spring提供的,依赖于Spring,如果哪天不用Spring了,就会报错。而sessionFactory是Hibernate提供的,没有问题。HibernateTemplate的依赖性太强了。下面看一下具体配置:

[html] view plain copy
  1.   
  2. <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
  3.      <property name="dataSource" ref="dataSource" />  
  4.      <property name="configLocation" value="classpath:hibernate.cfg.xml" />   
  5. bean>  
        sessionFactory中的dataSource我们用刚刚配好的dataSource,用ref属性引用进来即可,configLocation我们不在这配了,直接加载hibernate.cfg.xml文件,使用hibernate配置文件中的配置,更加简洁方便。

4.4 配置事务管理器

        配置事务管理器,是用来管理sessionFactory的,这样所有的由sessionFactory产生的session将会有声明式的管理。配置如下:

[html] view plain copy
  1.   
  2. <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
  3.      <property name="sessionFactory" ref="sessionFactory" />  
  4. bean>  
        同样,sessionFactory我们用刚刚配置好的sessionFactory,用ref属性引用进来即可。到这里就会发现,从上面一直配下来,都是一连串的操作,一个个引用下来。

4.5 配置advice(通知)

        配置advice的目的是指定哪些方法需要什么类型的事务模式。看配置:

[html] view plain copy
  1. <tx:advice id="advice" transaction-manager="transactionManager">  
  2.     <tx:attributes>  
  3.         <tx:method name="save*" propagation="REQUIRED"/>  
  4.         <tx:method name="update*" propagation="REQUIRED"/>  
  5.         <tx:method name="delete*" propagation="REQUIRED"/>  
  6.         <tx:method name="*" propagation="SUPPORTS"/>  
  7.     tx:attributes>  
  8. tx:advice>  
        REQUIRED表示如果存在事务,则支持当前的事务,如果没有则创建一个新的事务,这个事务模式应用在所有以save、update和delete开头的方法上,也就是说对数据库的增删改的时候需要添加事务支持。SUPPORTS表示如果存在事务,则支持当前的事务,如果没有就算了。

4.6 配置AOP切面

[html] view plain copy
  1. <aop:config>  
  2.       
  3.     <aop:pointcut id="pointcut" expression="execution(* cn.it.shop.service.impl.*.*(..))" />  
  4.     <aop:advisor advice-ref="advice" pointcut-ref="pointcut"/>  
  5.       
  6.  aop:config>  
        AOP即面向切面编程,aop:pointcut定义一个切面,expression属性中配置的意思是所有cn.it.shop.service.impl包下的所有方法,不管返回值和参数是什么,都要切入事务。该包是属于dao层的,直接操作数据库的。aop:advice将通知和切面结合起来,我们直接使用上面配置好的advice和pointcut,将其引入进来即可。这样配置好了后,意思就是说,凡是cn.it.shop.service.impl包下的方法都需要切入事务管理,具体地,以save、update、delete开头的方法使用REQUIED方式,其他方法使用SUPPORTS方式。这样就很好理解这个配置的意思了。

4.7 测试整合结果

        之前搭建Hibernate环境的时候,我们测试是直接new了一个Service来操作数据库,因为当时还没有和Spring整合。现在通过配置beans.xml后,让Spring去管理Hibernate的事务了,所以现在的测试要把Service交给Spring管理,通过Spring注入进来,并且依赖sessionFactory,如果能插入数据到数据库,则说明声明事务OK。

        首先,我们要在Spring的配置文件beans.xml中配一下这个Service:

[html] view plain copy
  1. <bean id="categoryService" class="cn.it.shop.service.impl.CategoryServiceImpl">  
  2.     <property name="sessionFactory" ref="sessionFactory" />  
  3. bean>  

        其次,我们需要在CategoryService接口和它的实现类CategoryServiceImpl中增加一个方法用来测试整合后的情况:

[java] view plain copy
  1. public interface CategoryService {  
  2.     public void save(Category category); //用来测试Hibernate环境  
  3.     public void update(Category category); //用来测试Spring和Hibernate整合后  
  4. }  
  5.   
  6. public class CategoryServiceImpl implements CategoryService {  
  7.   
  8.     @Override //没有和Spring整合的情况  
  9.     public void save(Category category) {  
  10.         //通过工具类获取session  
  11.         Session session = HibernateSessionFactory.getSession();  
  12.         try {  
  13.             //手动事务  
  14.             session.getTransaction().begin();  
  15.             //执行业务逻辑  
  16.             session.save(category);  
  17.             //手动提交  
  18.             session.getTransaction().commit();  
  19.         } catch(Exception e) {  
  20.             session.getTransaction().rollback();  
  21.             throw new RuntimeException(e);  
  22.         } finally {  
  23.             HibernateSessionFactory.closeSession();  
  24.         }  
  25.           
  26.     }  
  27.     /*Spring和Hibernate整个后*/  
  28.     private SessionFactory sessionFactory; //定义一个sessionFactory  
  29.       
  30.     //当需要使用sessoinFactory的时候,Spring会将sessionFactory注入进来  
  31.     public void setSessionFactory(SessionFactory sessionFactory) {  
  32.         this.sessionFactory = sessionFactory;  
  33.     }    
  34.     protected Session getSession() {  
  35.         //从当前线程获取session,如果没有则创建一个新的session  
  36.         return sessionFactory.getCurrentSession();  
  37.     }  
  38.       
  39.     @Override //Spring和Hibernate整合后的情况  
  40.     public void update(Category category) {  
  41.         getSession().update(category);      
  42.     }  
  43. }  
        现在我们可以去测试类中增添测试方法,来测试Spring和Hibernate整合后的结果了:
[java] view plain copy
  1. @RunWith(SpringJUnit4ClassRunner.class)  
  2. @ContextConfiguration(locations="classpath:beans.xml")  
  3. public class SSHTest {  
  4.       
  5.     @Resource  
  6.     private Date date;  
  7.       
  8.     @Resource  
  9.     private CategoryService categoryService;  
  10.       
  11.     @Test //测试Spring IOC的开发环境  
  12.     public void springIoc() {  
  13.         System.out.println(date);  
  14.     }  
  15.       
  16.     @Test  //测试Hibernate的开发环境,因为没有整合,可以直接new  
  17.     public void hihernate() {  
  18.         CategoryService categoryService = new CategoryServiceImpl();  
  19.         Category category = new Category("男士休闲"true);  
  20.         categoryService.save(category);  
  21.     }  
  22.       
  23.     @Test //测试Hibernate和Spring整合后  
  24.     public void hibernateAndSpring() {  
  25.         categoryService.update(new Category(1"休闲女式"true)); //categoryService通过Spring从上面注入进来的  
  26.     }  
  27. }  
        然后我们查看数据库,发现id=1的category被修改成了休闲女式了,说明更新成功。至此,Spring和Hibernate整合成功。

5. 搭建Struts2环境

5.1 添加相应的配置和jar包

        struts2运行所需的jar包我放在struts2.3.41的Library中了,直接引入即可,不再赘述。另外,还要对web.xml文件进行配置,配置如下:

[html] view plain copy
  1. xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  
  3.   <display-name>E_shopdisplay-name>  
  4.   <welcome-file-list>  
  5.     <welcome-file>index.jspwelcome-file>  
  6.   welcome-file-list>  
  7.     
  8.   <filter>  
  9.     <filter-name>struts2filter-name>  
  10.     <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class>  
  11.   filter>  
  12.     
  13.   <filter-mapping>  
  14.     <filter-name>struts2filter-name>  
  15.     <url-pattern>*.actionurl-pattern>  
  16.   filter-mapping>  
  17.     
  18. web-app>  
        如上,我们配置了一个StrutsPrepareAndExecuteFilter过滤器,并将过滤器的url-pattern设置为*.action,即所有.action后缀的都会首先经过这个过滤器,这也是struts2的入口处。

5.2 创建Action并且配置到struts.xml文件中

        我们创建一个Action如下:

[java] view plain copy
  1. public class CategoryAction extends ActionSupport {  
  2.     private CategoryService categoryService; //设置categoryService是为了很直观的看出与Spring整合前后的不同  
  3.       
  4.     public void setCategoryService(CategoryService categoryService) {  
  5.         this.categoryService = categoryService;  
  6.     }  
  7.       
  8.     public String update() {  
  9.         System.out.println("----update----");  
  10.         System.out.println(categoryService); //整合前后输出不同  
  11.         return "index";  
  12.     }  
  13.       
  14.     public String save() {  
  15.         System.out.println("----save----");  
  16.         System.out.println(categoryService);//整合前后输出不同  
  17.         return "index";  
  18.     }  
  19. }  
        然后我们配置struts.xml文件,该文件放在src目录下:
[html] view plain copy
  1. xml version="1.0" encoding="UTF-8" ?>  
  2.     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"  
  3.     "http://struts.apache.org/dtds/struts-2.3.dtd">  
  4.   
  5. <struts>  
  6.     <package name="shop" extends="struts-default">  
  7.           
  8.         <action name="category_*" class="cn.it.shop.action.CategoryAction" method="{1}">  
  9.             <result name="index">/index.jspresult>  
  10.         action>  
  11.     package>  
  12.   
  13. struts>  

5.3 测试Struts2环境

       测试方法是:写一个jsp访问Action,如果Action可以创建,则表示struts2环境OK。即struts2的一连串流程可以正常走完:jsp-->struts.xml-->Action-->struts.xml-->jsp,这样struts2的环境就算搭好了。我们写一个简单的index.jsp

[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2.   
  3. >  
  4. <html>  
  5.   <head>  
  6.     <title>My JSP 'index.jsp' starting pagetitle>  
  7.   head>  
  8.     
  9.   <body>   
  10.     span>  
  11.     <a href="${pageContext.request.contextPath }/category_update.action">访问updatea>  
  12.     <a href="category_save.action">访问savea>  
  13.   body>  
  14. html>  
        然后我们部署以下工程,打开tomcat服务器,在浏览器中输入:http://localhost:8080/E_shop/index.jsp后,能出现正常jsp页面,然后点击两个按钮,仍然跳转到index.jsp,然后我们看一下控制台的输出信息:
[java] view plain copy
  1. ----update----  
  2. null  
  3. ----save----  
  4. null  
        说明struts2的一条线走完了,环境没有问题,至此,struts2开发环境搭建完毕。

        我们看控制台输出了null,也就是说categoryService是空,也就是说根本没拿到categoryService,因为我们没有和Spring进行整合,没有被注入进来,所以null是正常的。我们沿着控制台输出的信息往上翻,会发现一条信息:Choosing bean (struts) for (com.opensymphony.xwork2.ObjectFactory)。括号里是struts说明没有和Spring整合前,Action是有Struts2产生的。

6. Spring和Struts2整合

6.1 添加相应的jar包

        Spring与Struts2整合时的jar包主要在spring4.2.4-web里面,里面包括struts2-spring-plugin-2.3.24.1.jar,导包不再赘述。

6.2 把Action和它的依赖交给Spring管理

        在Spring的配置文件beans.xml中配置Action和它的依赖,我们目前只有一个Action,配置如下所示:

[html] view plain copy
  1. <bean id="date" class="java.util.Date" />  
  2. <bean id="categoryAction" class="cn.it.shop.action.CategoryAction" scope="prototype">  
  3.     <property name="categoryService" ref="categoryService" />   
  4. bean>  

6.3 修改struts.xml中的配置

        原来在struts.xml中,class属性对应的是具体Action的完全限定名,现在将class属性的值改为Spring中配置action的id值,即categoryAction,如下:

[html] view plain copy
  1. <struts>  
  2.     <package name="shop" extends="struts-default">  
  3.   
  4.           
  5.         <action name="category_*" class="categoryAction" method="{1}">  
  6.             <result name="index">/index.jspresult>  
  7.         action>  
  8.     package>  
  9.   
  10. struts>  

6.4 配置监听器

        在web.xml中配置监听器ContextLoaderListener,这样在服务器启动的时候就可以加载Spring的配置文件了。如下:

[html] view plain copy
  1. xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  
  3.   <display-name>E_shopdisplay-name>  
  4.   <welcome-file-list>  
  5.     <welcome-file>index.jspwelcome-file>  
  6.   welcome-file-list>  
  7.     
  8.   <filter>  
  9.     <filter-name>struts2filter-name>  
  10.     <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class>  
  11.   filter>  
  12.     
  13.   <filter-mapping>  
  14.     <filter-name>struts2filter-name>  
  15.     <url-pattern>*.actionurl-pattern>  
  16.   filter-mapping>  
  17.   
  18.    
  19.   <listener>  
  20.     <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>  
  21.   listener>  
  22.     
  23.   <context-param>  
  24.     <param-name>contextConfigLocationparam-name>  
  25.     <param-value>classpath:beans.xmlparam-value>  
  26.   context-param>  
  27.     
  28. web-app>  

6.5 测试整合结果

        我们在Action中新加一句更新数据库的语句,如下:

[java] view plain copy
  1. public class CategoryAction extends ActionSupport {  
  2.       
  3.     private Category category;//设置一个私有成员变量接收url带过来的参数,注意下面要写好get和set方法  
  4.       
  5.     private CategoryService categoryService;  
  6.       
  7.     public void setCategoryService(CategoryService categoryService) {  
  8.         this.categoryService = categoryService;  
  9.     }  
  10.       
  11.     public String update() {  
  12.         System.out.println("----update----");  
  13.         System.out.println(categoryService);//由于已经和Spring整合,所以可以拿到这个categoryService了,打印出来就不是null了  
  14.         categoryService.update(category); //新加一条语句,来更新数据库  
  15.         return "index";  
  16.     }  
  17.       
  18.     public String save() {  
  19.         System.out.println("----save----");  
  20.         System.out.println(categoryService);  
  21.         return "index";  
  22.     }  
  23.   
  24.     public Category getCategory() {  
  25.         return category;  
  26.     }  
  27.   
  28.     public void setCategory(Category category) {  
  29.         this.category = category;  
  30.     }  
  31. }  

        然后我们修改一下index.jsp文件,如下:

[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2.   
  3. >  
  4. <html>  
  5.   <head>  
  6.     <title>My JSP 'index.jsp' starting pagetitle>  
  7.   head>  
  8.     
  9.   <body>  
  10.     <a href="${pageContext.request.contextPath }/category_update.action?category.id=2&category.type=gga&category.hot=false">访问updatea>  
  11.     <a href="category_save.action">访问savea>  
  12.   body>  
  13. html>  
        然后我们部署以下工程,打开tomcat服务器,在浏览器中输入:http://localhost:8080/E_shop/index.jsp后,能出现正常jsp页面,然后点击“访问update”按钮,仍然跳转到index.jsp,然后我们看一下控制台的输出信息:
[java] view plain copy
  1. ----update----  
  2. cn.it.shop.service.impl.CategoryServiceImpl@7c5ecf80  
  3. Hibernate: update category set hot=?, type=? where id=?  
       我们看到可以输出categoryService这个对象的信息了,也可以输出执行update语句时的SQL语句,然后我们查询一下数据库,发现id=2的数据的type被更新为gga,hot更新为false。我们沿着控制台输出的信息往上翻,会发现一条信息:Choosing bean (spring) for (com.opensymphony.xwork2.ObjectFactory),括号里为spring,与上面的情况对比可知,Struts2在与Spring整合后,Action交给了Spring去管理了。

        至此,Struts2、Hibernate4和Spring4整合工作已经全部完成。接下来就可以在SSH环境下进行开发了!


        整个项目的源码下载地址:http://blog.csdn.net/eson_15/article/details/51479994

        相关阅读:http://blog.csdn.net/column/details/str2hiberspring.html


【正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之气,日后必有一番作为!下面有个“顶”字,你就顺手把它点了吧(要先登录哦)~相的准,我分文不收;相不准,你也好回来找我~嘎嘎嘎】

你可能感兴趣的:(JavaWeb,Develop,JavaFrameWorks,Develop,Java框架)