国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
JSF+Spring+Hibernate的實例講解
 

我一直認為jsf必定會成為MS的 Net Freamwork的競爭對手。但,jsf尚在發(fā)展階段。至少目前不會。

JSF使用
原文地址:http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html

使用JavaServer Faces(JSF)、Spring Framework和Hibernate建立一個真實的Web應用程序
內容概要
使用JSF建立一個真實的Web應用程序不是沒有意義的任務,這篇文章介紹了如何將JSF與Sping Framework和Hibernate集成,并且給出了使用這些技術建立這個真實的Web應用程序的最佳實踐和設計指導
       JavaServer Faces(JSF)技術是J2EE應用程序的一個新的用戶接口框架,它非常適合基于MVC(Model-View-Controller)體系結構的應用程序。已經有大量的文章介紹JSF。然而,很多文章都是站在理論研究的層面上,沒有挑戰(zhàn)一個真實的企業(yè)開發(fā)。很多問題沒有解決,例如,JSF怎樣全面適合MVC體系結構?JSF如何與其他JAVA框架集成?業(yè)務邏輯應該放在JSF的backing beans里面嗎?怎樣處理JSF里面的安全問題?最重要的是你怎樣使用JSF建立一個真實的Web應用程序?
      這篇文章涉及所有這些問題。它向你展示如何集成其他特定的Java框架,Spring Framework和Hibernate,它示范怎樣去創(chuàng)建一個叫JCatalog的Web應用程序,一個在線的產品目錄系統(tǒng)。這篇文章使用JCatalog例子,介紹了Web應用程序設計的每一個階段,包括業(yè)務需求收集,分析,技術選擇,高層體系結構和詳細設計。這篇文章論述了JCatalog里面好的和不好的技術,示范了應用程序設計中一些關鍵方面的方法和步驟。
       這篇文章是寫給正在從事基于J2EE Web應用程序的Java架構師,開發(fā)者,它不是對JSF、Spring Framework和Hibernate的入門教程。如果您對這些領域不熟悉,請參考文章最后的資源鏈接。
例子應用程序的功能需求
        這篇文章的例子應用程序JCatalog是一個真實的Web應用程序,例子足夠現實是為了決定應用程序架構而進行意味深長的討論的基礎。我通過介紹JCatalog項目的需求開始。我在這里談到后面貫穿于整個文章的內容是為了演示技術選擇和體系結構設計。
設計Web應用程序的第一步是收集系統(tǒng)的功能需求,這個例子應用程序是一個典型的電子商務應用系統(tǒng)。用戶能瀏覽產品目錄和查看產品細節(jié),管理員能管理產品目錄。功能還可以增加,舉例來說,為了開發(fā)一個成熟的電子商務系統(tǒng),可以添加庫存管理和訂單處理的功能。
用例
用例分析被用于去訪問例子應用程序的功能需求,圖1是應用程序的用例圖。  




       圖1 用例圖

        一個用例圖確定在一個系統(tǒng)中的參與者以及參與者可以執(zhí)行的操作。例子應用中7個用例必須被實現。參與者中的User能瀏覽產品目錄和察看產品細節(jié)。一旦用戶以Administrator身份連接到系統(tǒng),他就能創(chuàng)建新產品,編輯存在的產品,刪除老的產品。

業(yè)務規(guī)則
JCatalog 必須符合下面的業(yè)務規(guī)則:
每個產品有一個唯一的產品ID
每個產品至少屬于一個目錄
產品ID一旦被創(chuàng)建就不能改變
假定
對于產品的設計和實現,我們做下面的假定。
英語是默認語言;不要求國際化
目錄中不超過500種產品
目錄的更新不頻繁
頁面流
圖2顯示了所有JCatalog的頁面和它們之間的轉換。

                                                                                              圖2 頁面流圖

        應用程序有兩組頁面:公共的國際互聯網和管理員的企業(yè)內部網。企業(yè)內部網只有對那些成功登陸到系統(tǒng)的用戶有效。產品概要頁面是公用的,它作為產品目錄的內容包含在一個HTML框架里面。產品列表是一個特殊的目錄,只能被管理員看見,它包含創(chuàng)建、編輯和刪除產品的鏈接。
        圖3是目錄頁的一個模型。理想情況下,每一個頁面所有的控制和必要的內容明細的模型應該被包含在需求文檔里面。

                      
                                                                    圖3 目錄頁面模型
高級體系結構設計
下一步的設計是Web應用程序的高級體系結構設計,它包括將應用程序細分成功能組件以及將這些組件劃分到各自所屬的層。高級體系結構設計獨立于使用的技術。
多層體系結構
一個多層體系結構將整個系統(tǒng)劃分成清晰的單元——客戶端、表示層、業(yè)務邏輯層、集成層和企業(yè)信息系統(tǒng)(EIS),這保證了清晰的責任劃分以及可維護性和可擴展性。三層或多層系統(tǒng)已經被證明比沒有業(yè)務邏輯層的客戶-服務器系統(tǒng)具有更多的可升級性和柔韌性。
客戶端是數據模型被消費和呈現的地方。對于一個Web應用程序,客戶層通常是Web瀏覽器?;跒g覽器的瘦客戶不包含表示邏輯;它依賴于表示層。
表示層使用業(yè)務邏輯層為用戶服務,它知道怎樣去處理一個客戶請求,怎樣去和業(yè)務邏輯層結合以及怎樣去選擇下一個試圖去顯示。
業(yè)務邏輯層包含一個應用程序的業(yè)務對象和業(yè)務服務。它從表示層接受請求,基于請求處理業(yè)務邏輯,作為訪問EIS層資源的的中介。業(yè)務邏輯層組件使用許多系統(tǒng)級別的服務,例如,安全管理、事物管理和資源管理。
集成層是業(yè)務邏輯層和EIS層之間的橋梁。它封裝了與EIS層相結合的邏輯。有時,集成層和業(yè)務邏輯層的結合是作為中間層被提到。
應用程序數據在EIS層被持久化,包括關系數據庫,面向對象數據庫和遺留系統(tǒng)。
JCatalog 的體系結構設計
圖4顯示了JCatalog的高級體系結構設計以及它怎樣適合多層體系結構。

                                                                       圖4 高級體系結構圖

應用程序使用了一個多層的非分布式的體系結構,圖4顯示應用程序層和每一層技術選擇的劃分。它也用于應用程序的部署圖。對于一個可配置的體系結構,表示層、業(yè)務邏輯層和集成層被定位在同樣的Web容器。定義良好的接口隔離了每一層的職責??膳渲玫捏w系結構使應用程序簡單和可升級。
對于表示層,經驗告訴我們,最好的實踐是選擇一個存在的,被驗證的Web應用框架,遠比設計開發(fā)一個定制的框架好。我們有幾個Web應用框架可供選擇,舉例來說,Struts、WebWork和JSF。對于JCatalog項目,我們使用JSF。
對于業(yè)務邏輯層,不是使用EJB(Enterprise JavaBeans)就是使用POJO(plain old Java objects)。如果應用程序是分布式的,EJB具有遠程接口是一個較好的選擇。因為JCatalog是一個典型的沒有遠程訪問請求的Web應用程序,POJO在Spring框架的幫助下,用于實現業(yè)務邏輯層。
Pure JDBC(Java Database Connectivity):這是最靈活的實現方法;然而,低級的JDBC和不好的JDBC代碼工作是麻煩的,執(zhí)行的不好。
Entity beans:一個容器管理持久化(CMP,container-managed persistence)的entity bean是隔離數據訪問代碼和處理O/R(object- relational) mapping數據持久化的昂貴的方法。它是一個以應用服務器為中心的解決辦法。一個entity bean不和特定的數據庫緊耦合,但是應用程序和EJB容器進耦合。
O/R mapping framework:一個O/R影射的框架采用以對象為中心的方法實現數據持久化。一個以對象為中心的應用程序是容易開發(fā)和高度輕便的。在這個領域內存在幾個框架——JDO(Java Data Objects),Hibernate,Toplink。CocoBase是一個新的例子。在例子應用程序中我們使用HIbernate。
現在,讓我們討論將應用程序的每一個層聯合起來設計的問題。因為JSF相對來說是一個新技術,我強調一下它的使用。
表現層和JavaServer Faces(JSF)
表現層收集用戶輸入,呈現數據,控制頁面導航,代替用戶與業(yè)務邏輯層交互。表現層也能校驗用戶輸入,維護應用程序的會話狀態(tài)。下面的章節(jié),我討論表現層的設計考慮和模式以及我選擇JSF去實現JCatalog項目的表現層的原因。
MOdel-View-Controller(MVC)
MVC是Java藍皮書(BluePrints)中推薦的交互式應用程序體系結構設計模式。MVC分別設計關注的問題,因此減少了代碼的重復,集中控制,使應用程序更具擴展性。MVC也幫助開發(fā)者使用不同的技術集合,集中他們核心的技術,通過定義清晰的接口進行合作。MVC是表現層的體系結構設計模式。
JavaServer Face
JSF是一個基于Java的Web應用程序服務端的用戶接口組件框架。JSF包括表示UI組件和管理其狀態(tài)的API;處理事件,服務端校驗,數據轉換;定義頁面導航;支持國際化和可訪問性;提供所有這些特點的擴展能力。它還包括兩個為JSP定制的標簽庫,一個用于表示JSP頁面內的UI組件,一個用于配置服務端的對象組件。
JSF和MVC
JSF很適合基于MVC的表現層體系結構。它提供動作和表現之間清楚地劃分。它影響了UI組件和Web層概念,不限定你去使用特定的腳本技術或者標記語言。
JSF backing beans 是model層(后面的章節(jié)有關于backing beans 的更多內容)。它們也包含動作,這是控制層的擴展,代理用戶對業(yè)務邏輯層的請求。請注意,從整體應用程序的體系結構來看,業(yè)務邏輯層也能被作為Model層提到。使用JSF定制標簽的JSP頁面是視圖層。Faces Servlet提供控制者的功能。
為什么用JSF
JSF不僅僅只是另一個Web框架,下面是JSF與其他Web框架不同的特點:
象Swing一樣面向對象的Web應用程序開發(fā):服務端有狀態(tài)的UI組件模型,具有事件監(jiān)聽和操作者,開始了面向對象Web應用程序開發(fā)。
Backing-bean管理:Backing beans是頁面中JavaBeans組件和UI組件的聯合。Backing-bean管理UI組件對象定義和對象執(zhí)行應用程序特殊過程以及控制數據的分離。JSF在正確的范圍內執(zhí)行存儲和管理這些backing-bean實例。
可擴展的UI組件模型:JSF UI組件是組成JSF應用程序用戶接口可配置、可復用的元素。你能擴展標準的UI組件和開發(fā)更多的復雜組件。舉例來說,菜單條和樹型構件。
靈活的表現模型:一個renderer分隔一個UI組件的功能和視圖。多個renderer能被創(chuàng)建,用于定義相同或不同客戶端上同樣組件的不同外觀。
可擴展的轉化和校驗模型:基于標準的轉換者和校驗者,你能開發(fā)定制的轉換者和校驗者,它們提供最好的模型保護。
盡管JSF很強大,但是現在還不成熟。組件、轉換者和校驗者是JSF基本的。每一個校驗模型不能處理組件和校驗者之間多對多的校驗。另外,JSF定制標簽不能和JSTL(JSP Standard Tag Library)無縫結合。
在下面的部分,我討論用JSF實現JCatalog項目時幾個關鍵方面和設計決定。首先討論JSF中managed beans和backing beans的定義和使用。然后,我介紹JSF中怎樣處理安全、分頁、緩存、文件上傳、校驗和錯誤消息定制。
Managed bean,backing bean,view object和domain object model
JSF介紹了兩個新的術語:managed bean 和 backing bean。JSF 提供一個強大的managed-bean工廠。被JSF執(zhí)行的JavaBean對象管理被叫做managed beans。一個managed bean描述一個bean怎樣被創(chuàng)建和管理。它沒有利用bean的功能性。
Backing bean 定義頁面特性和處理邏輯與UI組件的聯合。每一個backing-bean屬性被綁定到組件實例或者它的值中的一個。一個backing bean也定義一個組件可執(zhí)行的功能的集合,例如,校驗組件的數據,處理組件觸發(fā)事件,組件激活時與導航相關的執(zhí)行過程。
一個典型的JSF應用程序在應用程序的每一個頁面中連接一個backing bean。然而,有時在真實的世界里,強迫一個backing bean和一個頁面一對一的關系不是一個理想的解決方案。它能造成象代碼重復這樣的問題。在真實世界的場景里,幾個頁面可能需要共享在后臺的同樣的backing bean。例如,在JCatalog項目里,CreateProduct和EditProduct頁面共享同樣的ProductBean的定義。
一個試圖對象是在表示層明確使用的模型對象。它包含了必須顯示在視圖層的數據和校驗用戶輸入,處理事件和與業(yè)務邏輯層相結合的邏輯。backing bean是基于JSF應用程序的視圖對象。
在這篇文章中Backing bean 和視圖對象是可交換的術語。
比較Struts中的Actionform和Action,在JSF中開發(fā)backing beans遵循面向對象設計的最好實踐。一個backing bean不僅包含視圖數據,也包含與數據相關的行為。在Struts 中,Action 和ActionForm包含數據和邏輯分離。
我們都聽說過域對象模型。那么,域對象模型和視圖對象有什么不同呢?在一個簡單的Web應用程序里,一個域對象模型能被用于所有的層,然而,在一些復雜的Web應用程序里面,一個單獨的視圖對象模型需要被使用。域對象模型是關于業(yè)務對象,應該歸入業(yè)務邏輯層。它包含特定業(yè)務對象相關的業(yè)務數據和業(yè)務邏輯。一個視圖對象包含特定數據和行為的表示。JCatalog項目的ProductListBean提供了一個好的例子。它包含表示層數據和邏輯細節(jié),舉例來說,與分頁相關的數據和邏輯。從域對象模型分離視圖對象的缺點是數據映射必須發(fā)生在兩個對象模型之間。在JCatalog項目中,ProductBeanBuilder和UserBeanBuilder使用基于反射的Commons BeanUtils去實現數據映射。
安全
當前,JSF沒有內置的安全特征。例子的安全需求是基本的:用戶連接到管理員使用的公司內部網需要的認證是基于用戶名和密碼,不需要授權。
在JSF里面幾個處理用戶認證的方法已經被提出:
Use a base backing bean:這個解決方 案是簡單的。然而,它使backing beans與特殊的遺產層次綁定。
Use JSF ViewHandler decorator:這種方法使安全邏輯緊緊地加上一個特殊的Web層技術。
Use a servlet filter:一個JSF 應用程序與其他基于Java的Web應用程序不同。它在一個恰當的地方使用一個過濾器處理認證檢查。這種方法使Web應用程序中的認證邏輯減弱了。
在例子應用程序中,SecurityFilter類處理用戶認證。當前,受保護的資源只有三個頁面,為了簡單,它們被硬編碼在Filter類里面??梢酝ㄟ^擴展安全規(guī)則來改進它,把受保護的資源放到配置文件中。
分頁
應用程序的目錄頁需要分頁。表現層能處理分頁,這意味著所有數據必須被重新得到存儲在這層。分頁也能在業(yè)務邏輯層、集成層甚至是EIS層處理。JCatalog項目的假定是在目錄中的產品不超過500種。所有產品信息適合保存在用戶session中。分頁邏輯存在ProductListBean類中。與分頁有關的參數“每頁的產品”通過JSF的managed-bean工具配置。
緩存
緩存是Web應用程序中改善性能的眾多重要技術中的一種。緩存能在應用程序體系結構內的許多層完成。體系結構中的一層減少調用它下面的層時,緩存是非常有益的。JSF managed-bean工具使在表現層實現緩存更容易。通過改變一個managed bean的范圍,包含在managed bean中的數據能在不同的范圍內緩存。
例子應用程序使用二級緩存。第一級緩存在業(yè)務邏輯層里面。CachedCatalogServiceImpl類維護所有產品和目錄的讀/寫緩存。Spring 管理的類作為一個單獨服務bean。所以,一級緩存是一個應用程序范圍的讀/寫緩存。
對于簡單的分頁邏輯和將來應用程序速度的提高,表現層的會話范圍內的產品也被緩存。每個用戶維護他session里面自己的ProductListBean。缺點是占用系統(tǒng)內存和存在舊數據。在一個用戶session的持續(xù)時間里,如果管理員更新了目錄,用戶可能會看到舊的目錄數據。然而,基于這樣的假定,目錄中部超過500種產品,而且目錄更新不頻繁,我們應該能夠忍受這些缺點。
文件上傳
目前,JSF的Sun參考實現中不支持文件上傳。Struts有很好的文件上傳能力,然而,Struts外觀集成庫是必須使用。 在JCatalog項目中,一個圖片與每個產品關聯。一個用戶創(chuàng)建一個新的產品之后,必須上傳與之相關的圖片。圖片保存在應用服務器的文件系統(tǒng)里面。產品ID是圖片名.
例子應用程序使用<input type="file">,Servlet 和Jakarta通用的文件上傳API,實現一個簡單的文件長傳功能。這個功能使用兩個參數:產品圖片路徑和圖片上傳結果頁面。它們都通過ApplicatonBean配置。請參考FileUploadServlet類的詳細資料。
校驗
JSF具有的標準校驗是簡單基本的,不能滿足真實的需求。開發(fā)自己的JSF校驗是容易的。我在例子應用程序中使用定制標簽來開發(fā)SelectedItemsRange校驗。它校驗通過UISelectMany UI組件選擇的項目數量:
<h:selectManyListbox value="#{productBean.selectedCategoryIds}" id="selectedCategoryIds">
   <catalog:validateSelectedItemsRange minNum="1"/>
   <f:selectItems value="#{applicationBean.categorySelectItems}" id="categories"/>
</h:selectManyListbox>
更多的詳細資料請參考例子應用程序。
錯誤消息定制
 在JSF里面,你可以設置資源包定制轉換和校驗時的錯誤消息。資源包被設置在faces-config.xml里面:
<message-bundle>catalog.view.bundle.Messages</message-bundle>
The error message‘s key-value pairs are added to the Message.properties file:


#conversion error messages
javax.faces.component.UIInput.CONVERSION=Input data is not in the correct type.

#validation error messages
javax.faces.component.UIInput.REQUIRED=Required value is missing.
業(yè)務邏輯層和Spring Framework
業(yè)務對象和業(yè)務服務在業(yè)務邏輯層。一個業(yè)務對象不僅包含數據,也有與特定對象關聯的邏輯。在例子應用程序中標識了三個業(yè)務對象:Product,Category和User.
業(yè)務服務與業(yè)務對象相結合,提供高級的業(yè)務邏輯。一個包含直接使用的服務接口的標準的業(yè)務接口層應該被定義。在Spring Framework的幫助下,POJO實現了Jcatalog項目業(yè)務邏輯層。有兩個業(yè)務服務:CatalogService包含與目錄管理相關的業(yè)務邏輯,UserService包含了用戶管理邏輯。
Spring是基于控制反轉概念(IOC,inversion of control)。在例子應用程序中使用的Spring特征包括:
Bean management with application contexts:Spring能有效地組織我們的中間層對象,垂直處理。Spring 能避免一個實體功能的分解,促進好的面向對象設計實現,舉例來說,接口設計。
Declarative transaction management:Spring 使用AOP(aspect-oriented programming)去描述不使用EJB容器的聲明性事務處理。這種方法,事務管理能被應用到任何POJO。Spring事務管理不和JTA(Java Transaction API)綁定,使用不同的事物策略工作。在例子應用程序中聲明性事務管理Hibernate中的事務。
Data-access exception hierarchy:Spring提供一個值得回味的異常層次代替SQLException。使用Spring數據訪問異常層次,Spring數據訪問異常翻譯者必須在Spring配置文件里面定義:       
<bean id="jdbcExceptionTranslator"
class= "org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator">
   <property name="dataSource">
      <ref bean="dataSource"/>
   </property>
</bean>
在例子應用程序中,如果插入的一個新產品的ID是重復的,一個 DataIntegrityViolationException 會被拋出。這個異常會被捕獲然后作為DuplicateProductIdException被拋出。這種方法,DuplicateProductIdException能處理不同的數據訪問異常。
 Hibernate integration:Spring不強迫我們使用它強大的JDBC抽象特征。它和O/R映射框架集成的很好,尤其是Hibernate。Sping提供有效的、安全的Hibernate會話操作。在應用程序上下文操作Hibernate的配置SessionFactories 和JDBC數據源,使應用程序容易測試。
集成層和HIbernate
Hibernate是一個開源O/R映射框架,它減少使用JDBC API的需要。Hibernate支持所有主流的SQL數據庫管理系統(tǒng)。Hibernate Query Language是SQL面向對象的最小的擴展來設計的,在對象和關系世界間提供了一個優(yōu)雅的橋。Hibernate提供數據恢復和更新的工具,事務管理,數據連接池,programmatic and declarative queries,聲明實體關系管理。
Hibernate和其他O/R映射框架相比入侵性較小。使用反射和運行時產生字節(jié)碼,SQL在系統(tǒng)開始時產生。它允許我們開發(fā)符合Java習慣的持久對象,包括聯合,繼承,多態(tài),聚合和Java集合框架。在例子應用程序中的業(yè)務對象是POJO,不需要實現Hibernate的特殊接口。
Data Access Object (DAO)
JCatalog項目使用DAO模式。這個模式抽象和封裝了所有對數據源的訪問。應用程序有兩個DAO接口。CatalogDao和UserDao。它們的實現類是HibernateCatalogdaoImpl和HibernateUserDaoImpl包含與Hibernate相關的管理和持久化數據邏輯。
實現設計
現在,讓我把每件事情都串起來,實現JCatalog項目。你可以沖資源列表中下載應用程序的完整源代碼。
數據庫設計
我們?yōu)槔討贸绦騽?chuàng)建指定目錄的結構,它包含4個表,如圖5:

                                                          圖5 數據結構圖

類設計
圖6圖解了JCatalog項目的類圖

 

                                                      圖6 類圖

面向接口編程貫穿于整個設計。在表現層,四個bean被使用:ProductBean, ProductListBean, UserBean和 MessageBean。業(yè)務邏輯層包含兩個服務(CatalogService and UserService)和三個業(yè)務對象(Product, Category, and User)。集成層包括兩個DAO接口和它們的Hibernate實現。Spring application contexts 包含和管理業(yè)務邏輯層和集成層的很多object beans。ServiceLocator使JSF和業(yè)務邏輯層結合到一起。
Wire everything up
因為這篇文章篇幅的限制,我們只看一個用例。CreateProduct用例示范了怎樣將每件事情串起來建造應用程序。深入細節(jié)以前,讓我們使用一個序列圖(圖7)示范所有層端到端的整合:

                             

                                    
                                                       圖7 CreateProduct用例的序列圖
現在,讓我們通過對每一層的介紹討論如何實現CreateProduct用例的更多細節(jié)。
表現層
表現層的實現包括創(chuàng)建JSP頁面,定義頁面導航,創(chuàng)建和配置backing beans,將JSF與業(yè)務邏輯層結合。
JSP page:createProduct.jsp是創(chuàng)建新產品的頁面。它包括UI組件和捆綁這些組件的ProductBean。ValidateItemsRange自定義標簽檢驗用戶選擇目錄的數目。每個新產品至少有一個目錄被選擇。
Page navigation:應用程序的導航定義在應用程序的配置文件里面,faces-navigation.xml。CreateProduct定義的導航規(guī)則是:
<navigation-rule>
   <from-view-id>*</from-view-id>
   <navigation-case>
      <from-outcome>createProduct</from-outcome>
      <to-view-id>/createProduct.jsp</to-view-id>
   </navigation-case>
</navigation-rule>
<navigation-rule>
   <from-view-id>/createProduct.jsp</from-view-id>
   <navigation-case>
      <from-outcome>success</from-outcome>
      <to-view-id>/uploadImage.jsp</to-view-id>
   </navigation-case>
   <navigation-case>
      <from-outcome>retry</from-outcome>
      <to-view-id>/createProduct.jsp</to-view-id>
   </navigation-case>
   <navigation-case>
      <from-outcome>cancel</from-outcome>
      <to-view-id>/productList.jsp</to-view-id>
   </navigation-case>
</navigation-rule>
Backing bean: ProductBean不僅包含了頁面中UI組件與數據映射的屬性,也包含三個actions:createAction,editAction和deleteAction。這是createAction()方法的代碼:

public String createAction() {
   try {
      Product product = ProductBeanBuilder.createProduct(this);

      //Save the product.
      this.serviceLocator.getCatalogService().saveProduct(product);

      //Store the current product id inside the session bean.
      //For the use of image uploader.
      FacesUtils.getSessionBean().setCurrentProductId(this.id);

      //Remove the productList inside the cache.
      this.logger.debug("remove ProductListBean from cache");
      FacesUtils.resetManagedBean(BeanNames.PRODUCT_LIST_BEAN);
   } catch (DuplicateProductIdException de) {
      String msg = "Product id already exists";
      this.logger.info(msg);
      FacesUtils.addErrorMessage(msg);

      return NavigationResults.RETRY;
   } catch (Exception e) {
      String msg = "Could not save product";
      this.logger.error(msg, e);
      FacesUtils.addErrorMessage(msg + ": Internal Error");

      return NavigationResults.FAILURE;
   }
   String msg = "Product with id of " + this.id + " was created successfully.";
   this.logger.debug(msg);
   FacesUtils.addInfoMessage(msg);

   return NavigationResults.SUCCESS;
}
在這個action里面,基于ProductBean的一個Product業(yè)務對象被建立。ServiceLocator查詢CatalogService。最后,createProduct的請求被委派給業(yè)務邏輯層的CatalogService。
Managed-bean declaration: ProductBean必須在JSF的配置資源文件faces-managed-bean.xml中配置:

<managed-bean>
   <description>
      Backing bean that contains product information.
   </description>
   <managed-bean-name>productBean</managed-bean-name>
   <managed-bean-class>catalog.view.bean.ProductBean</managed-bean-class>
   <managed-bean-scope>request</managed-bean-scope>   
   <managed-property>
      <property-name>id</property-name>
      <value>#{param.productId}</value>
   </managed-property>
   <managed-property>
      <property-name>serviceLocator</property-name>
      <value>#{serviceLocatorBean}</value>
   </managed-property>
</managed-bean>
ProductBean有一個請求的范圍,這意味著如果ProductBean在JSP頁面內引用JSF執(zhí)行為每一個請求創(chuàng)建ProductBean實例的任務。被管理的ID屬性與productId這個請求參數組裝。JSF從請求得到參數,設置managed property。
Integration between presentation and business-logic tiers: ServiceLocator抽象了查詢服務的邏輯。在例子應用程序中,ServiceLocator被定義成一個一個接口。接口被JSF managed bean實現為ServiceLocatorBean,它從Spring application context查詢服務:
ServletContext context = FacesUtils.getServletContext();
this.appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
this.catalogService = (CatalogService)this.lookupService(CATALOG_SERVICE_BEAN_NAME);
this.userService = (UserService)this.lookupService(USER_SERVICE_BEAN_NAME);
ServiceLocator被定義為BaseBean中的一個屬性。JSF managed bean容易連接ServiceLocator執(zhí)行必須訪問ServiceLocator的那些managed beans。使用了Inversion of control(IOC,控制反轉)
業(yè)務邏輯層
定義業(yè)務對象,創(chuàng)建服務接口和實現,在Spring中配置這些對象組成了這一層的任務。
Business objects: 因為Hibernate提供了持久化,Product和Category業(yè)務對象需要為它們包含的所有屬性提供getter和setter方法。
Business services:CatalogService接口定義了所有與目錄管理有關的服務:

public interface CatalogService {
   public Product saveProduct(Product product) throws CatalogException;
   public void updateProduct(Product product) throws CatalogException;
   public void deleteProduct(Product product) throws CatalogException;
   public Product getProduct(String productId) throws CatalogException;
   public Category getCategory(String categoryId) throws CatalogException;
   public List getAllProducts() throws CatalogException;
   public List getAllCategories() throws CatalogException;
}
CachedCatalogServiceImpl服務的接口實現,它包含CatalogDao對象的一個setter。Spring將CachedCatalogServiceImpl 和CatalogDao連接在一起。因為我們提供了接口,所以對實現的依賴不是很緊密。
Spring configuration: 下面是CatalogService的Spring comfiguration:

<!-- Hibernate Transaction Manager Definition -->
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
   <property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>

<!-- Cached Catalog Service Definition -->
<bean id="catalogServiceTarget" class="catalog.model.service.impl.CachedCatalogServiceImpl" init-method="init">
   <property name="catalogDao"><ref local="catalogDao"/></property>
</bean>

<!-- Transactional proxy for the Catalog Service -->
<bean id="catalogService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
   <property name="transactionManager"><ref local="transactionManager"/></property>
   <property name="target"><ref local="catalogServiceTarget"/></property>
   <property name="transactionAttributes">
      <props>
         <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
       <prop key="save*">PROPAGATION_REQUIRED</prop>
       <prop key="update*">PROPAGATION_REQUIRED</prop>
       <prop key="delete*">PROPAGATION_REQUIRED</prop>
      </props>
   </property>
</bean>
Spring聲明事務管理是在CatalogService. CatalogService 里面設置,它能實現不同CatalogDao。Spring創(chuàng)建并管理單體實例Catalogservice,不需要工廠。
現在,業(yè)務邏輯層準備好了,讓我們將它與集成層整合。
Integration between Spring and Hibernate:下面是HibernateSessionFactory的配置:

<!-- Hibernate SessionFactory Definition -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
   <property name="mappingResources">
      <list>
         <value>catalog/model/businessobject/Product.hbm.xml</value>
         <value>catalog/model/businessobject/Category.hbm.xml</value>
         <value>catalog/model/businessobject/User.hbm.xml</value>
      </list>
   </property>
   <property name="hibernateProperties">
      <props>
         <prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
       <prop key="hibernate.show_sql">true</prop>
       <prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
       <prop key="hibernate.cache.provider_class">net.sf.hibernate.cache.HashtableCacheProvider</prop>
      </props>
   </property>
   <property name="dataSource">
      <ref bean="dataSource"/>
   </property>
</bean>
CatalogDao使用HibernateTemplate集成Hibernate和Spring.下面是HibernateTemplate的配置:

<!-- Hibernate Template Defintion -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate.HibernateTemplate">
   <property name="sessionFactory"><ref bean="sessionFactory"/></property>
   <property name="jdbcExceptionTranslator"><ref bean="jdbcExceptionTranslator"/></property>
</bean>
集成層
Hibernate使用一個XML配置文件去映射業(yè)務對象到關系型數據庫。在JCatalog項目中,Product.hbm.xml表示Product業(yè)務對象的映射。Category.hbm.xml用于業(yè)務對象Category。配置文件和相應的業(yè)務對象在同樣的目錄下。下面是Product.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
      "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
      "<hibernate-mapping package="catalog.model.businessobject">
   <class name="Product" table="product">
      <id name="id" column="ID" unsaved-value="null">
         <generator class="assigned"/>
      </id>
      <property name="name" column="NAME" unique="true" not-null="true"/>
      <property name="price" column="PRICE"/>    
      <property name="width" column="WIDTH"/>     
      <property name="height" column="height"/>     
      <property name="description" column="description"/>  
      <set name="categoryIds" table="product_category" cascade="all">
         <key column="PRODUCT_ID"/>
         <element column="CATEGORY_ID" type="string"/>
      </set>
   </class>
</hibernate-mapping>
CatalogDao通過Spring使用HibernateTemplate連接:
<!-- Catalog DAO Definition: Hibernate implementation -->
<bean id="catalogDao" class="catalog.model.dao.hibernate.CatalogDaoHibernateImpl">
   <property name="hibernateTemplate"><ref bean="hibernateTemplate"/></property>
</bean>
結論
這篇文章介紹了怎樣將JSF集成到Spring Framework和Hibernate,建立了一個真實的應用程序。這三種技術的聯合提供了一個可靠的Web應用程序開發(fā)框架。一個多層體系結構應該做為Web應用程序的高級體系結構。JSF很適合MVC設計模式,能夠被用于實現表示層。Spring框架能被用于業(yè)務邏輯層去管理業(yè)務對象,提供聲明性事務管理和資源管理。Spring與Hibernate結合的很好。Hibernate是一個強有力的O/R映射框架,能夠提供集成層的服務。
通過將Web應用程序劃分成不同的層和面向接口編程,每一層的技術可以被取代。例如, 在表示層Struts能取代JSF,在集成層JDO能取代Hibernate。應用程序層之間的整合不是沒有意義的,使用inversion of control和Service Locator設計模式能使這個工作容易。JSF提供了其他框架,如Struts所缺少的功能。然而,這不意味著你應該立刻拋棄Struts而開始使用JSF 。無論怎樣,你的項目是否使用JSF作為你的Web框架,取決于你項目的狀態(tài)和功能需求以及團隊專家的意見。

 

Resources

Download the JCatalog project sample application:
http://www.javaworld.com/javaworld/jw-07-2004/jsf/jw-0719-jsf.zip

Official JavaServer Faces site:
http://java.sun.com/j2ee/javaserverfaces/index.jsp

A good JSF tutorial can be found in The J2EE 1.4 Tutorial (Chapters 17 to 21):
http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html

More articles and books on JSF:
http://jsfcentral.com/reading/index.html

Official Spring Framework site:
http://www.springframework.org

Good introduction to the Spring Framework by Rod Johnson:
http://www.theserverside.com/articles/article.tss?l=SpringFramework

Rod Johnson‘s book Expert One-on-One J2EE Design and Development (Wrox, October 2002; ISBN: 0764543857) is the corner stone of the Spring Framework:
http://www.wrox.com/WileyCDA/WroxTitle/productCd-0764543857.html

Official Hibernate site:
http://www.hibernate.org

Online documentation of Hibernate:
http://www.hibernate.org/hib_docs/reference/en/html/

Introduction to the integration between the Spring Framework and Hibernate:
http://hibernate.bluemars.net/110.html

"Designing Enterprise Applications with the J2EE Platform, Second Edition" is a good introduction to the multitiered architecture and MVC design pattern:
http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/index.html

Commons BeanUtils:
http://jakarta.apache.org/commons/beanutils/

Commons FileUpload:
http://jakarta.apache.org/commons/fileupload/

For more on JavaServer Faces, read the following JavaWorld articles by David Geary:
"A First Look at JavaServer Faces, Part 1" (November 2002)
"A First Look at JavaServer Faces, Part 2" (December 2002)
"JavaServer Faces, Redux" (November 2003)
Browse the JavaServer Pages section of JavaWorld‘s Topical Index:
http://www.javaworld.com/channel_content/jw-jsp-index.shtml

Browse the Enterprise Java section of JavaWorld‘s Topical Index:
http://www.javaworld.com/channel_content/jw-enterprise-index.shtml

本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Huihoo.com - 利用JSF、SpringFramework和Hibernate構建Web應用的實例講述
利用JSF、SpringFramework和Hibernate構建Web應用的實例講述(4)
使用Spring框架的好處(轉帖)
Struts,Hibernate,Spring經典面試題 - xp1204的專欄 - CS...
Spring 學習一(了解Spring)
Java面試中常問的Spring方面問題(55道含答案)
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服