SSH框架網(wǎng)上商城項(xiàng)目第1戰(zhàn)之整合Struts2、Hibernate4.3和Spring4.2
本文開始做一個(gè)網(wǎng)上商城的項(xiàng)目,首先從搭建環(huán)境開始,一步步整合S2SH。這篇博文主要總結(jié)一下如何整合Struts2、Hibernate4.3和Spring4.2。
整合三大框架得先從搭建各部分環(huán)境開始,也就是說首先得把Spring,Hibernate和Struts2的環(huán)境搭建好,確保它們沒有問題了,再做整合。這篇博文遵從的順序是:先搭建Spring環(huán)境-->然后搭建Hibernate環(huán)境--> 整合Spring和Hibernate --> 搭建Struts2環(huán)境 --> 整合Spring和Struts2。
1. 整個(gè)項(xiàng)目jar包的管理
Spring的jar包很多,開發(fā)的時(shí)候建議將它們分個(gè)類,然后依次添加到User Library,方便管理,也一目了然。這里我總結(jié)一下整個(gè)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相關(guān)的都放到aop中,與持久化(與Hibernate整合)相關(guān)的放到persistence中,與web(與struts2整合)相關(guān)的放到web中。每個(gè)部分都有哪些jar包呢?請(qǐng)看下面的截圖:

注:以上每個(gè)分類的包中,并非包含原來包中所有的jar,有些jar文件并沒有用到,等具體項(xiàng)目需要的時(shí)候再往里加就行了,上圖是保證項(xiàng)目的環(huán)境可以搭建所需要的的最基本的jar包。
2.搭建Spring環(huán)境
上面的jar包截圖是最后整合好的所有jar包,剛開始搭建環(huán)境的時(shí)候不需要一次性全部加進(jìn)來,可以一點(diǎn)一點(diǎn)的加,這樣也更利于理解每個(gè)部分的jar包都有什么作用,當(dāng)然,一次都加進(jìn)來也是可以的。
2.1 添加配置文件beans.xml和相應(yīng)的jar包
新建一個(gè)工程,然后添加在User Library中添加自己的庫,這里主要添加兩個(gè),即spring-4.2.4-core和spring4.2.4-aop,添加jar包不再贅述。添加完了后,在src目錄下添加beans.xml文件,這個(gè)文件的模板網(wǎng)上很多,Spring自帶的例子里也有,考一份過來就行,見下圖:

2.2 測(cè)試Spring的IoC環(huán)境
我們寫一個(gè)普通的java類java.util.Date類來測(cè)試一下Spring IoC是否正常,如果在測(cè)試程序中能正常注入,則說明Spring的IoC環(huán)境搭建成功,下面我們寫一個(gè)測(cè)試用例:
/**
* @Description TODO(采用Spring的注解調(diào)試,僅僅支持Spring3.1及以上)
* @author Ni Shengwu
*
*/
/*
* Spring3.1后多了個(gè)spring-test-4.2.4.RELEASE.jar包,這個(gè)jar包專門用來支持JUnit基于注解的測(cè)試的,該jar包在spring-4.2.4-core中
* 該jar包里有個(gè)SpringJUnit4ClassRunner.class,用@RunWith注解加進(jìn)來即可
*
* 注解@ContextConfiguration表示將ApplicationContext對(duì)象注入進(jìn)來,就不用像以往那樣在測(cè)試程序里先new了,直接使用
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:beans.xml")
public class SSHTest {
@Resource
private Date date;
@Test //測(cè)試Spring IOC的開發(fā)環(huán)境
public void springIoc() {
System.out.println(date);
}
}
最后能正常輸出:Thu Apr 28 22:45:13 CST 2016。說明Date對(duì)象已經(jīng)被Spring給注入進(jìn)來了,從而驗(yàn)證了Spring IoC功能正常,為此,Spring的環(huán)境搭建完成。
3. 搭建Hibernate環(huán)境
Hibernate的環(huán)境搭建相比于Spring要復(fù)雜一些,因?yàn)橛玫搅薓yEclipse中的逆向工程。我們按以下步驟來搭建Hibernate開發(fā)環(huán)境:
3.1 添加相應(yīng)的jar包
這里主要是向User Library中添加兩項(xiàng)jar包:hibernate4.3.11和MySQL驅(qū)動(dòng)包mysql-connector-java-5.1.26,不再贅述。
3.2 新建數(shù)據(jù)庫和表
drop database if exists shop; create database shop default character set utf8; use shop; drop table if exists category; create table category ( /* 類別編號(hào),自動(dòng)增長(zhǎng) */ id int not null auto_increment, /* 類別名稱 */ type varchar(20), /* 類別是否為熱點(diǎn)類別,熱點(diǎn)類別才有可能顯示在首頁*/ hot bool default false, /* 設(shè)置類別編號(hào)為主鍵*/ primary key (id) );
3.3 DB瀏覽器連接到Mysql數(shù)據(jù)庫
DB瀏覽器指的是MyEclipse中的一個(gè)視圖窗口,可以很直觀的看到MySQL中都有哪些數(shù)據(jù)庫和表,打開DB瀏覽器的方法:Window->Open Perspective->DB Browser打開DB瀏覽器工作窗口。如果沒有DB Browser,按照下面:Window->Show View->other->輸入DB Browser,找到打開即可。
打開后,我們開始連接到MySQL數(shù)據(jù)庫了,在DB Browser窗口的空白處右鍵->new,就會(huì)彈出下面的對(duì)話框:

填好后,點(diǎn)擊Test Driver測(cè)試一下,測(cè)試通過表示DataBase connection Driver已經(jīng)配置好,然后finish即可,這樣我們就能在DB瀏覽器窗口中看到數(shù)據(jù)庫MySQL5.6了,右鍵打開就能看到數(shù)據(jù)庫中已有的庫和表了,如下:

3.4 創(chuàng)建xml映射文件和sessionFactory
sessionFactory是用來創(chuàng)建session的,我們通過如下方式創(chuàng)建:工程名右鍵->myeclipse->Add Hibernate Capabilities,如果沒有Add Hibernate Capabilities,就點(diǎn)擊project facets->Install Hibernate Facets,會(huì)彈出如下窗口:

下一步,在MyEclipse中添加Hibernate Support,即hibernate.cfg.xml映射文件和sessionFactory。這里主要是給sessionFactory建個(gè)包,默認(rèn)包不行。

下一步,添加驅(qū)動(dòng),由于我們之前已經(jīng)配置好了一個(gè)驅(qū)動(dòng)了,所以在這里直接選擇剛剛配置好的即可。

下一步,由于之前我們已經(jīng)添加過自己的jar保留,這里不用選擇,直接finish。

這樣我們就完成了Hibernate配置文件和sessionFactory的創(chuàng)建。下面我們簡(jiǎn)單看一下MyEclipse創(chuàng)建的sessionFactory里面都有啥:
public class HibernateSessionFactory {
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); //sessionFactory中用的是線程池技術(shù)
private static org.hibernate.SessionFactory sessionFactory; //sessionFactory:創(chuàng)建session的工廠
private static Configuration configuration = new Configuration();
private static ServiceRegistry serviceRegistry;
static { //類加載時(shí)初始化sessionFactory
try {
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry); //Hibernate4中創(chuàng)建sessionFactory的方法
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
private HibernateSessionFactory() { //私有構(gòu)造方法阻止new出對(duì)象,保證sessionFactory的單例
}
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get(); //從線程池中拿session
if (session == null || !session.isOpen()) { //如果線程池是空的,或者session打開失敗
if (sessionFactory == null) {
rebuildSessionFactory(); //如果sessionFactory是空的,那就再創(chuàng)建一次,和static部分一樣的
}
session = (sessionFactory != null) ? sessionFactory.openSession() : null; //sessionFactory不為空就創(chuàng)建一個(gè)session
threadLocal.set(session); //然后把這個(gè)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() {//提供一個(gè)公共接口讓外界獲得這個(gè)單例sessionFactory
return sessionFactory;
}
public static Configuration getConfiguration() {
return configuration;
}
}
從創(chuàng)建的HibernateSessionFactory中可以看出,主要用到了單例模式和線程池技術(shù)。也不難理解。
3.5 通過逆向工程生成model、orm映射文件
下面開始使用逆向工程創(chuàng)建實(shí)例對(duì)象了,也就是數(shù)據(jù)庫的表對(duì)應(yīng)的model。在DB Browsera窗口右擊我們剛剛創(chuàng)建的表shop,選擇Hibernate Reverse Engineering開始創(chuàng)建:

創(chuàng)建的時(shí)候有兩種方式,基于配置文件的和基于注解的,具體的看開發(fā)人員心情了,可以選擇:

然后下一步,選擇一下native主鍵自增方式,然后便完成了逆向工程創(chuàng)建model和orm映射了。

完成后,會(huì)有Category的model生成,同時(shí)在hibernate.cfg.xml文件中也會(huì)生成相應(yīng)的映射,前面基于配置文件的和基于注解的在hibernate.cfg.xml中生成的映射時(shí)不同的。
3.6 測(cè)試Hibernate持久化數(shù)據(jù)庫
因?yàn)檫@里還沒有與Spring整合,只是單純的搭建Hibernate開發(fā)環(huán)境,所以我們沒有必要使用注解,我們通過直接new一個(gè)service的方式執(zhí)行數(shù)據(jù)入庫。
先寫CategoryService接口和實(shí)現(xiàn)類:
public interface CategoryService {
public void save(Category category); //用來測(cè)試Hibernate環(huán)境
}
public class CategoryServiceImpl implements CategoryService {
@Override //沒有和Spring整合的情況
public void save(Category category) {
//通過剛剛生成的sessionFactory獲取session
Session session = HibernateSessionFactory.getSession();
try {
//手動(dòng)事務(wù)
session.getTransaction().begin();
//執(zhí)行業(yè)務(wù)邏輯
session.save(category);
//手動(dòng)提交
session.getTransaction().commit();
} catch(Exception e) {
session.getTransaction().rollback();
throw new RuntimeException(e);
} finally {
HibernateSessionFactory.closeSession();
}
}
}
下面在剛剛的測(cè)試用例中添加對(duì)Hibernate的測(cè)試:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:beans.xml")
public class SSHTest {
@Resource
private Date date;
@Test //測(cè)試Spring IOC的開發(fā)環(huán)境
public void springIoc() {
System.out.println(date);
}
@Test //測(cè)試Hibernate的開發(fā)環(huán)境,因?yàn)闆]有整合,可以直接new
public void hihernate() {
CategoryService categoryService = new CategoryServiceImpl();
Category category = new Category("男士休閑", true);
categoryService.save(category);
}
}
我們查看數(shù)據(jù)庫,發(fā)現(xiàn)多了剛剛插入的這項(xiàng),說明Hibernate環(huán)境沒有問題。至此,Hibernate的開發(fā)環(huán)境我們就搭建好了。
4. 整合Spring和Hibernate
搭建好了Spring和Hibernate的開發(fā)環(huán)境后,我們開始整合這兩者。整合Spring和Hibernate后就可以使用AOP讓Spring來管理Hibernate的事務(wù)了。整合Spring和Hibernate主要從兩大方面入手,一是導(dǎo)入必要的jar包,二是配置beans.xml文件。下面我們一步步整合Spring和Hibernate。
4.1 導(dǎo)入相應(yīng)的jar包
整合Spring和Hibernate時(shí)需要導(dǎo)入的jar包有兩大塊,spring4.2.4-persistence和c3p0-0.9.5.1,每一塊jar包中的具體jar文件請(qǐng)參見上面的截圖,這里不再贅述。下面開始配置beans.xml文件了。
4.2 配置數(shù)據(jù)源dataSource
首先配置一下dataSource,然后hibernate.cfg.xml中相應(yīng)的部分可以干掉了。因?yàn)樵赟pring中配置好了,Spring會(huì)去初始化這個(gè)dataSource,也就是說這就交給Spring來完成了,hibernate.cfg.xml中的相應(yīng)部分可以刪掉了。如下:
<!-- 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是用來產(chǎn)生一個(gè)session的,另外HibernateTemplate也可以,但是這里采用sessionFactory而不用HibernateTemplate,是因?yàn)镠ibernateTemplate是Spring提供的,依賴于Spring,如果哪天不用Spring了,就會(huì)報(bào)錯(cuò)。而sessionFactory是Hibernate提供的,沒有問題。HibernateTemplate的依賴性太強(qiáng)了。下面看一下具體配置:
<!-- 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屬性引用進(jìn)來即可,configLocation我們不在這配了,直接加載hibernate.cfg.xml文件,使用hibernate配置文件中的配置,更加簡(jiǎn)潔方便。
4.4 配置事務(wù)管理器
配置事務(wù)管理器,是用來管理sessionFactory的,這樣所有的由sessionFactory產(chǎn)生的session將會(huì)有聲明式的管理。配置如下:
<!-- 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屬性引用進(jìn)來即可。到這里就會(huì)發(fā)現(xiàn),從上面一直配下來,都是一連串的操作,一個(gè)個(gè)引用下來。
4.5 配置advice(通知)
配置advice的目的是指定哪些方法需要什么類型的事務(wù)模式??磁渲茫?br />
<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表示如果存在事務(wù),則支持當(dāng)前的事務(wù),如果沒有則創(chuàng)建一個(gè)新的事務(wù),這個(gè)事務(wù)模式應(yīng)用在所有以save、update和delete開頭的方法上,也就是說對(duì)數(shù)據(jù)庫的增刪改的時(shí)候需要添加事務(wù)支持。SUPPORTS表示如果存在事務(wù),則支持當(dāng)前的事務(wù),如果沒有就算了。
4.6 配置AOP切面
<aop:config> <!-- 配置哪些包的類要切入事務(wù) --> <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上面,否則會(huì)報(bào)錯(cuò) --> </aop:config>
AOP即面向切面編程,aop:pointcut定義一個(gè)切面,expression屬性中配置的意思是所有cn.it.shop.service.impl包下的所有方法,不管返回值和參數(shù)是什么,都要切入事務(wù)。該包是屬于dao層的,直接操作數(shù)據(jù)庫的。aop:advice將通知和切面結(jié)合起來,我們直接使用上面配置好的advice和pointcut,將其引入進(jìn)來即可。這樣配置好了后,意思就是說,凡是cn.it.shop.service.impl包下的方法都需要切入事務(wù)管理,具體地,以save、update、delete開頭的方法使用REQUIED方式,其他方法使用SUPPORTS方式。這樣就很好理解這個(gè)配置的意思了。
4.7 測(cè)試整合結(jié)果
之前搭建Hibernate環(huán)境的時(shí)候,我們測(cè)試是直接new了一個(gè)Service來操作數(shù)據(jù)庫,因?yàn)楫?dāng)時(shí)還沒有和Spring整合?,F(xiàn)在通過配置beans.xml后,讓Spring去管理Hibernate的事務(wù)了,所以現(xiàn)在的測(cè)試要把Service交給Spring管理,通過Spring注入進(jìn)來,并且依賴sessionFactory,如果能插入數(shù)據(jù)到數(shù)據(jù)庫,則說明聲明事務(wù)OK。
首先,我們要在Spring的配置文件beans.xml中配一下這個(gè)Service:
<property name="sessionFactory" ref="sessionFactory" /><!-- 依賴的sessionFactory用我們之前配好的sessionFactory-->
</bean>
其次,我們需要在CategoryService接口和它的實(shí)現(xiàn)類CategoryServiceImpl中增加一個(gè)方法用來測(cè)試整合后的情況:
public interface CategoryService {
public void save(Category category); //用來測(cè)試Hibernate環(huán)境
public void update(Category category); //用來測(cè)試Spring和Hibernate整合后
}
public class CategoryServiceImpl implements CategoryService {
@Override //沒有和Spring整合的情況
public void save(Category category) {
//通過工具類獲取session
Session session = HibernateSessionFactory.getSession();
try {
//手動(dòng)事務(wù)
session.getTransaction().begin();
//執(zhí)行業(yè)務(wù)邏輯
session.save(category);
//手動(dòng)提交
session.getTransaction().commit();
} catch(Exception e) {
session.getTransaction().rollback();
throw new RuntimeException(e);
} finally {
HibernateSessionFactory.closeSession();
}
}
/*Spring和Hibernate整個(gè)后*/
private SessionFactory sessionFactory; //定義一個(gè)sessionFactory
//當(dāng)需要使用sessoinFactory的時(shí)候,Spring會(huì)將sessionFactory注入進(jìn)來
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
protected Session getSession() {
//從當(dāng)前線程獲取session,如果沒有則創(chuàng)建一個(gè)新的session
return sessionFactory.getCurrentSession();
}
@Override //Spring和Hibernate整合后的情況
public void update(Category category) {
getSession().update(category);
}
}
現(xiàn)在我們可以去測(cè)試類中增添測(cè)試方法,來測(cè)試Spring和Hibernate整合后的結(jié)果了:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:beans.xml")
public class SSHTest {
@Resource
private Date date;
@Resource
private CategoryService categoryService;
@Test //測(cè)試Spring IOC的開發(fā)環(huán)境
public void springIoc() {
System.out.println(date);
}
@Test //測(cè)試Hibernate的開發(fā)環(huán)境,因?yàn)闆]有整合,可以直接new
public void hihernate() {
CategoryService categoryService = new CategoryServiceImpl();
Category category = new Category("男士休閑", true);
categoryService.save(category);
}
@Test //測(cè)試Hibernate和Spring整合后
public void hibernateAndSpring() {
categoryService.update(new Category(1, "休閑女式", true)); //categoryService通過Spring從上面注入進(jìn)來的
}
}
然后我們查看數(shù)據(jù)庫,發(fā)現(xiàn)id=1的category被修改成了休閑女式了,說明更新成功。至此,Spring和Hibernate整合成功。
5. 搭建Struts2環(huán)境
5.1 添加相應(yīng)的配置和jar包
struts2運(yùn)行所需的jar包我放在struts2.3.41的Library中了,直接引入即可,不再贅述。另外,還要對(duì)web.xml文件進(jìn)行配置,配置如下:
<?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>
如上,我們配置了一個(gè)StrutsPrepareAndExecuteFilter過濾器,并將過濾器的url-pattern設(shè)置為*.action,即所有.action后綴的都會(huì)首先經(jīng)過這個(gè)過濾器,這也是struts2的入口處。
5.2 創(chuàng)建Action并且配置到struts.xml文件中
我們創(chuàng)建一個(gè)Action如下:
public class CategoryAction extends ActionSupport {
private CategoryService categoryService; //設(shè)置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 測(cè)試Struts2環(huán)境
測(cè)試方法是:寫一個(gè)jsp訪問Action,如果Action可以創(chuàng)建,則表示struts2環(huán)境OK。即struts2的一連串流程可以正常走完:jsp-->struts.xml-->Action-->struts.xml-->jsp,這樣struts2的環(huán)境就算搭好了。我們寫一個(gè)簡(jiǎn)單的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服務(wù)器,在瀏覽器中輸入:http://localhost:8080/E_shop/index.jsp后,能出現(xiàn)正常jsp頁面,然后點(diǎn)擊兩個(gè)按鈕,仍然跳轉(zhuǎn)到index.jsp,然后我們看一下控制臺(tái)的輸出信息:
----update----
null
----save----
null
說明struts2的一條線走完了,環(huán)境沒有問題,至此,struts2開發(fā)環(huán)境搭建完畢。
我們看控制臺(tái)輸出了null,也就是說categoryService是空,也就是說根本沒拿到categoryService,因?yàn)槲覀儧]有和Spring進(jìn)行整合,沒有被注入進(jìn)來,所以null是正常的。我們沿著控制臺(tái)輸出的信息往上翻,會(huì)發(fā)現(xiàn)一條信息:Choosing bean (struts) for (com.opensymphony.xwork2.ObjectFactory)。括號(hào)里是struts說明沒有和Spring整合前,Action是有Struts2產(chǎn)生的。
6. Spring和Struts2整合
6.1 添加相應(yīng)的jar包
Spring與Struts2整合時(shí)的jar包主要在spring4.2.4-web里面,里面包括struts2-spring-plugin-2.3.24.1.jar,導(dǎo)包不再贅述。
6.2 把Action和它的依賴交給Spring管理
在Spring的配置文件beans.xml中配置Action和它的依賴,我們目前只有一個(gè)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整合時(shí)配置好的categoryService --> </bean>
6.3 修改struts.xml中的配置
原來在struts.xml中,class屬性對(duì)應(yīng)的是具體Action的完全限定名,現(xiàn)在將class屬性的值改為Spring中配置action的id值,即categoryAction,如下:
<struts>
<package name="shop" extends="struts-default">
<!-- class對(duì)應(yīng)的是Spring中配置該Action的id值,因?yàn)橐唤oSpring管理 -->
<action name="category_*" class="categoryAction" method="{1}">
<result name="index">/index.jsp</result>
</action>
</package>
</struts>
6.4 配置監(jiān)聽器
在web.xml中配置監(jiān)聽器ContextLoaderListener,這樣在服務(wù)器啟動(dòng)的時(shí)候就可以加載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中監(jiān)聽器的啟動(dòng)優(yōu)先級(jí)要高于過濾器,所以配在下面無所謂的 --> <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 測(cè)試整合結(jié)果
我們?cè)贏ction中新加一句更新數(shù)據(jù)庫的語句,如下:
public class CategoryAction extends ActionSupport {
private Category category;//設(shè)置一個(gè)私有成員變量接收url帶過來的參數(shù),注意下面要寫好get和set方法
private CategoryService categoryService;
public void setCategoryService(CategoryService categoryService) {
this.categoryService = categoryService;
}
public String update() {
System.out.println("----update----");
System.out.println(categoryService);//由于已經(jīng)和Spring整合,所以可以拿到這個(gè)categoryService了,打印出來就不是null了
categoryService.update(category); //新加一條語句,來更新數(shù)據(jù)庫
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服務(wù)器,在瀏覽器中輸入:http://localhost:8080/E_shop/index.jsp后,能出現(xiàn)正常jsp頁面,然后點(diǎn)擊“訪問update”按鈕,仍然跳轉(zhuǎn)到index.jsp,然后我們看一下控制臺(tái)的輸出信息:
----update---- cn.it.shop.service.impl.CategoryServiceImpl@7c5ecf80 Hibernate: update category set hot=?, type=? where id=?
我們看到可以輸出categoryService這個(gè)對(duì)象的信息了,也可以輸出執(zhí)行update語句時(shí)的SQL語句,然后我們查詢一下數(shù)據(jù)庫,發(fā)現(xiàn)id=2的數(shù)據(jù)的type被更新為gga,hot更新為false。我們沿著控制臺(tái)輸出的信息往上翻,會(huì)發(fā)現(xiàn)一條信息:Choosing bean (spring) for (com.opensymphony.xwork2.ObjectFactory),括號(hào)里為spring,與上面的情況對(duì)比可知,Struts2在與Spring整合后,Action交給了Spring去管理了。
至此,Struts2、Hibernate4和Spring4整合工作已經(jīng)全部完成,接下來就可以在SSH環(huán)境下進(jìn)行開發(fā)了!
本文介紹的SSH整合中所需要的完整jar包:免費(fèi)下載
整個(gè)項(xiàng)目的源碼下載地址:http://www.dbjr.com.cn/article/86099.htm
原文地址:http://blog.csdn.net/eson_15/article/details/51277324
(注:到最后提供整個(gè)項(xiàng)目的源碼下載!歡迎大家收藏或關(guān)注)
以上就是本文的全部?jī)?nèi)容,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- SSH整合中 hibernate托管給Spring得到SessionFactory
- 詳解JAVAEE——SSH三大框架整合(spring+struts2+hibernate)
- Spring4整合Hibernate5詳細(xì)步驟
- spring+hibernate 兩種整合方式配置文件的方法
- Java框架篇:Spring+SpringMVC+hibernate整合開發(fā)
- Spring 整合 Hibernate 時(shí)啟用二級(jí)緩存實(shí)例詳解
- Spring+Hibernate+Struts(SSH)框架整合實(shí)戰(zhàn)
- Spring與Hibernate整合事務(wù)管理的理解
- Spring MVC+FastJson+hibernate-validator整合的完整實(shí)例教程
- struts+spring+hibernate三個(gè)框架的整合
- Spring和Hibernate的整合操作示例
相關(guān)文章
利用MultipartFile實(shí)現(xiàn)文件上傳功能
這篇文章主要為大家詳細(xì)介紹了利用MultipartFile實(shí)現(xiàn)文件上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
mybatis plus開發(fā)過程中遇到的問題記錄及解決
這篇文章主要介紹了mybatis plus開發(fā)過程中遇到的問題記錄及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
java中PriorityBlockingQueue的入隊(duì)知識(shí)點(diǎn)總結(jié)
在本篇文章里小編給大家整理一篇關(guān)于java中PriorityBlockingQueue的入隊(duì)知識(shí)點(diǎn)總結(jié)內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。2021-01-01
java并發(fā)包中CountDownLatch和線程池的使用詳解
這篇文章主要介紹了java并發(fā)包中CountDownLatch和線程池的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-02-02
Java實(shí)現(xiàn)對(duì)象復(fù)制的方法實(shí)例
這篇文章主要介紹了Java實(shí)現(xiàn)對(duì)象復(fù)制的方法實(shí)例,深復(fù)制:復(fù)制出來的對(duì)象中的變量(包括基本類型和字符串)和原來的對(duì)象的值都相同,引用對(duì)象也會(huì)指向復(fù)制出來的對(duì)象,需要的朋友可以參考下2023-08-08

