王歡
[摘要] 當今開發Web應用的語言有很多種,如J2EE, ASP.NET, PHP等, 各種語言都有各自的優勢和不同的應用場合。但企業級應用大都采用J2EE,使用它的框架技術SSH (Struts, Spring, Hibernate) 可以簡化開發流程,加快開發速度,同時便于今后的運行和維護。
[關鍵詞] J2EE; SSH集成框架; Struts; Spring; Hibernate; MVC
doi : 10 . 3969 / j . issn . 1673 - 0194 . 2012 . 02. 030
[中圖分類號]TP311.5[文獻標識碼]A[文章編號]1673 - 0194(2012)02- 0053- 03
J2EE領域針對不同的層(Model,View,Controller)有很多框架,如何選擇適合的框架是個關鍵問題。本文通過分析模型層、視圖層和控制層的不同功能,最終選擇SSH的集成。
1MVC模型
當用戶向Web容器發送一個請求后,Web容器會根據請求和地址去調用一個Servlet進行處理,當Servlet處理完成以后,它需要將結果頁面回送給Web容器。這時我們可以在Servlet內部編寫Java類來生成HTML代碼,Servlet直接把這些內容返回給Web容器的Response對象。此時Web容器收到這些內容并將其全部轉化為HTML,再返回給瀏覽器。這種編程思想有一定的缺陷,它將Java代碼也就是Servlet里面的代碼和HTML代碼混雜在一起,如果我們在之后對先前開發的代碼進行維護,這時需要修改Servlet代碼里那些用于生成HTML代碼的字符串,這樣非常麻煩,不便于開發和維護。于是人們開始思考采用其他方法來解決這一不便,于是MVC模式應運而生,用來實現Java代碼和HTML代碼的分離。
在MVC模式中,當Servlet處理完請求后,會產生一些數據,這些數據都會被裝在對象中,這個對象具有不同的屬性,我們將這個對象叫做JavaBean。這時我們再寫一個JSP頁面,這個頁面從JavaBean中讀取數據并嵌入在HTML代碼中。以后當需要修改HTML代碼的時候,我們就不需要修改Servlet,而是可以直接去修改JSP頁面,這樣就實現了Java代碼和HTML代碼的分離。
2SSH集成框架的設計
2.1視圖層(View)
視圖層的主要任務就是提供一個接口,接收用戶提交的數據并將服務器處理的結果顯示給用戶,一般采用JSP頁面實現。在沒有采用框架技術前,會面臨以下問題:首先,普通的HTML組件和JSP 標簽提供的功能非常有限;其次,為了實現復雜的界面,不可避免地會在JSP頁面中混入大量的Java代碼,這樣無法真正實現頁面邏輯與處理邏輯的分離。最后,對頁面的國際化處理要求越來越高。針對以上問題,在視圖層采用Struts來實現。Struts提供了功能強大的自定義標簽,不僅實現傳統HTML頁面組件的所有功能,還封裝了大量Java代碼,如邏輯判斷、循環顯示等功能。同時針對頁面的國際化和數據校驗要求,Struts也提供了相應的處理機制。
2.2控制層(Controller)
控制層的主要功能是接受客戶端的請求,并調用相應的組件進行處理,最后采用不同的視圖顯示結果,在控制層采用Struts,Spring框架。Struts擁有一個結構清晰、功能全面、配置靈活的控制層結構,通過配置文件對客戶請求進行分發和處理,實現視圖層和控制層的銜接。對于模塊間的緊耦合問題,采用Spring的IoC容器實現的依賴注入功能。另外,Spring的AOP很好地實現了事務管理功能。
2.3模型層(Model)
模型層的功能包括業務邏輯操作(JavaBean類)和數據庫(DAO類)的操作,Spring的依賴注入功能解決了由于控制層通過硬編碼調用這些類產生的緊耦合問題。另外,Hibernate以面向對象的方式實現了對數據的持久化工作,簡化數據操作。
3Struts框架
3.1Struts概述
Struts是一個嚴格按照MVC模式設計的框架,重點在控制層和視圖層上,即主要提供一個ActionServlet控制器和一套自定義標簽庫。View層主要通過JSP頁面來顯示,其提供的自定義標簽庫可以大大簡化開發的過程。Controller主要采用Servlet實現,由ActionServlet和Action組成。Model主要采用Java/EJB實現。
3.2Struts的工作原理
如圖3所示,Struts這個 Web層框架主要處理接收參數,返回結果,與數據庫沒有關系。換句話說,它就是一個大的Servlet,既然是Servlet,我們就可以在web.xml文件中對它進行配置并映射URL地址。這里它叫做ActionServlet。我們可以把符合某一組特征的請求映射給這個ActionServlet,是一組而不是一個。當ActionServlet收到不同的請求后,它會交給不同的Action進行處理。這時需要參照struts-config.xml這個配置文件來查看哪個請求對應哪個Action。目前為止,我們可能會疑問,這樣做的好處在哪里?以前每收到一個請求,我們會編寫一個Servlet,而現在我們每遇到一個請求,我們會編寫一個Action,這有什么區別呢?
ActionServlet在調用Action之前,會將頁面參數封裝到JavaBean對象中,這樣可以省去大量的request.getParameter(“”)這個方法;同時如果用這個方法來獲得參數,我們還需要進行類型轉換,例如將字符串類型轉換成整形或日期類型。但如果封裝到JavaBean中,就不用再進行類型轉換。但是參數被FormBean封裝后,我們怎么知道哪個FormBean對應哪個Action呢?這個問題可以通過查詢struts-config.xml文件來解決。那么對于這個Form類,我們可以看到里面對應著所有的屬性,并且每一個屬性都有一個set和get方法。這里需要強調一點,通常情況下,頁面的屬性名稱和Form類的屬性名稱相同,但是嚴格來說即使不一樣也可以,關鍵是get方法的名字去掉get后要和頁面的屬性名稱一樣,這里名稱是嚴格區分大小寫的。在數據被封裝到JavaBean中后,通過圖4,我們發現還需要經過FormBean的validate方法的驗證,如果數據沒有意義,即沒有通過驗證,則這些數據不會被傳遞給Action。這時會顯示一個錯誤頁面,這個錯誤頁面由struts-config.xml中的input屬性來決定。默認情況下,我們需要對這些屬性進行驗證。當通過驗證后,我們再來看Action類,每個Action并不是直接返回頁面,而是返回一個ActionForward對象,而這個對象對應一個頁面,這種對應關系可以在struts-config.xml中看到。例如:<forward name="reg" path="/reg.jsp" />,這樣就實現了代碼和頁面的解耦。以后每當想修改跳轉的頁面時,只需修改配置文件即可。
4Spring 框架
4.1Spring概述
Spring 是一個開源的控制反轉(Inversion of Control, IoC)和面向切面(AOP)的容器框架,它的主要目的是簡化企業開發。
4.2IoC (Inversion of Control)和DI(Dependency Injection)
所謂控制反轉就是應用本身不負責依賴對象的創建及維護,它是由外部容器負責的。這樣控制權就由應用轉移到了外部容器,控制權的轉移就是反轉。
IOC控制反轉:
public class PersonServiceBean{
private PersonDao personDao = new PersonDao();
public void save(Person person){
personDao.save(person);}}
personDao 是在應用內部創建及維護的。原來要創建對象personDao是由PersonDao負責創建的,控制反轉后,對象personDao的創建不再由PersonDao控制,而是由外部容器(這里我們指的是Spring容器)來負責創建。
依賴注入(Dependency Injection):在運行期間,由外部容器動態地將依賴對象注入到組件中。通過接口來啟用這個對象,不像原來,如果不提供依賴類,連編譯都無法通過。
當我們把依賴對象交給外部容器負責創建時,那么PersonServiceBean類可以改為:
public class PersonServiceBean{
private PersonDao personDao;
public PersonServiceBean(PersonDao personDao){
this.personDao=personDao;}
public void save(Person person){
personDao.save(person);}}
依賴注入的3種方式:
(1) 使用構造器傳遞參數注入。在配置文件中,<constructor-arg index=”0” type=”類型” ref=”依賴對象的名稱”></ constructor-arg>Index=”0”: 表示第一個參數</constructor-arg>標簽對。構造方法中有幾個參數,就要有幾個標簽對。
(2) 使用屬性setter方法注入。在類中,添加參數的setter方法為,在配置文件中:<property name=”” ref=””></property>。
(3) 使用Field注入(用于注解方式)。
4.3AOP (Aspect Oriented Programming)
用AOP很容易實現如權限攔截、運行期監控等功能。Spring提供了兩種面向切面使用方式:
(1) 基于注解方式:@Pointcut(“execution(*cn.demo.service..*.*(..))”)。
(2) 基于XML配置方式:execution(*cn.demo.service..*.*(..))”。
5Hibernate 框架
5.1Hibernate概述
ORM (Object Relational Mapping):解決面向對象程序設計與關系數據庫之間數據不匹配的技術。它是開源的對象關系映射框架。Hibernate本質上是一個提供數據庫服務的中間件。其常用的6個核心接口是:Session,SessionFactory,Configuration,Transaction,Query,Criteria。使用Hibernate主要是創建相關的XML“映射文檔”。
5.2使用Hibernate的注意事項
(1) 默認的構造方法(必須的,無參的)。
(2) 有無意義的標示符id(主鍵,可選),但是強烈建議加上,否則Hibernate的一些特性會受到限制。這樣操作效率也會更高。
(3) 非final的,對懶加載有影響。類不能被繼承。在運行過程中,Hibernate會把這個實體類替換成一個新的類,它是繼承該實體類的。如果不能繼承,那么懶加載這個功能也就失效了。懶加載是為了提高性能,避免不必要的數據查詢,推后與數據庫交互的時間,延遲到當你需要訪問這個屬性的時候。代理只在session關閉之前有效。通過asm和cglib這兩個Jar包實現懶加載。
對象狀態:
(1) 瞬時(transient):數據庫中沒有數據與之對應,超過作用域會被JVM垃圾回收器回收,一般是new出現且與session沒有關聯的對象。
(2) 持久(persistent):數據庫中有數據與之對應,當前與session有關聯,并且相關聯的session沒有關閉,事務沒有提交;持久對象狀態發生改變,在事務提交時會影響到數據庫(Hibernate能檢測到)。
(3) 托管(detached):數據庫中有數據與之對應,但當前沒有session與之關聯;托管對象發生改變,Hibernate不能檢測到。
6結束語
通過Struts,Spring,Hibernate三種框架的集成,充分發揮各自優勢。該框架不僅具有Struts清晰的控制結構、Hibernate帶來的操作數據庫的方便性,而且Spring的IoC實現模塊間的解耦。
主要參考文獻
[1] 張峰. 基于Ajax技術與J2EE框架的Web應用研究與實現[D]. 北京:中國地質大學,2008.
[2] 李濤. J2EE平臺下快速WEB開發的研究與應用[D]. 武漢:武漢理工大學,2010.
[3] 朱平付. 基于J2EE的輕量級架構開發方法及應用研究[D]. 長沙:中南大學,2008.
[4] 張軍芳. 基于J2EE平臺和MVC模式的Web研究與應用[D]. 武漢:武漢理工大學,2008.