1. 程式人生 > >【SSH網上商城專案實戰01】整合Struts2、Hibernate4.3和Spring4.2

【SSH網上商城專案實戰01】整合Struts2、Hibernate4.3和Spring4.2

【2018.6.2更新】我新搭建的部落格系統上線了(使用SpringBoot搭建的),後面會在新系統中發表部落格,這裡也會給出連結,歡迎各位朋友收藏交流哈~ 
部落格地址:http://www.itcodai.com       

        今天開始做一個網上商城的專案,首先從搭建環境開始,一步步整合S2SH。這篇博文主要總結一下如何整合Struts2、Hibernate4.3和Spring4.2。

        整合三大框架得先從搭建各部分環境開始,也就是說首先得把Spring,Hibernate和Struts2的環境搭建好,確保它們沒有問題了,再做整合。這篇博文遵從的順序是:先搭建Spring環境-->然後搭建Hibernate環境--> 整合Spring和Hibernate --> 搭建Struts2環境 --> 整合Spring和Struts2。

1. 整個專案jar包的管理

        Spring的jar包很多,開發的時候建議將它們分個類,然後依次新增到User Library,方便管理,也一目瞭然。這裡我總結一下整個SSH所需要的基本jar包,看下圖:

        從圖中可以看出,首先將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包呢?請看下面的截圖:

  

        注:以上每個分類的包中,並非包含原來包中所有的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自帶的例子裡也有,考一份過來就行,見下圖:

2.2 測試Spring的IoC環境

        我們寫一個普通的java類java.util.Date類來測試一下Spring IoC是否正常,如果在測試程式中能正常注入,則說明Spring的IoC環境搭建成功,下面我們寫一個測試用例:

/**
 * @Description TODO(採用Spring的註解除錯,僅僅支援Spring3.1及以上)
 * @author Ni Shengwu
 *
 */
/*
 * Spring3.1後多了個spring-test-4.2.4.RELEASE.jar包,這個jar包專門用來支援JUnit基於註解的測試的,該jar包在spring-4.2.4-core中
 * 該jar包裡有個SpringJUnit4ClassRunner.class,用@RunWith註解加進來即可
 * 
 * 註解@ContextConfiguration表示將ApplicationContext物件注入進來,就不用像以往那樣在測試程式裡先new了,直接使用
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:beans.xml")
public class SSHTest {
	
	@Resource
	private Date date;
	
	@Test //測試Spring IOC的開發環境
 	public void springIoc() {
		System.out.println(date);
	}
}

        最後能正常輸出: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 新建資料庫和表

drop database if exists shop;
create database shop default character set utf8;
use shop;
drop table if exists category;
create table category
(
   /* 類別編號,自動增長 */
   id  int not null auto_increment,
   /* 類別名稱 */
   type varchar(20),
   /* 類別是否為熱點類別,熱點類別才有可能顯示在首頁*/
   hot  bool default false,
   /* 設定類別編號為主鍵*/
   primary key (id)
);

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,就會彈出下面的對話方塊:

        填好後,點選Test Driver測試一下,測試通過表示DataBase connection Driver已經配置好,然後finish即可,這樣我們就能在DB瀏覽器視窗中看到資料庫MySQL5.6了,右鍵開啟就能看到資料庫中已有的庫和表了,如下:

3.4 建立xml對映檔案和sessionFactory

        sessionFactory是用來建立session的,我們通過如下方式建立:工程名右鍵->myeclipse->Add Hibernate Capabilities,如果沒有Add Hibernate Capabilities,就點選project facets->Install Hibernate Facets,會彈出如下視窗:

        下一步,在MyEclipse中新增Hibernate Support,即hibernate.cfg.xml對映檔案和sessionFactory。這裡主要是給sessionFactory建個包,預設包不行。

        下一步,新增驅動,由於我們之前已經配置好了一個驅動了,所以在這裡直接選擇剛剛配置好的即可。

        下一步,由於之前我們已經新增過自己的jar保留,這裡不用選擇,直接finish。

        這樣我們就完成了Hibernate配置檔案和sessionFactory的建立。下面我們簡單看一下MyEclipse建立的sessionFactory裡面都有啥:

public class HibernateSessionFactory {

    private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); //sessionFactory中用的是執行緒池技術
    private static org.hibernate.SessionFactory sessionFactory; //sessionFactory:建立session的工廠
	
    private static Configuration configuration = new Configuration();
    private static ServiceRegistry serviceRegistry; 

    static { //類載入時初始化sessionFactory
    	try {
		configuration.configure();
		serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
		sessionFactory = configuration.buildSessionFactory(serviceRegistry); //Hibernate4中建立sessionFactory的方法
	} catch (Exception e) {
		System.err.println("%%%% Error Creating SessionFactory %%%%");
		e.printStackTrace();
	}
    }
    private HibernateSessionFactory() { //私有構造方法阻止new出物件,保證sessionFactory的單例
    }
	
    public static Session getSession() throws HibernateException {
        Session session = (Session) threadLocal.get();  //從執行緒池中拿session

		if (session == null || !session.isOpen()) { //如果執行緒池是空的,或者session開啟失敗
			if (sessionFactory == null) {
				rebuildSessionFactory(); //如果sessionFactory是空的,那就再建立一次,和static部分一樣的
			}
			session = (sessionFactory != null) ? sessionFactory.openSession() : null; //sessionFactory不為空就建立一個session
			threadLocal.set(session); //然後把這個session放到執行緒池中,下次再拿
		}

        return session;
    }

    public static void rebuildSessionFactory() {
	try {
		configuration.configure();
		serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
		sessionFactory = configuration.buildSessionFactory(serviceRegistry);
	} catch (Exception e) {
		System.err.println("%%%% Error Creating SessionFactory %%%%");
		e.printStackTrace();
	}
    }

    public static void closeSession() throws HibernateException {
        Session session = (Session) threadLocal.get();
        threadLocal.set(null);

        if (session != null) {
            session.close();
        }
    }

    public static org.hibernate.SessionFactory getSessionFactory() {//提供一個公共介面讓外界獲得這個單例sessionFactory
	return sessionFactory;
    }

    public static Configuration getConfiguration() {
	return configuration;
    }

}

        從建立的HibernateSessionFactory中可以看出,主要用到了單例模式和執行緒池技術。也不難理解。

3.5 通過逆向工程生成model、orm對映檔案

        下面開始使用逆向工程建立例項物件了,也就是資料庫的表對應的model。在DB Browsera視窗右擊我們剛剛建立的表shop,選擇Hibernate Reverse Engineering開始建立:

        建立的時候有兩種方式,基於配置檔案的和基於註解的,具體的看開發人員心情了,可以選擇:

        然後下一步,選擇一下native主鍵自增方式,然後便完成了逆向工程建立model和orm映射了。

        完成後,會有Category的model生成,同時在hibernate.cfg.xml檔案中也會生成相應的對映,前面基於配置檔案的和基於註解的在hibernate.cfg.xml中生成的對映時不同的。

3.6 測試Hibernate持久化資料庫

        因為這裡還沒有與Spring整合,只是單純的搭建Hibernate開發環境,所以我們沒有必要使用註解,我們通過直接new一個service的方式執行資料入庫。

        先寫CategoryService介面和實現類:

public interface CategoryService {
	public void save(Category category); //用來測試Hibernate環境
}

public class CategoryServiceImpl implements CategoryService {

    @Override //沒有和Spring整合的情況
    public void save(Category category) {
        //通過剛剛生成的sessionFactory獲取session
        Session session = HibernateSessionFactory.getSession();
        try {
            //手動事務
            session.getTransaction().begin();
            //執行業務邏輯
            session.save(category);
            //手動提交
            session.getTransaction().commit();
        } catch(Exception e) {
            session.getTransaction().rollback();
            throw new RuntimeException(e);
        } finally {
            HibernateSessionFactory.closeSession();
        }       
    }
}

        下面在剛剛的測試用例中新增對Hibernate的測試:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:beans.xml")
public class SSHTest {
	
	@Resource
	private Date date;	
	
	@Test //測試Spring IOC的開發環境
	public void springIoc() {
		System.out.println(date);
	}
	
	@Test  //測試Hibernate的開發環境,因為沒有整合,可以直接new
	public void hihernate() {
		CategoryService categoryService = new CategoryServiceImpl();
		Category category = new Category("男士休閒", true);
		categoryService.save(category);
	}
}

        我們檢視資料庫,發現多了剛剛插入的這項,說明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中的相應部分可以刪掉了。如下:

 <!-- com.mchange.v2.c3p0.ComboPooledDataSource類在c3p0-0.9.5.1.jar包的com.mchange.v2.c3p0包中 -->
 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
 	<property name="driverClass" value="com.mysql.jdbc.Driver" />
 	<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/shop" />
 	<property name="user" value="root" />
 	<property name="password" value="root" />
 </bean>

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

4.3 配置sessionFactory

        配置sessionFactory是用來產生一個session的,另外HibernateTemplate也可以,但是這裡採用sessionFactory而不用HibernateTemplate,是因為HibernateTemplate是Spring提供的,依賴於Spring,如果哪天不用Spring了,就會報錯。而sessionFactory是Hibernate提供的,沒有問題。HibernateTemplate的依賴性太強了。下面看一下具體配置:

<!-- org.springframework.orm.hibernate4.LocalSessionFactoryBean類在spring-orm-4.2.4.RELEASE.jar包的org.springframework.orm.hibernate4包中 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
	 <property name="dataSource" ref="dataSource" />
	 <property name="configLocation" value="classpath:hibernate.cfg.xml" /> <!-- 載入hibernate配置檔案 -->
</bean>

        sessionFactory中的dataSource我們用剛剛配好的dataSource,用ref屬性引用進來即可,configLocation我們不在這配了,直接載入hibernate.cfg.xml檔案,使用hibernate配置檔案中的配置,更加簡潔方便。

4.4 配置事務管理器

        配置事務管理器,是用來管理sessionFactory的,這樣所有的由sessionFactory產生的session將會有宣告式的管理。配置如下:

<!-- org.springframework.orm.hibernate4.HibernateTransactionManager類spring-orm-4.2.4.RELEASE.jar包的org.springframework.orm.hibernate4包中 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
	 <property name="sessionFactory" ref="sessionFactory" />
</bean>

        同樣,sessionFactory我們用剛剛配置好的sessionFactory,用ref屬性引用進來即可。到這裡就會發現,從上面一直配下來,都是一連串的操作,一個個引用下來。

4.5 配置advice(通知)

        配置advice的目的是指定哪些方法需要什麼型別的事務模式。看配置:

 <tx:advice id="advice" transaction-manager="transactionManager">
 	<tx:attributes>
 		<tx:method name="save*" propagation="REQUIRED"/>
 		<tx:method name="update*" propagation="REQUIRED"/>
 		<tx:method name="delete*" propagation="REQUIRED"/>
 		<tx:method name="*" propagation="SUPPORTS"/>
 	</tx:attributes>
 </tx:advice>

        REQUIRED表示如果存在事務,則支援當前的事務,如果沒有則建立一個新的事務,這個事務模式應用在所有以save、update和delete開頭的方法上,也就是說對資料庫的增刪改的時候需要新增事務支援。SUPPORTS表示如果存在事務,則支援當前的事務,如果沒有就算了。

4.6 配置AOP切面

<aop:config>
 	<!-- 配置哪些包的類要切入事務 -->
 	<aop:pointcut id="pointcut" expression="execution(* cn.it.shop.service.impl.*.*(..))" />
 	<aop:advisor advice-ref="advice" pointcut-ref="pointcut"/><!-- 連線了<span style="font-family:Microsoft YaHei;">上</span>面的advice和上面的pointcut -->
 	<!-- aop:pointcut要寫在aop:advisor上面,否則會報錯 -->
 </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:

 <bean id="categoryService" class="cn.it.shop.service.impl.CategoryServiceImpl">
 	<property name="sessionFactory" ref="sessionFactory" /><!-- 依賴的sessionFactory用我們之前配好的sessionFactory-->
 </bean>

        其次,我們需要在CategoryService介面和它的實現類CategoryServiceImpl中增加一個方法用來測試整合後的情況:

public interface CategoryService {
	public void save(Category category); //用來測試Hibernate環境
	public void update(Category category); //用來測試Spring和Hibernate整合後
}

public class CategoryServiceImpl implements CategoryService {

    @Override //沒有和Spring整合的情況
    public void save(Category category) {
        //通過工具類獲取session
        Session session = HibernateSessionFactory.getSession();
        try {
            //手動事務
            session.getTransaction().begin();
            //執行業務邏輯
            session.save(category);
            //手動提交
            session.getTransaction().commit();
        } catch(Exception e) {
            session.getTransaction().rollback();
            throw new RuntimeException(e);
        } finally {
            HibernateSessionFactory.closeSession();
        }
        
    }
    /*Spring和Hibernate整個後*/
    private SessionFactory sessionFactory; //定義一個sessionFactory
    
    //當需要使用sessoinFactory的時候,Spring會將sessionFactory注入進來
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }  
    protected Session getSession() {
        //從當前執行緒獲取session,如果沒有則建立一個新的session
        return sessionFactory.getCurrentSession();
    }
    
    @Override //Spring和Hibernate整合後的情況
    public void update(Category category) {
        getSession().update(category);    
    }
}

        現在我們可以去測試類中增添測試方法,來測試Spring和Hibernate整合後的結果了:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:beans.xml")
public class SSHTest {
	
	@Resource
	private Date date;
	
	@Resource
	private CategoryService categoryService;
	
	@Test //測試Spring IOC的開發環境
	public void springIoc() {
		System.out.println(date);
	}
	
	@Test  //測試Hibernate的開發環境,因為沒有整合,可以直接new
	public void hihernate() {
		CategoryService categoryService = new CategoryServiceImpl();
		Category category = new Category("男士休閒", true);
		categoryService.save(category);
	}
	
	@Test //測試Hibernate和Spring整合後
	public void hibernateAndSpring() {
		categoryService.update(new Category(1, "休閒女式", true)); //categoryService通過Spring從上面注入進來的
	}
}

        然後我們檢視資料庫,發現id=1的category被修改成了休閒女式了,說明更新成功。至此,Spring和Hibernate整合成功。

5. 搭建Struts2環境

5.1 新增相應的配置和jar包

        struts2執行所需的jar包我放在struts2.3.41的Library中了,直接引入即可,不再贅述。另外,還要對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" 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">
  <display-name>E_shop</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <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>*.action</url-pattern>
  </filter-mapping>
  
</web-app>

        如上,我們配置了一個StrutsPrepareAndExecuteFilter過濾器,並將過濾器的url-pattern設定為*.action,即所有.action字尾的都會首先經過這個過濾器,這也是struts2的入口處。

5.2 建立Action並且配置到struts.xml檔案中

        我們建立一個Action如下:

public class CategoryAction extends ActionSupport {
	private CategoryService categoryService; //設定categoryService是為了很直觀的看出與Spring整合前後的不同
	
	public void setCategoryService(CategoryService categoryService) {
		this.categoryService = categoryService;
	}
	
	public String update() {
		System.out.println("----update----");
		System.out.println(categoryService); //整合前後輸出不同
		return "index";
	}
	
	public String save() {
		System.out.println("----save----");
		System.out.println(categoryService);//整合前後輸出不同
		return "index";
	}
}

        然後我們配置struts.xml檔案,該檔案放在src目錄下:

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

<struts>
	<package name="shop" extends="struts-default">
		<!-- category_update.actiocan: 訪問update方法 -->
		<action name="category_*" class="cn.it.shop.action.CategoryAction" method="{1}">
			<result name="index">/index.jsp</result>
		</action>
	</package>

</struts>

5.3 測試Struts2環境

       測試方法是:寫一個jsp訪問Action,如果Action可以建立,則表示struts2環境OK。即struts2的一連串流程可以正常走完:jsp-->struts.xml-->Action-->struts.xml-->jsp,這樣struts2的環境就算搭好了。我們寫一個簡單的index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
  </head>
  
  <body> 
    <!-- 下面兩種寫法都可以訪問 --></span>
    <a href="${pageContext.request.contextPath }/category_update.action">訪問update</a>
    <a href="category_save.action">訪問save</a>
  </body>
</html>

        然後我們部署以下工程,開啟tomcat伺服器,在瀏覽器中輸入:http://localhost:8080/E_shop/index.jsp後,能出現正常jsp頁面,然後點選兩個按鈕,仍然跳轉到index.jsp,然後我們看一下控制檯的輸出資訊:

----update----
null
----save----
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,配置如下所示:

 <bean id="date" class="java.util.Date" />
 <bean id="categoryAction" class="cn.it.shop.action.CategoryAction" scope="prototype">
 	<property name="categoryService" ref="categoryService" /> <!-- 依賴的categoryService用上面和Hibernate整合時配置好的categoryService -->
 </bean>

6.3 修改struts.xml中的配置

        原來在struts.xml中,class屬性對應的是具體Action的完全限定名,現在將class屬性的值改為Spring中配置action的id值,即categoryAction,如下:

<struts>
	<package name="shop" extends="struts-default">

		<!-- class對應的是Spring中配置該Action的id值,因為要交給Spring管理 -->
		<action name="category_*" class="categoryAction" method="{1}">
			<result name="index">/index.jsp</result>
		</action>
	</package>

</struts>

6.4 配置監聽器

        在web.xml中配置監聽器ContextLoaderListener,這樣在伺服器啟動的時候就可以載入Spring的配置檔案了。如下:

<?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" 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">
  <display-name>E_shop</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <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>*.action</url-pattern>
  </filter-mapping>

 <!-- web.xml中監聽器的啟動優先順序要高於過濾器,所以配在下面無所謂的 -->
  <listener>
  	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>classpath:beans.xml</param-value>
  </context-param>
  
</web-app>

6.5 測試整合結果

        我們在Action中新加一句更新資料庫的語句,如下:

public class CategoryAction extends ActionSupport {
	
	private Category category;//設定一個私有成員變數接收url帶過來的引數,注意下面要寫好get和set方法
	
	private CategoryService categoryService;
	
	public void setCategoryService(CategoryService categoryService) {
		this.categoryService = categoryService;
	}
	
	public String update() {
		System.out.println("----update----");
		System.out.println(categoryService);//由於已經和Spring整合,所以可以拿到這個categoryService了,打印出來就不是null了
		categoryService.update(category); //新加一條語句,來更新資料庫
		return "index";
	}
	
	public String save() {
		System.out.println("----save----");
		System.out.println(categoryService);
		return "index";
	}

	public Category getCategory() {
		return category;
	}

	public void setCategory(Category category) {
		this.category = category;
	}
}

        然後我們修改一下index.jsp檔案,如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
  </head>
  
  <body>
    <a href="${pageContext.request.contextPath }/category_update.action?category.id=2&category.type=gga&category.hot=false">訪問update</a>
    <a href="category_save.action">訪問save</a>
  </body>
</html>

        然後我們部署以下工程,開啟tomcat伺服器,在瀏覽器中輸入:http://localhost:8080/E_shop/index.jsp後,能出現正常jsp頁面,然後點選“訪問update”按鈕,仍然跳轉到index.jsp,然後我們看一下控制檯的輸出資訊:

----update----
[email protected]
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環境下進行開發了!

        【正在看本人部落格的這位童鞋,我看你氣度不凡,談吐間隱隱有王者之氣,日後必有一番作為!下面有個“頂”字,你就順手把它點了吧(要先登入哦)~相的準,我分文不收;相不準,你也好回來找我~嘎嘎嘎】

       文末福利:“程式設計師私房菜”,一個有溫度的公眾號~ 
        程式設計師私房菜

_____________________________________________________________________________________________________________________________________________________

-----樂於分享,共同進步!

相關推薦

SSH網上商城專案實戰01整合Struts2Hibernate4.3Spring4.2

【2018.6.2更新】我新搭建的部落格系統上線了(使用SpringBoot搭建的),後面會在新系統中發表部落格,這裡也會給出連結,歡迎各位朋友收藏交流哈~  部落格地址:http://www.itcodai.com                今天開始做一個網上商城

SSH網上商城專案實戰15執行緒定時器同步首頁資料(類似於部落格定期更新排名)

  轉自:https://blog.csdn.net/eson_15/article/details/51387378   上一節我們做完了首頁UI介面,但是有個問題:如果我在後臺添加了一個商品,那麼我必須重啟一下伺服器才能重新同步後臺資料,然後重新整理首頁才能同步資

SSH學習02 SSH網上商城專案實戰02基本增刪查改ServiceAction的抽取以及使用註解替換xml

【SSH網上商城專案實戰02】基本增刪查改、Service和Action的抽取以及使用註解替換xml 轉自:https://blog.csdn.net/eson_15/article/details/51297698 上一節我們搭建好了Struts2、Hibernate和Spring的開

SSH網上商城專案實戰05完成資料庫的級聯查詢分頁

  轉自:https://blog.csdn.net/eson_15/article/details/51320212 上一節我們完成了EasyUI選單的實現。這一節我們主要來寫一下CategoryServiceImpl實現類,完成資料庫的級聯查詢。一般專案從後往前做,先做se

SSH網上商城專案實戰08查詢刪除商品類別功能的實現

  轉自:https://blog.csdn.net/eson_15/article/details/51338991 上一節我們完成了使用DataGrid顯示所有商品資訊,這節我們開始新增幾個功能:新增、更新、刪除和查詢。首先我們實現下前臺的顯示,然後再做後臺獲取資料。

SSH網上商城專案實戰07Struts2Json的整合

    轉自:https://blog.csdn.net/eson_15/article/details/51332758   上一節我們完成了DataGrid顯示jason資料,但是沒有和後臺聯絡在一起,只是單純地顯示了我們自己弄的json資

SSH網上商城專案實戰06基於DataGrid的資料顯示

  轉自:https://blog.csdn.net/eson_15/article/details/51322262 1. 回顧一下第4節內容         在第4節中,我們使用Eas

SSH網上商城專案實戰11查詢刪除商品功能的實現

  轉自:https://blog.csdn.net/eson_15/article/details/51360804   在第8節我們完成了查詢和刪除商品類別的功能,那麼現在實現查詢和刪除商品的功能就很好做了,原理和第8節一模一樣,只是修改一些引數,比如請求不同的a

SSH網上商城專案實戰10商品類基本模組的搭建

      前面我們完成了與商品類別相關的業務邏輯,接下來我們開始做具體商品部分。 1. 資料庫建表並對映Model         首先我們在資料庫中新建一張表,然後使用逆

SSH網上商城專案實戰17購物車基本功能的實現

  轉自:https://blog.csdn.net/eson_15/article/details/51418350 上一節我們將商品的詳細頁面做完了,並使用了Hibernate的二級快取載入詳細頁面來提高系統的效能。這節我們開始做購物車部分。 1. 新增新的表

SSH網上商城專案實戰16Hibernate的二級快取處理首頁的熱門顯示

    轉自:https://blog.csdn.net/eson_15/article/details/51405911   網上商城首頁都有熱門商品,那麼這些商品的點選率是很高的,當用戶點選某個熱門商品後需要進入商品的詳細資訊頁面,就像淘寶裡面

SSH網上商城專案實戰14商城首頁UI的設計

  轉自:https://blog.csdn.net/eson_15/article/details/51373403 前面我們利用EasyUI和SSH搭建好了後臺的基本框架,做好了後臺的基本功能,包括對商品類別的管理和商品的管理等,這一節我們開始搭建前臺頁面。 做首頁的思

SSH網上商城專案實戰13Struts2實現檔案上傳功能

  轉自:https://blog.csdn.net/eson_15/article/details/51366384 上一節我們做完了新增和更新商品的功能,這兩個部分裡有涉及到商品圖片的上傳,並沒有詳細解說。為此,這篇文章詳細介紹一下Struts2實現檔案上傳的功能。 1

SSH網上商城專案實戰12新增更新商品功能的實現

  新增商品部分原理和新增商品類別是一樣的,不過要比商品類別複雜,因為商品的屬性有很多,對應的資料庫中的欄位也就多了,新增商品還有個選項是上傳圖片,這一小塊內容會在下一篇部落格中單獨說明,因為這涉及到一個知識點,就是Struts2實現檔案上傳功能。其他廢話不多說了,現在開始完善新增

SSH網上商城專案實戰18過濾器實現購物登入功能的判斷

    轉自:https://blog.csdn.net/eson_15/article/details/51425010     上一節我們做完了購物車的基本操作,但是有個問題是:當用戶點選結算

SSH網上商城專案實戰21從Demo中看易寶支付的流程

        這一節我們先寫一個簡單點的Demo來測試易寶支付的流程,熟悉這個流程後,再做實際的開發,因為是一個Demo,所以我沒有考慮一些設計模

SSH網上商城專案實戰23完成線上支付功能

    轉自: https://blog.csdn.net/eson_15/article/details/51464415  上一節我們做好了支付頁面的顯示,從上一節支付頁面顯示的jsp程式碼中可以看出,當用戶點選

SSH網上商城專案實戰25使用java email給使用者傳送郵件

      當用戶購買完商品後,我們應該向使用者傳送一封郵件,告訴他訂單已生成之類的資訊,郵箱地址是從使用者的基本資訊中獲取,好了,首先我們來看一下java中傳送郵件的方法。

SSH網上商城專案實戰24Struts2中如何處理多個Model請求

    1. 問題的提出   Struts2中如果實現了ModelDriven<model>介面

SSH網上商城專案實戰26完成訂單支付後的簡訊傳送功能

    上一節我們使用了Java mail完成了給買家傳送郵件的功能,還遺留一個功能,就是給買家傳送簡訊,告訴他訂單已經生成之類的。這一節主要介紹一下如何在使用者支付完成後自動給使用者傳送簡訊。