本文開始做一個網(wǎ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. 整個項目jar包的管理
Spring的jar包很多,開發(fā)的時候建議將它們分個類,,然后依次添加到User Library,,方便管理,也一目了然,。這里我總結(jié)一下整個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中,。每個部分都有哪些jar包呢,?請看下面的截圖:
注:以上每個分類的包中,并非包含原來包中所有的jar,有些jar文件并沒有用到,,等具體項目需要的時候再往里加就行了,,上圖是保證項目的環(huán)境可以搭建所需要的的最基本的jar包。
2.搭建Spring環(huán)境
上面的jar包截圖是最后整合好的所有jar包,,剛開始搭建環(huán)境的時候不需要一次性全部加進來,,可以一點一點的加,這樣也更利于理解每個部分的jar包都有什么作用,,當(dāng)然,,一次都加進來也是可以的。
2.1 添加配置文件beans.xml和相應(yīng)的jar包
新建一個工程,,然后添加在User Library中添加自己的庫,,這里主要添加兩個,即spring-4.2.4-core和spring4.2.4-aop,,添加jar包不再贅述,。添加完了后,在src目錄下添加beans.xml文件,,這個文件的模板網(wǎng)上很多,,Spring自帶的例子里也有,考一份過來就行,,見下圖:
2.2 測試Spring的IoC環(huán)境
我們寫一個普通的java類java.util.Date類來測試一下Spring IoC是否正常,,如果在測試程序中能正常注入,則說明Spring的IoC環(huán)境搭建成功,,下面我們寫一個測試用例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /**
* @Description TODO(采用Spring的注解調(diào)試,僅僅支持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的開發(fā)環(huán)境
public void springIoc() {
System.out.println(date);
}
}
|
最后能正常輸出:Thu Apr 28 22:45:13 CST 2016。說明Date對象已經(jīng)被Spring給注入進來了,,從而驗證了Spring IoC功能正常,,為此,Spring的環(huán)境搭建完成,。
3. 搭建Hibernate環(huán)境
Hibernate的環(huán)境搭建相比于Spring要復(fù)雜一些,,因為用到了MyEclipse中的逆向工程。我們按以下步驟來搭建Hibernate開發(fā)環(huán)境:
3.1 添加相應(yīng)的jar包
這里主要是向User Library中添加兩項jar包:hibernate4.3.11和MySQL驅(qū)動包mysql-connector-java-5.1.26,,不再贅述,。
3.2 新建數(shù)據(jù)庫和表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 ,
/* 設(shè)置類別編號為主鍵*/
primary key (id)
);
|
3.3 DB瀏覽器連接到Mysql數(shù)據(jù)庫
DB瀏覽器指的是MyEclipse中的一個視圖窗口,,可以很直觀的看到MySQL中都有哪些數(shù)據(jù)庫和表,,打開DB瀏覽器的方法:Window->Open Perspective->DB Browser打開DB瀏覽器工作窗口。如果沒有DB Browser,,按照下面:Window->Show View->other->輸入DB Browser,,找到打開即可。
打開后,,我們開始連接到MySQL數(shù)據(jù)庫了,,在DB Browser窗口的空白處右鍵->new,就會彈出下面的對話框:
填好后,,點擊Test Driver測試一下,,測試通過表示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,就點擊project facets->Install Hibernate Facets,,會彈出如下窗口:
下一步,,在MyEclipse中添加Hibernate Support,即hibernate.cfg.xml映射文件和sessionFactory,。這里主要是給sessionFactory建個包,,默認包不行。
下一步,,添加驅(qū)動,,由于我們之前已經(jīng)配置好了一個驅(qū)動了,所以在這里直接選擇剛剛配置好的即可,。
下一步,,由于之前我們已經(jīng)添加過自己的jar保留,這里不用選擇,,直接finish,。
這樣我們就完成了Hibernate配置文件和sessionFactory的創(chuàng)建。下面我們簡單看一下MyEclipse創(chuàng)建的sessionFactory里面都有啥:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | 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 { //類加載時初始化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出對象,,保證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)建一個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;
}
}
|
從創(chuàng)建的HibernateSessionFactory中可以看出,,主要用到了單例模式和線程池技術(shù)。也不難理解,。
3.5 通過逆向工程生成model,、orm映射文件
下面開始使用逆向工程創(chuàng)建實例對象了,也就是數(shù)據(jù)庫的表對應(yīng)的model,。在DB Browsera窗口右擊我們剛剛創(chuàng)建的表shop,,選擇Hibernate Reverse Engineering開始創(chuàng)建:
創(chuàng)建的時候有兩種方式,基于配置文件的和基于注解的,,具體的看開發(fā)人員心情了,,可以選擇:
然后下一步,選擇一下native主鍵自增方式,,然后便完成了逆向工程創(chuàng)建model和orm映射了,。
完成后,會有Category的model生成,,同時在hibernate.cfg.xml文件中也會生成相應(yīng)的映射,,前面基于配置文件的和基于注解的在hibernate.cfg.xml中生成的映射時不同的。
3.6 測試Hibernate持久化數(shù)據(jù)庫
因為這里還沒有與Spring整合,,只是單純的搭建Hibernate開發(fā)環(huán)境,,所以我們沒有必要使用注解,我們通過直接new一個service的方式執(zhí)行數(shù)據(jù)入庫,。
先寫CategoryService接口和實現(xiàn)類:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public interface CategoryService {
public void save(Category category); //用來測試Hibernate環(huán)境
}
public class CategoryServiceImpl implements CategoryService {
@Override //沒有和Spring整合的情況
public void save(Category category) {
//通過剛剛生成的sessionFactory獲取session
Session session = HibernateSessionFactory.getSession();
try {
//手動事務(wù)
session.getTransaction().begin();
//執(zhí)行業(yè)務(wù)邏輯
session.save(category);
//手動提交
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
throw new RuntimeException(e);
} finally {
HibernateSessionFactory.closeSession();
}
}
}
|
下面在剛剛的測試用例中添加對Hibernate的測試:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @RunWith (SpringJUnit4ClassRunner. class )
@ContextConfiguration (locations= "classpath:beans.xml" )
public class SSHTest {
@Resource
private Date date;
@Test //測試Spring IOC的開發(fā)環(huán)境
public void springIoc() {
System.out.println(date);
}
@Test //測試Hibernate的開發(fā)環(huán)境,,因為沒有整合,可以直接new
public void hihernate() {
CategoryService categoryService = new CategoryServiceImpl();
Category category = new Category( "男士休閑" , true );
categoryService.save(category);
}
}
|
我們查看數(shù)據(jù)庫,,發(fā)現(xiàn)多了剛剛插入的這項,,說明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時需要導(dǎo)入的jar包有兩大塊,,spring4.2.4-persistence和c3p0-0.9.5.1,每一塊jar包中的具體jar文件請參見上面的截圖,,這里不再贅述,。下面開始配置beans.xml文件了。
4.2 配置數(shù)據(jù)源dataSource
首先配置一下dataSource,然后hibernate.cfg.xml中相應(yīng)的部分可以干掉了,。因為在Spring中配置好了,,Spring會去初始化這個dataSource,也就是說這就交給Spring來完成了,,hibernate.cfg.xml中的相應(yīng)部分可以刪掉了,。如下:
1 2 3 4 5 6 7 | <!-- 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: /> < property name = "user" value = "root" />
< property name = "password" value = "root" />
</ bean >
|
hibernate.cfg.xml中需要干掉的部分:
4.3 配置sessionFactory
配置sessionFactory是用來產(chǎn)生一個session的,另外HibernateTemplate也可以,,但是這里采用sessionFactory而不用HibernateTemplate,,是因為HibernateTemplate是Spring提供的,依賴于Spring,,如果哪天不用Spring了,,就會報錯。而sessionFactory是Hibernate提供的,,沒有問題,。HibernateTemplate的依賴性太強了。下面看一下具體配置:
1 2 3 4 5 | <!-- 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 配置事務(wù)管理器
配置事務(wù)管理器,,是用來管理sessionFactory的,,這樣所有的由sessionFactory產(chǎn)生的session將會有聲明式的管理。配置如下:
1 2 3 4 | <!-- 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屬性引用進來即可。到這里就會發(fā)現(xiàn),,從上面一直配下來,,都是一連串的操作,一個個引用下來,。
4.5 配置advice(通知)
配置advice的目的是指定哪些方法需要什么類型的事務(wù)模式,。看配置:
1 2 3 4 5 6 7 8 | < 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)建一個新的事務(wù),這個事務(wù)模式應(yīng)用在所有以save,、update和delete開頭的方法上,,也就是說對數(shù)據(jù)庫的增刪改的時候需要添加事務(wù)支持,。SUPPORTS表示如果存在事務(wù),則支持當(dāng)前的事務(wù),,如果沒有就算了,。
4.6 配置AOP切面
1 2 3 4 5 6 | < 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上面,否則會報錯 -->
</ aop:config >
|
AOP即面向切面編程,,aop:pointcut定義一個切面,,expression屬性中配置的意思是所有cn.it.shop.service.impl包下的所有方法,不管返回值和參數(shù)是什么,,都要切入事務(wù),。該包是屬于dao層的,直接操作數(shù)據(jù)庫的,。aop:advice將通知和切面結(jié)合起來,,我們直接使用上面配置好的advice和pointcut,將其引入進來即可,。這樣配置好了后,,意思就是說,凡是cn.it.shop.service.impl包下的方法都需要切入事務(wù)管理,,具體地,,以save、update,、delete開頭的方法使用REQUIED方式,,其他方法使用SUPPORTS方式。這樣就很好理解這個配置的意思了,。
4.7 測試整合結(jié)果
之前搭建Hibernate環(huán)境的時候,,我們測試是直接new了一個Service來操作數(shù)據(jù)庫,因為當(dāng)時還沒有和Spring整合?,F(xiàn)在通過配置beans.xml后,,讓Spring去管理Hibernate的事務(wù)了,所以現(xiàn)在的測試要把Service交給Spring管理,,通過Spring注入進來,,并且依賴sessionFactory,如果能插入數(shù)據(jù)到數(shù)據(jù)庫,,則說明聲明事務(wù)OK,。
首先,我們要在Spring的配置文件beans.xml中配一下這個Service:
<bean id="categoryService" class="cn.it.shop.service.impl.CategoryServiceImpl">
<property name="sessionFactory" ref="sessionFactory" /><!-- 依賴的sessionFactory用我們之前配好的sessionFactory-->
</bean>
其次,,我們需要在CategoryService接口和它的實現(xiàn)類CategoryServiceImpl中增加一個方法用來測試整合后的情況:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | public interface CategoryService {
public void save(Category category); //用來測試Hibernate環(huán)境
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 {
//手動事務(wù)
session.getTransaction().begin();
//執(zhí)行業(yè)務(wù)邏輯
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
//當(dāng)需要使用sessoinFactory的時候,Spring會將sessionFactory注入進來
public void setSessionFactory(SessionFactory sessionFactory) {
this .sessionFactory = sessionFactory;
}
protected Session getSession() {
//從當(dāng)前線程獲取session,,如果沒有則創(chuàng)建一個新的session
return sessionFactory.getCurrentSession();
}
@Override //Spring和Hibernate整合后的情況
public void update(Category category) {
getSession().update(category);
}
}
|
現(xiàn)在我們可以去測試類中增添測試方法,,來測試Spring和Hibernate整合后的結(jié)果了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | @RunWith (SpringJUnit4ClassRunner. class )
@ContextConfiguration (locations= "classpath:beans.xml" )
public class SSHTest {
@Resource
private Date date;
@Resource
private CategoryService categoryService;
@Test //測試Spring IOC的開發(fā)環(huán)境
public void springIoc() {
System.out.println(date);
}
@Test //測試Hibernate的開發(fā)環(huán)境,,因為沒有整合,可以直接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從上面注入進來的
}
}
|
然后我們查看數(shù)據(jù)庫,,發(fā)現(xiàn)id=1的category被修改成了休閑女式了,,說明更新成功。至此,,Spring和Hibernate整合成功,。
5. 搭建Struts2環(huán)境
5.1 添加相應(yīng)的配置和jar包
struts2運行所需的jar包我放在struts2.3.41的Library中了,直接引入即可,,不再贅述,。另外,還要對web.xml文件進行配置,,配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <? xml version = "1.0" encoding = "UTF-8" ?>
< 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設(shè)置為*.action,,即所有.action后綴的都會首先經(jīng)過這個過濾器,,這也是struts2的入口處。
5.2 創(chuàng)建Action并且配置到struts.xml文件中
我們創(chuàng)建一個Action如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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目錄下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <? xml version = "1.0" encoding = "UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
< 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環(huán)境
測試方法是:寫一個jsp訪問Action,,如果Action可以創(chuàng)建,則表示struts2環(huán)境OK,。即struts2的一連串流程可以正常走完:jsp-->struts.xml-->Action-->struts.xml-->jsp,,這樣struts2的環(huán)境就算搭好了。我們寫一個簡單的index.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <%@ 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頁面,,然后點擊兩個按鈕,,仍然跳轉(zhuǎn)到index.jsp,然后我們看一下控制臺的輸出信息:
----update----
null
----save----
null
說明struts2的一條線走完了,,環(huán)境沒有問題,,至此,struts2開發(fā)環(huán)境搭建完畢,。
我們看控制臺輸出了null,,也就是說categoryService是空,也就是說根本沒拿到categoryService,,因為我們沒有和Spring進行整合,,沒有被注入進來,所以null是正常的,。我們沿著控制臺輸出的信息往上翻,,會發(fā)現(xiàn)一條信息:Choosing bean (struts) for (com.opensymphony.xwork2.ObjectFactory),。括號里是struts說明沒有和Spring整合前,Action是有Struts2產(chǎn)生的,。
6. Spring和Struts2整合
6.1 添加相應(yīng)的jar包
Spring與Struts2整合時的jar包主要在spring4.2.4-web里面,,里面包括struts2-spring-plugin-2.3.24.1.jar,導(dǎo)包不再贅述,。
6.2 把Action和它的依賴交給Spring管理
在Spring的配置文件beans.xml中配置Action和它的依賴,,我們目前只有一個Action,配置如下所示:
1 2 3 4 | < 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屬性對應(yīng)的是具體Action的完全限定名,,現(xiàn)在將class屬性的值改為Spring中配置action的id值,即categoryAction,,如下:
1 2 3 4 5 6 7 8 9 10 | < struts >
< package name = "shop" extends = "struts-default" >
<!-- class對應(yīng)的是Spring中配置該Action的id值,,因為要交給Spring管理 -->
< 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ù)器啟動的時候就可以加載Spring的配置文件了,。如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <? xml version = "1.0" encoding = "UTF-8" ?>
< 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)聽器的啟動優(yōu)先級要高于過濾器,,所以配在下面無所謂的 -->
< 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 測試整合結(jié)果
我們在Action中新加一句更新數(shù)據(jù)庫的語句,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public class CategoryAction extends ActionSupport {
private Category category; //設(shè)置一個私有成員變量接收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整合,,所以可以拿到這個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文件,,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <%@ 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頁面,然后點擊“訪問update”按鈕,,仍然跳轉(zhuǎn)到index.jsp,,然后我們看一下控制臺的輸出信息:
1 2 3 | ----update----
cn.it.shop.service.impl.CategoryServiceImpl @7c5ecf80
Hibernate: update category set hot=?, type=? where id=?
|
我們看到可以輸出categoryService這個對象的信息了,也可以輸出執(zhí)行update語句時的SQL語句,,然后我們查詢一下數(shù)據(jù)庫,,發(fā)現(xiàn)id=2的數(shù)據(jù)的type被更新為gga,hot更新為false,。我們沿著控制臺輸出的信息往上翻,,會發(fā)現(xiàn)一條信息:Choosing bean (spring) for (com.opensymphony.xwork2.ObjectFactory),括號里為spring,,與上面的情況對比可知,,Struts2在與Spring整合后,Action交給了Spring去管理了。
至此,,Struts2,、Hibernate4和Spring4整合工作已經(jīng)全部完成,接下來就可以在SSH環(huán)境下進行開發(fā)了,!
本文介紹的SSH整合中所需要的完整jar包:免費下載
整個項目的源碼下載地址:http://www.jb51.net/article/86099.htm
原文地址:http://blog.csdn.net/eson_15/article/details/51277324
(注:到最后提供整個項目的源碼下載!歡迎大家收藏或關(guān)注)
以上就是本文的全部內(nèi)容,,希望能給大家一個參考,,也希望大家多多支持腳本之家。
如對本文有疑問,,請?zhí)峤坏浇涣魃鐓^(qū),,廣大熱心網(wǎng)友會為你解答!,! 點擊進入社區(qū)
|