日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

整合Struts2、Spring、Hibernate构建J2EE应用

發(fā)布時間:2023/12/15 javascript 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 整合Struts2、Spring、Hibernate构建J2EE应用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

【論文摘要】

J2EE即是以Java 2平臺為基礎(chǔ)的體系結(jié)構(gòu),又是一組旨在簡化企業(yè)解決方案的開發(fā)、部署、運行、維護等相關(guān)復(fù)雜問題的技術(shù)規(guī)范與指南。Struts2、Spring、Hibernate是當(dāng)今符合J2EE技術(shù)規(guī)范的三個流行的開源框架。本文通過對這三個框架的工作機制的分析引伸出它們在J2EE應(yīng)用中的互補作用,進而講解它們在J2EE開發(fā)中的整合。最后通過一個簡單的實例演示Struts2+Spring+Hibernate的開發(fā)流程。

關(guān)鍵字: Struts2? Spring? Hibernate? J2EE??

【Abstract】

J2EE is the structure base on Java 2 platform, it also a set of technical specification and guidelines to simplify the complex issues of the enterprise solutions of development, deployment, operation and maintenance of enterprise solutions. Struts2, Spring and Hibernate are three prevailing open-source framework in line with J2EE technical specification. This paper analyzes the working mechanism of these three frameworks, amplifies the complementary effect in their application of J2EE, and then introduces their integration in the development of J2EE. Finally, it demonstrates the developing process of Struts2+Spring+Hibernate through a simple case.

一 Struts2簡介

(一) Struts2是什么,及在Java web開發(fā)中的作用

Struts2是一個基于J2EE平臺的開源的MVC框架。它著力于Control和View,提供完善的控制方案并定制了功能強大的標(biāo)簽庫。從某種意義上講Struts2并不涉及Model,但它提供了訪問Model的入口(execute()方法相當(dāng)于訪問Model的一個入口,業(yè)務(wù)邏輯層及其以下層次Struts2不涉及)。使用Struts2開發(fā)的系統(tǒng)具有以下多種優(yōu)點:結(jié)構(gòu)層次分明(MVC),可重用性高(框架正是把系統(tǒng)的共性部分抽取出來,提供給不同應(yīng)用使用),程序健壯性(強大的驗證機制與類型轉(zhuǎn)換功能)、可伸縮性(動態(tài)加載插件、設(shè)計良好的抽象類、接口等)有保證,便于開發(fā)與設(shè)計分工(MVC)等。

(二) Struts2與Struts的關(guān)系及區(qū)別

Struts2不是Struts的簡單的版本升級,而是本質(zhì)上的飛越。事實上Struts2主要是從WebWork基礎(chǔ)上發(fā)展起來,再吸收Struts的一些優(yōu)點匯集而成的。(至于為什么叫Struts2而不叫WebWork2.x,很大程度是因為Struts在業(yè)內(nèi)的知名度要比WebWork要高的原故。)

由于Struts2主要是繼承于WebWrok的,所以它與Struts1的區(qū)別其實是很大的,以下列舉其中幾個重要方面:

Action類:Struts1要求Action類必須繼承一個抽象基類(如Action、BasicAction)。Struts2也提供一個抽象基類ActionSupport實現(xiàn)常用的一些接口,Struts2的Action類盡管常常實現(xiàn)這個類,但這不是必須的,它不只可以繼承一個Action類,還可以不繼承Action類而實現(xiàn)其他接口,以便于定制一些特定的服務(wù),增強了Action類的靈活性。

線程模式: Struts1的Action是單例模式,盡管這一定程度節(jié)約了資源的損耗,但同時要求開發(fā)者必須小心翼翼地把它設(shè)計成線程安全(需要是無狀態(tài)的,即不能有可寫屬性)的,從而限制了Action所能做的工作。Struts2的Action即可以是單例模式,也可以是原型模式的,即可為每一個請求產(chǎn)生一個實例,因此沒有線程安全問題。這也進一步體現(xiàn)了Struts2比Struts1要優(yōu)雅得多。

對Servlet依賴: Struts1的Action依賴于Servlet API,當(dāng)一個Action被調(diào)用時HttpServletRequest和HttpServletResponse需被傳遞給execute(或其它定制的)方法。Struts2的Action不依賴于容器,允許Action脫離容器單獨執(zhí)行(從而提高了可測性)。在需要時Struts2的Action也可以訪問HttpServetRequest和HttpServletResponse。

輸入捕獲: Struts1的Action是單例模式(不應(yīng)該出現(xiàn)可寫屬性),數(shù)據(jù)是先經(jīng)過ActionForm封裝再交給Action的。我認為這是Struts1設(shè)計的最大缺陷之一,ActionForm與DAO層的Doamin對象形式差不多,執(zhí)行的功能也相似,只是意圖不同,這種代碼的冗余會給開發(fā)、維護帶來一系列問題。而Struts2的Action則是原型模式,每個Action都可以有其特有的屬性,從而數(shù)據(jù)不需要經(jīng)由ActionForm封裝便可直接獲取。很明顯Struts2對輸入的捕獲及處理過程更加易于理解、更加簡潔。

(三) strust2的工作流程

strust2的工作流程可歸納為以下幾個步驟

1.客戶端Http請求提交。

2.strust2的總控制器FilterDispatcher通過sturts.xml分析哪個Action進行處理。

3.指定的Action執(zhí)行相關(guān)的類型轉(zhuǎn)換方法(可省)、setXxx()方法、validate()方法等。

4.執(zhí)行execute()方法(如果有指定其它方法則調(diào)用其它方法)。

5.sturts.xml根據(jù)execute()方法(或其它方法)返回的結(jié)果字符串確定接下來的工作(通常是調(diào)用一個jsp頁面,也可以是另一個Action或其它方式)。

6.Http響應(yīng)客戶端。

二 Spring簡介

(一) Spring是什么

Spring是一個輕量級的提供控制反轉(zhuǎn)(IoC)、面向切面(AOP)容器的開源框架。

2004年Spring創(chuàng)始人Rod Johnson發(fā)表的《Expert one-to-one J2EE Development without EJB》劍指EJB,對EJB的各種龐大又笨重的結(jié)構(gòu)進行了分析和否定,隨后推出的Spring便是以簡潔實用的方式替換了EJB所能完成的大部分功能(以我對EJB的一點淺薄認識,必須承認就目前而言,特別是EJB3.0的推出,在很多方面Spring還是無法企及的)。它使用基本的JavaBean來完成以前只能由EJB完成的事情。當(dāng)然Spring適合的范圍不僅限于服務(wù)器端的開發(fā)。從簡單性、可測試性和松耦合的角度而言,任何Java應(yīng)用都可以從Spring中受益。

傳統(tǒng)J2EE應(yīng)用由于分層多,而各層之間又沒有合理的銜接,至使開發(fā)效率低、系統(tǒng)也不易維護,應(yīng)用服務(wù)器廠商對各種技術(shù)的支 持 并沒有真正統(tǒng)一,導(dǎo)致J2EE的應(yīng)用沒有真正實現(xiàn)一次編譯及到處執(zhí)行的承諾。Spring的推出簡化了J2EE應(yīng)用開發(fā)的復(fù)雜性,它能獨立于各種應(yīng)用服務(wù)器容器,致力于J2EE應(yīng)用各層的解決方案,它貫穿于View、Business及DAO各層,是它們之間很好的黏合劑。Spring的作用正是能與已有的框架配合,把它們無縫地整合在一起,使整個J2EE應(yīng)用開發(fā)更加順暢。

(二) Spring相關(guān)技術(shù)介紹

1.輕量級:

Spring的輕量級并不是體現(xiàn)在Spring的完整代碼只有那么一點點(不到3MB),而是指Spring所需的系統(tǒng)開銷是很小的(簡直不能與EJB相提并論)。另外,Spring應(yīng)用中的對象并不依賴于Spring的特定類(對象無需顯示的聲明Spring的特定類),Spring是非侵入式的。

2.控制反轉(zhuǎn):

控制反轉(zhuǎn)(IoC)技術(shù)的運用降低了各層的耦合度。這是Spring框架最核心的一個方面。IoC概括起來說就是:一個對象所依賴的其它對象會通過容器(被動的)傳遞(在Spring常稱為“注入”)進來,而不是該對象自己創(chuàng)建或者查找依賴對象。可以說企業(yè)級應(yīng)用各層的無逢銜接正是通過IoC實現(xiàn)。更進一步說,Spring抽象了服務(wù),借助于各種J2EE API抽象,開發(fā)者能夠一致地使用J2EE 技術(shù),而不管具體的實現(xiàn)方式是怎樣的。下面代碼可以很好的說明這一點:

這是傳統(tǒng)的服務(wù)層的實現(xiàn)類:

public class UserServiceImpl implements UserService{

//由于依賴對象由當(dāng)前對象管理,所以這里new 需指明具體實現(xiàn)類。

private UserDao userDao=new UserDaoImpl();

private void add(User user)

{

? userDao.add(user);

}

}

使用Spring框架后的情況:

public class PersonServiceBean implements PersonService {

//依賴注入,即通過構(gòu)造器,讓容器把創(chuàng)建好的依賴對象注入進來

//此處不需要硬編碼說明具體實現(xiàn)類(只需在xml文件配置即可),這便是IoC的巨大優(yōu)點!

private UserDao userDao;

public PersonServiceBean(UserDao userDao) {

? this.UserDao=userDao;

}

private void add(User user)

{

? userDao.add(user);

}

}

抽象了服務(wù)!僅此一點,足矣讓絕大多數(shù)開發(fā)者興奮不已!

3.面向切面:

Spring提供了面向切面(AOP)編程的支 持 ,允許開發(fā)者以聲名方式使用企業(yè)級服務(wù),最典型的是聲明式事務(wù)管理。通過Spring提供的事務(wù)管理服務(wù),開發(fā)者便不再需要手工管理事務(wù),也無需處理復(fù)雜的事務(wù)傳播行為。

下面還是以例子說明AOP的作用:

這是DAO層的代碼:

public class UserDaoImpl implements UserDao

{

public void save(User user)

{

? Session s=HibernateUtil.getSession();

? Transaction tx=null;

? try {

?? tx=s.beginTransaction(); //開啟事務(wù)

?? s.save(user);

?? tx.commit();//提交事務(wù)

? }catch(Exception e){

?? if(tx!=null)

??? tx.rollback();//回滾事務(wù)

?? try {

??? throw e;

?? }catch (Exception e1) {

??? e1.printStackTrace();

?? }

? }finally{

?? if(s!=null)

??? s.close();//關(guān)閉session

? }

}

}

顯然這是不好的代碼。盡管事務(wù)管理屬于DAO層的代碼,但由于DAO各方法會以不同方式組合成同一個事務(wù),從而事務(wù)不應(yīng)該在DAO層管理,而應(yīng)該交給更高一層級,于是應(yīng)該去掉事務(wù)管理代碼,改為:

public class UserDaoImpl implements UserDao

{

public void save(User user)

{

? s=HibernateUtil.getSession();

? try {

?? s.save(user);

? }finally{

?? //同上,關(guān)閉session

? }

}

}

然后是服務(wù)層代碼:

public class UserManagerImpl implements UserManager {

private UserDao userDao;

public void saveUser(User user)

{

? Session s=HibernateUtil.getSession();

? Transaction tx=null;

? try {

?? tx=s.beginTransaction();

?? userDao.save(user);

?? //其它方法

?? sendMessage();

?? sendEmail();

?? tx.commit();

? }catch(Exception e){

?? //同上,回滾事務(wù)

? }finally{

?? //同上,關(guān)閉session

? }

}

}

這是在沒有Spring情況下習(xí)慣的做法,這似乎也是較為合理的做法,但事務(wù)的開啟與關(guān)閉是DAO層的代碼,怎么跑到服務(wù)層來了呢?顯然這樣做服務(wù)層一定程度耦合了DAO層,通過Spring可以得到很好的解決:

public class UserManagerImpl implements UserManager {

private UserDao userDao;

//聲明事務(wù)處理方式

@Transactional(propagation=Propagation.REQUIRED)

public void saveUser(User user)

{

? userDao.save(user);

? //其它方法

? sendMessage();

? sendEmail();

<, SPAN style="mso-spacerun: yes"> }

}

不但徹底解耦,還大大簡化了代碼,程序顯得優(yōu)雅許多了。

4.容器:

Spring容器包含并管理應(yīng)用對象的配置和生命周期,開發(fā)者可以通過XML配置每個bean如何被創(chuàng)建(默認是singleton,也可以是prototype),以及它們是如何相互關(guān)聯(lián)的。

如下applicationContext.xml配置:

class="org.apache.commons.dbcp.BasicDataSource">

class="org.Springframework.orm.Hibernate3.LocalSessionFactoryBean"?

destroy-method="close">

?

可以看得出Spring自底向上把各層銜接起來。特別是在多框架整合的情況(如上面配置,即是整合了Hibernate、Struts2的典型配置方式),Spring使各框架無逢地結(jié)合到了一起。

三 Hibernate簡介

(一) Hibernate是什么

Hibernate是一個開源的數(shù)據(jù)持久層框架,用于實現(xiàn)對象與關(guān)系之間的映射(即O/R Mapping)。它對JDBC進行了輕量級的對象封裝,使Java程序員可以使用面向?qū)ο缶幊趟枷雭聿僮鲾?shù)據(jù)庫。它不但提供了從Java類到數(shù)據(jù)表的映射,還提供了數(shù)據(jù)查詢和恢復(fù)機制。相對于使用JDBC和SQL來操作數(shù)據(jù)庫,通過使用Hibernate,大量封裝持久化操作的業(yè)務(wù)邏輯不再需要編寫煩瑣的JDBC語句,極大簡化了編程實現(xiàn)。Hibernate是跨數(shù)據(jù)庫的,因此基于Hibernate編寫的代碼不會因為數(shù)據(jù)庫的更換而重寫。

(二) 領(lǐng)域模型

Hibernate中領(lǐng)域模型(Domain)對象通過xml文件映射了數(shù)據(jù)庫的一張表(或多張表),xml文件通常位于Domain對象同一個包,命名為ClassName.hbm.xml(ClassName為映射的類名),Domain對象通常只有一些屬性(對應(yīng)表的字段)及相應(yīng)的setter、getter方法,當(dāng)然還得符合以下幾個條件才能成為Domain對象:

1。必須要有默認的構(gòu)造方法。

2。有無意義的標(biāo)識符id(主鍵)。

3。非final,這是使用懶加載所需的要求。(因為懶加載需要繼承該類,如果加了final,該類便不可繼承了。)

(三) 對象狀態(tài)

在Hibernate中,對象狀態(tài)也是比較重要的概念,分別有以下三種:

1.瞬時:數(shù)據(jù)庫沒有記錄與之對應(yīng)。

2.持久:數(shù)據(jù)庫有記錄與之對應(yīng),當(dāng)前與session有關(guān)聯(lián),并且相關(guān)聯(lián)的session沒有關(guān)閉,事務(wù)沒有提交。持久對象狀態(tài)發(fā)生改變,在事務(wù)提交時會影響到數(shù)據(jù)庫。

3.脫管:即脫離管理。數(shù)據(jù)庫有記錄與之對應(yīng),當(dāng)前沒有session與之關(guān)聯(lián),脫管對象狀態(tài)發(fā)生改變,不會影響到數(shù)據(jù)庫。

(四) HQL(Hibernate Query Language)

是Hibernate提供的用于跨數(shù)據(jù)庫查詢的面向?qū)ο蟛樵冋Z言,它是按對象名而不是按表名來查詢。同時支 持 多態(tài)查詢,即查詢父類,會同時查詢子類。比如from Object會查詢所有對象,即查詢所有表。

(五) 對象關(guān)系映射

Hibernate提供了一對一、多對一、一對多、多對多等對象關(guān)系映射。

但需要指出的是,由于實際系統(tǒng)運行時性能的需求,往往不做多對多關(guān)聯(lián)(它需要對多個表進行關(guān)聯(lián)查詢,效率很低),甚至一對多關(guān)聯(lián)也很少做。

(六) 懶加載

懶加載,即只有在要用到數(shù)據(jù)時才到數(shù)據(jù)庫里讀取。通過session.load()可以實現(xiàn)對象的懶加載,從而盡量減少數(shù)據(jù)庫訪問次數(shù)以緩解系統(tǒng)的壓力。需要注意的是,能夠懶加載的對象都是被改寫過的代 理 對象,當(dāng)相關(guān)聯(lián)的session沒有關(guān)閉時,訪問這些懶加載對象(代 理 對象)的屬性(getId、getClass除外)Hibernate會初始化這些代 理 ,或用Hibernate.initialize(proxy)來初始化代 理 對象;當(dāng)相關(guān)聯(lián)的session關(guān)閉后,再訪問懶加載對象將出現(xiàn)異常。

(七) 緩存

緩存又可分為一級緩存跟二級緩存。

一級緩存,是Session級共享。save、update、saveOrUpdate、load、get、list、iterate、lock這些方法都會將對象放入一級緩存中,由于一級緩存不能控制緩存的大小,不宜操作過大的數(shù)據(jù),否則容易造成內(nèi)存溢出,為此需用session.evict(Object)、session.clear()方法清除緩存中的內(nèi)容。

二級緩存,是SessionFactory級共享。Hibernate并沒有實現(xiàn)二級緩存,而是將之交給第三方緩存組件(如:EhCache、OSCache等)實現(xiàn)。

四 整合Struts2、Spring、Hibe, rnate構(gòu)建J2EE應(yīng)用

(一) 什么是J2EE

J2EE即Java2平臺企業(yè)版(Java 2 Platform Enterprise Edition),是一套以Java 2平臺為基礎(chǔ)的技術(shù)架構(gòu)。包含許多組件,目的在于簡化并規(guī)范應(yīng)用系統(tǒng)的開發(fā)與部署,進而提高可移植性、安全性與再用價值。J2EE核心是一組技術(shù)規(guī)范與指南,它給開發(fā)人員提供了一個應(yīng)用標(biāo)準(zhǔn),定義了一個標(biāo)準(zhǔn)的應(yīng)用體系結(jié)構(gòu),J2EE作為解決企業(yè)級應(yīng)用的標(biāo)準(zhǔn),將企業(yè)級應(yīng)用劃分成不同層次,便于應(yīng)用開發(fā),管理和部署。J2EE應(yīng)用服務(wù)器支 持 各種組件,如Servlet、JSP、EJB等,這些組件分別安裝和部署于各自的容器中,使用標(biāo)準(zhǔn)的J2EE service API連接,靈活地實現(xiàn)應(yīng)用。

(二) J2EE多層應(yīng)用分析與實現(xiàn)

經(jīng)典的J2EE三層結(jié)構(gòu)是指表示層(Presentation),業(yè)務(wù)邏輯層(Business logic)以及基礎(chǔ)架構(gòu)層(Infrastructure)。在實際項目開發(fā)中,往往會對三層體系結(jié)構(gòu)做一些擴展來滿足項目的需要。如今較流行的方式是將三層體系擴展為五層體系,即在表示層與業(yè)務(wù)邏輯層之間增加控制層(在某些情況下甚至還會在控制層與業(yè)務(wù)邏輯層再增加代 理 層),再把基礎(chǔ)架構(gòu)層細分為數(shù)據(jù)訪問層、數(shù)據(jù)層。Struts2 + Spring + Hibernate可以實現(xiàn)J2EE的這種多層結(jié)構(gòu)。其中Struts2用于表示層與控制層,而Spring工作的中心在業(yè)務(wù)層,同時又粘合控制層、業(yè)務(wù)層與數(shù)據(jù)訪問層,Hibernate則用于數(shù)據(jù)訪問與持久化工作。

(三) J2EE層次結(jié)構(gòu)

1. 數(shù)據(jù)層

數(shù)據(jù)層是指提供所需數(shù)據(jù)的數(shù)據(jù)庫系統(tǒng)。數(shù)據(jù)庫里記錄了系統(tǒng)所需要的所有數(shù)據(jù)。由于數(shù)據(jù)庫系統(tǒng)本身的多樣性,J2EE提供了JDBC接口用于數(shù)據(jù)庫之上的組件能訪問各種數(shù)據(jù)庫系統(tǒng)。Hibernate則進一步封裝了JDBC對數(shù)據(jù)庫的操作。

2. 數(shù)據(jù)訪問層

包括數(shù)據(jù)查詢與持久化工作。本層將完成具體的數(shù)據(jù)處理工作,包括增、查、改、刪(CRUD)。

本層運用DAO設(shè)計模式,通過使用Hibernate的ORM技術(shù)很好的解決了“阻抗不匹配”(即對象操作與關(guān)系數(shù)據(jù)庫操作方式不同)的問題。DAO進一步封裝了JDBC對數(shù)據(jù)庫表的CRUD操作,實現(xiàn)了用一致的面向?qū)ο蟮姆绞讲僮鞑煌瑪?shù)據(jù)庫,同時也降低了數(shù)據(jù)操作的難度。

3. 服務(wù)層

本層是整個系統(tǒng)架構(gòu)的核心,需完成所有業(yè)務(wù)規(guī)則的制定、業(yè)務(wù)流程的實現(xiàn)等與業(yè)務(wù)需求有關(guān)的系統(tǒng)設(shè)計。Spring的引入很大程度的簡化這一層的復(fù)雜性。例如事務(wù)處理,開發(fā)者不再為事務(wù)邊界控制而為難。本層把一些算法、數(shù)據(jù)處理(通過調(diào)用DAO層)等與業(yè)務(wù)相關(guān)的處理封裝于一體,交由控制層調(diào)用。把服務(wù)層與控制層分離,使層次更加分明,分工更加細致,從而更方便團隊調(diào)配工作。

4. 控制層

本層接受客戶端的請求,轉(zhuǎn)交給服務(wù)層處理,最后將處理結(jié)果返回給客戶。通過引入Struts2框架,控制層會以Struts2為主導(dǎo)。(相對Struts1而言)Struts2作為一個Filter而不再只是Servlet,在請求到來時(在必要的情況下會)對信息進行驗證、處理(如類型轉(zhuǎn)換),只有驗證通過的請求才會轉(zhuǎn)交給業(yè)務(wù)層處理,最后將處理結(jié)果返回給客戶。盡管在未引入Struts2的情況下Servlet可以做相同的事,但相比之下Struts2使這些工作規(guī)范化、模式化,開發(fā)者只需在模式化的處理(Action)類填補一些代碼,甚至可以通過XML文件的配置來實現(xiàn)這些操作,大大簡化了代碼,提高了開發(fā)效率。

5. 視圖層

視圖層是呈現(xiàn)給客戶的界面,通常是JSP、HTML等頁面。在使用Struts2框架的應(yīng)用中,會使用Struts2提供的功能豐富的標(biāo)簽庫增強頁面動態(tài)內(nèi)容的輸出能力。

(四) 為什么要整合Struts2、Spring、Hibernate

通過以上各層的分析,可以清楚的看到Struts2、Spring、Hibernate在整個J2EE應(yīng)用中的作用以及它們相互間的協(xié)作關(guān)系。Hibernate負責(zé)底層數(shù)據(jù)庫操作,Spring協(xié)調(diào)整個應(yīng)用各功能組件,并在業(yè)務(wù)層中解耦該層與數(shù)據(jù)訪問層,而Struts2則在控制層做主導(dǎo),并對視圖層頁面輸出能力做了增強。三個框架功能互補,讓整個J2EE應(yīng)用確實體現(xiàn)高效、易擴展、健壯。

一個簡單的應(yīng)用示例

(一) 項目介紹與準(zhǔn)備工作

為進一步分析如何通過Struts2、Spring、Hibernate構(gòu)建J2EE應(yīng)用,并且能在盡可能小的篇幅說明開發(fā)的過程,下面將通過項目開發(fā)中常見的“管理員登錄”的例子演示它們的整合過程。與此登錄過程無關(guān)的數(shù)據(jù)、設(shè)計過程、代碼將不做說明。另外,以下所講的各層,并不是真實項目開發(fā)的“步驟”,事實上正是框架的引入最大限度的使各層解耦,從而允許各層并行的開發(fā)。以下是項目的整體架構(gòu)圖(亦是工作流程圖):

(注:Spring的ContextLoaderListener及applicationContext.xml不屬于單獨的某一層,而是橫跨控制層、服務(wù)層、DAO層,管理各層組件。Hibernate的HibernateDaoSupport對JDBC進行了封裝。)

開發(fā)、測試環(huán)境:Eclipse6.5、jdk1.6、tomcat6.0、IE6

數(shù)據(jù)庫:mysql5.0

建立J2EE項目EShop2,并導(dǎo)入Spring、Hibernate、Struts2及整合所需相關(guān)jar包。將Spring、Struts2框架引進項目(Hibernate將由Spring引入)。(位于WebRoot\WEB-INF目錄下的)web.xml需做如下配置:

Struts2

org.apache.Struts2.dispatcher.FilterDispatcher

Struts2

/*

org.Springframework.web.context.ContextLoaderListener

(二) 數(shù)據(jù)庫設(shè)計

管理員表admin相關(guān)字段:

ID帳號? &, nbsp;?????????????????????????????? 密碼

id(int)??? LoginName(char(12))?????? loginPwd(char(12))

(三) Domain對象及O/R Mapping映射文件建立

Domain對象源文件Admin.java如下:

public class Admin {

private Integer id;

private String loginName;

private String loginPwd;

public Admin(){}

public Integer getId() {

? return id;

}

public void setId(Integer id) {

? this.id = id;

}

//其它getter、setter略

}

O/R Mapping映射文件Admin.hbm.xml主要內(nèi)容:

?

??

?

?

??

?

?

??

?

Hibernate正是通過本文件建立了對象與數(shù)據(jù)庫表的映射關(guān)系,從而程序員可以通過操作對象的方式操作數(shù)據(jù)庫表。

(四) DAO層

面向接口編程,這是好的做法。如下是AdminDao接口:

public interface AdminDao {

public Admin findAdminByNP(String LoginName,String LoginPwd);

//還有其它方法如saveAdmin(),removeAdmin()等略。

}

接口實現(xiàn)類:

//本類繼承于HibernateDaoSupport,這是Hibernate提供的一個重要的類,通過它操作數(shù)據(jù)庫,使代碼如此簡潔,以至程序無需任何注釋了。

public class AdminDaoImpl extends HibernateDaoSupport implements AdminDao {

public Admin findAdminByNP(String loginName, String loginPwd) {

? String hql="from Admin where LoginName=? and LoginPwd=?";

? String []values={loginName, loginPwd};

? List list=(List)this.getHibernateTemplate().find(hql,values);

? if (list.size()>0)

? {

?? return list.get(0);

? }

? return null;

}

//其它實現(xiàn)方法略。

}

(五) 服務(wù)層

還是面向接口,AdminService接口代碼如下:

public interface AdminService {

public Admin adminLogin(String loginName,String loginPwd) throws Exception;

//其它業(yè)務(wù)方法略

}

接口實現(xiàn)AdminServiceImpl:

public class AdminServiceImpl implements AdminService {

private AdminDao adminDao; //服務(wù)層通過DAO層接口操作數(shù)據(jù)庫

public Admin adminLogin(String loginName, String loginPwd) throws Exception {

? Admin admin = adminDao.findAdminByNP(loginName, loginPwd);

? return admin;

}

}

盡管服務(wù)層是項目的核心,通常也是開發(fā)過程中最復(fù)雜的一個環(huán)節(jié),但可以看到,有了DAO層,本例程序相當(dāng)簡單。這似乎未見Spring的身影。好,我們擴展一下功能,設(shè)想登錄時需要更新管理員的登錄次數(shù)并記錄日志。日志對象會對應(yīng)數(shù)據(jù)庫的另一個表。這樣登錄時將同時寫兩個表,出于數(shù)據(jù)一致性的考慮,這時就需要開啟事務(wù),如何管理呢?看如下代碼:

//引入Spring事務(wù)注解及事務(wù)傳播屬性注解類

import org.Springframework.transaction.annotation.Transactional;

import org.Springframework.transaction.annotation.Propagation;

@Transactional?? //注解管理事務(wù)

public class AdminServiceImpl implements AdminService {

private AdminDao adminDao;

//指定本方法須在同一事務(wù)內(nèi)處理

@Transactional(propagation=Propagation.REQUIRED)

public Admin adminLogin(String loginName, String loginPwd) throws Exception {

? Admin admin = adminDao.findAdminByNP(loginName, loginPwd);

? if (admin!=null)

? {

?????? //更新管理員登錄次數(shù),代碼略

?????? //添加管理員登錄事件記錄,代碼略

? }

? return admin;

}

}

事務(wù)的創(chuàng)建、開啟、回滾、提交等操作交由Spring管理,程序不會因為事務(wù)的引入增加多少代碼(只是增加兩句注解語句而已),盡管可以通過xml配置的方式管理事務(wù),但我認為這是最優(yōu)雅的做法。

(六) 控制層

控制層將以Struts2為主導(dǎo),首先是Struts2配置文件struts.xml,它應(yīng)位于源文件夾src根目錄下(編譯后將位于classes根目錄下)。

核心代碼如下:

?

??

?? error.jsp

?

?

?

?? index.jsp

?? login.jsp

?

AdminAction.java涉及相關(guān)代碼:

import com.opensymphony.xwork2.ActionContext;

//通過繼承ActionSupport我們的Action類將獲得一些像自動成員賦值、校驗、類型轉(zhuǎn)換等功能。

public class AdminAction extends ActionSupport {

private Admin admin;

private AdminService adminService;

//相關(guān)getter、setter方法略

public String login() throws Exception {

? String result=this.ERROR;

? String loginName,loginPwd;

? /**

?? * 領(lǐng)域模型的賦值是通過繼承ActionSupport,由Struts2為我們做的。

?? * 盡管可以在此驗證this.getAdmin().getLoginName()、

?? * this.getAdmin().getLoginPwd()值的合法性(如是否非空、長度是否

?? * 適合等)但這不是規(guī)范的做法,這部分工作應(yīng)該交由validate()方法處理

?? */?

? loginName=this.getAdmin().getLoginName();

? loginPwd=this.getAdmin().getLoginPwd();

? //調(diào)用服務(wù)層方法實現(xiàn)登錄驗證的操作,根據(jù)是否獲得Admin對象確定登錄成功與否

? Admin admin=this.getAdminService().adminLogin(loginName, loginPwd);

? if (admin!=null)

? {

?? Map session = ActionContext.getContext().getSession();

?? session.put("adminId",admin.getId()); //盡管可以把整個admin對象放入session,但這不是好的做法,畢竟除了id跟LoginName其它信息基本不使用。

?? session.put("adminLoginName",admin.getLoginName());

?? result=this.SUCCESS;

? }

? else

? {

?? Map request=(Map)ActionContext.getContext().get("request");

?? request.put("errorMessage", "用戶名或密碼輸入不正確!");

? }

? return result;

}

@Override

public void validate() {

? // 具體驗證實現(xiàn)略

}

}

前面除了在業(yè)務(wù)層擴展登錄方法,其它地方一直沒有出現(xiàn)Spring,必須承認 ContextLoaderListener是很容易讓人遺忘它的存在(除了在配置web.xml的時候),事實上站在開發(fā)者的角度看Spring很大程度是通過applicationContext.xml文件發(fā)揮作用的。盡管Spring不屬于控制層,但控制層是它為我們的項目服務(wù)的最后一層,是時候請出我們的功臣了。如下是applicationContext.xml配置:

class="org.apache.commons.dbcp.BasicDataSource">

class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" destroy-method="close">

?

可以看出,整個開發(fā)中除了視圖層Spring未涉足,從數(shù)據(jù)層到控制層,Spring一直在發(fā)揮作用。它調(diào)配好各項準(zhǔn)備工作,使各層有機的融合在一起。

(七) 視圖層

視圖層是客戶向服務(wù)器發(fā)起請求的窗口,表單頁面login.jsp主要代碼如下:

<%@ taglib uri="/Struts-tags" prefix="s" %>

<SPAN style=" Roman’?="" New="" ’Times="" Roman’;="" 宋體;="" 150%;="" 12pt;="">用戶名" required="true" />

<SPAN style=" Roman’?="" New="" ’Times="" Roman’;="" 宋體;="" 150%;="" 12pt;="">密碼" required="true"/>

<SPAN style=" Roman’?="" New="" ’Times="" Roman’;="" 宋體;="" 150%;="" 12pt;="">登錄">

<SPAN style=" Roman’?="" New="" ’Times="" Roman’;="" 宋體;="" 150%;="" 12pt;="">重置">

另外還有一個用于顯示錯誤報告的頁面error.jsp,內(nèi)容略。

(八) 程序運行

輸入http://localhost:8080/EShop2/adminope/login.jsp進入登錄頁面:

輸入不完整信息(未輸入密碼),程序返回登錄頁并提示錯誤:

輸入驗證未通過的信息(用戶名或密碼錯誤),需說明的是,因為是以dispatcher方式跳轉(zhuǎn),所以隱藏了error.jsp的真實地址(仍為表單目標(biāo)地址adminLogin.action):

輸入正確信息,成功登錄后臺:

(九) 總結(jié)

至此“管理員登錄”功能已開發(fā)完畢。當(dāng)然,本例所談的開發(fā),僅指編碼,事實上它只是軟件開發(fā)的一個環(huán)節(jié)。關(guān)于可行性研究、需求分析、設(shè)計、測試以及運行、維護不是本文所討論的范疇。通過以上的分析與說明,相信讀者能看出整個流程的規(guī)范化。盡管看起來有些按部就班,但事實上這正是現(xiàn)代軟件業(yè)向大規(guī)模、群體、團隊開發(fā)的必由之路。J2EE的規(guī)范以及為我們提供的指南是每個軟件開發(fā)從業(yè)人員所必須深刻學(xué)習(xí)的。而Struts2、Spring、Hibernate框架的學(xué)習(xí)與整合三者構(gòu)建J2EE應(yīng)用,從小的方面看是幫助我們領(lǐng)會與實踐J2EE思想、提高軟件開發(fā)素質(zhì),從大的方面看是提高軟件開發(fā)效率(各種框架為我們做了很多工作)、使軟件易于維護(規(guī)范化的代碼),進而促進軟件業(yè)的發(fā)展。

參考書目:

1.《輕量級Java EE企業(yè)應(yīng)用實戰(zhàn)-struts2+spring+hibernate整合開發(fā)》 李剛 電子工業(yè)出版社

2.《spring揭秘》 王福強 人民郵電出版社

3.《Struts 2深入詳解》孫鑫 電子工業(yè)出版社

4.《J2EE 企業(yè)級應(yīng)用測試實踐》 白勝 清華大學(xué)出版社

?

http://www.striveday.com/newsshow/532.html

總結(jié)

以上是生活随笔為你收集整理的整合Struts2、Spring、Hibernate构建J2EE应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。