<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-9  評論-168  文章-266  trackbacks-0
            JSF是一種新的用于構架j2ee應用用戶界面的技術,它尤其適合于基于MVC架構的應用中。雖已有很多文章介紹過了JSF,然而它們大多從理論高度來介紹JSF而不是面向于實際應用。目前對于實際應用,JSF仍有很多問題沒有解決,例如:如何使JSF適應于MVC整體構架中?如何將JSF與其他Java 框架整合起來?是否應該將業務邏輯放置在JSF的backing beans中?如何處理JSF中的安全機制?更為重要的是如何利用JSF構架現實世界的Web應用?

           本文將涉及到上面的這些問題,它將演示如何將JSF、Spring和Hibernate整合在一起,構架出一個名為JCatalog的在線產品價目系統。利用該Demo,本文涵蓋了Web應用開發的每一個階段,包括需求收集、分析,技術選擇,系統架構和實現。本文討論了在JCatalog中涉及到的各種技術的優點和缺點并展示了一些關鍵部分的設計方法。

    本文的對象是從事基于J2ee的Web應用架構人員和開發人員,它并不是對JSF、SpringFramework和Hibernate的簡單介紹,如果對這些領域不甚了解,請參看相關資源。

    該范例的功能需求
    JCatalog是一個現實世界的Web應用,我首先描述JCatalog的需求,在通篇的技術決策和架構設計時都將涉及到本部分。

    在設計Web應用的第一階段是收集系統的功能需求,范例應用是一個典型的電子商務應用系統,用戶可以瀏覽產品的catalog并查看產品的詳細情況,而管理員可以管理產品的catalog。通過增加一些其他功能,如inventory管理和訂單處理等,該應用可成為一個成熟的電子商務系統。

    Use cases
    Use-case分析被用來展示范例應用的功能需求,圖1就是該應用的use-case圖。
        


    use-case圖用于表示系統中的actors以及可能進行的operations,在該應用中將有七個use-case,用戶能夠瀏覽產品 catalog和查看產品的詳細情況,一旦用戶登錄到系統中,她將成為管理員,從而可以創建新的產品,編輯已存在的產品或者刪除老的產品等。

    Business rules
    JCatalog必須符合以下business rules:
    • 每個產品必須具有唯一的ID
    • 每個產品必須屬于至少一個category
    • 產品ID一旦創立不得修改
    Assumptions
    我們在系統的設計和實現中做以下假定:
    • 英語講是缺省語言,且不需事先國際化
    • 在Catalog不講不會超過500個產品
    • catalog將不會被頻繁的修改
    Page flow
    圖2顯示了所有的JCatalog的pages以及它們之間的transitions關系:
        


    該應用中存在兩組pages:公開的internet和用于管理的intranet,其中intranet只能被那些成功登錄到系統的用戶訪問。 ProductSummary不作為一個單獨的page展示給用戶,它顯示在Catalog page中的frame中。ProductList只對管理員可視,它包含用于創建、編輯和刪除產品的鏈接。

    圖3是一個Catalog頁面的示意圖,理想狀況下,在需求文檔中應該包含每一頁的詳細示意圖。
            


    構架設計
    Web應用開發的下一個階段是構架設計,它包括將應用劃分為多個功能組件并將這些組件分割組合成層,高層的構架設計應該中立于所選用的特定技術。

    多層架構
    多層架構是將整個系統清晰的分為多個功能單元:client、presentation、business-logic、integration和 EIS,這將確保職責得到清晰的劃分,使得系統更易于維護和擴展。具有三層或等多層的系統被證明比C/S模型具有更好的伸縮性和靈活性。

    client層是使用和表示數據模型的地方,對于一個Web應用,client層通常是瀏覽器,基于瀏覽器的瘦客戶端不包含任何表示邏輯,它依賴于
    presentation層。

    presentation層將business-logic層的服務展示給用戶,它應知道如何處理用戶的請求,如何同business-logic層交互,并且知道如何選擇下一個視圖顯示給用戶。

    business-logic層包含應用的business objects和business services。它接受來在于presentation層的請求、基于請求處理業務邏輯。業務邏輯層組件將受益于系統級的服務,如安全管理、事務管理和資源管理等。

    integration層是介于
    business-logic層和EIS層之間的橋梁,它封裝了與EIS層交互的邏輯。有時,將integration層和business-logic層合稱為中間層。

    應用的數據被保存在EIS層中,它包括關系數據庫、面向對象數據庫和以及遺留系統等。

    JCatalog的構架設計
    圖4顯示了JCatalog的構架設計以及如何應用于多層構架系統中。
     


    該應用采用了多層非分布式的構架,圖4展示了系統的分層以及每一層中選擇的技術,它同時又是該范例的部署圖,它的presentation、 business-logic和integration層將存在于同一個web容器中。定義良好的接口將孤立每一層的職責,這一架構使得應用更為簡單和更好的伸縮性。

    對于presentation層,經驗表明,最好的方法是選擇已存在的并已得到證明了的Web應用框架,而不是自己去設計和開發新的框架。我們擁有多個可選擇的框架,如Struts,WebWork和JSF等,在JCatalog中,我們選擇采用JSF。

    EJB和POJO都可以用來創建業務邏輯層,如果應用是分布式的,采用具有remote接口的EJB是一個好的選擇;由于JCatalog是一個典型的不需要遠程訪問的Web應用,因此選用POJO,并充分利用Spring Framework的幫助,將是實現業務邏輯層的更好選擇。

    integration層利用關系型數據庫事先數據的持續化,存在多種方法可用來實現:
    • JDBC:這是最為靈活的方法,然而,低級的JDBC難以使用,而且質量差的JDBC代碼很難運轉良好
    • Entity beans:CMP的Entity bean是一種分離數據訪問代碼和處理ORM的昂貴的方法,它是以應用服務器為中心的方法,即entity bean不是將應用與某種數據庫類型而是EJB容器約束在一起。
    • O/R mapping framework:一個ORM框架采用以對象為中心的方法實現數據持續化,一個以對象為中心的應用易于開發并具有高度的可移植性。在該領域中存在幾個框架可用—JDO、Hibernate、TopLink以及CocoBase等。在我們的范例中將選用Hibernate。
    現在,我們將討論每一層中的設計問題,由于JSF是一個相對較新的技術,因此將著重于它的使用:

    presentation層和JSF
    表示層的功能是收集用戶的輸入、展示數據、控制頁面導航并將用戶的輸入傳遞給業務邏輯層,表示層同時需要驗證用戶的輸入以及維護應用的session狀態。在下面幾部分中,我將討論表示層設計時的考慮和模式,并說明選擇JSF作為JCatalog表示層的原因。

    MVC
    MVC是Java-Blueprints推薦的架構設計模式,MVC將幾個方面分離開來,從而減少代碼的重復,它以控制為中心并使得應用更具擴展性。MVC同時可幫助具有不同技能的用戶更關注于自己的技能,通過定義良好的接口進行相互合作。MVC是表示層的架構設計模式。

    JSF
    JSF是Web應用的服務器端用戶組件框架,它包含以下API:表示UI組件、管理它們的狀態、處理事件、服務器端驗證、數據轉換、定義頁面導航、支持國際化,并為這些特性提供擴展能力。它同時包括兩個JSP的tag庫以在JSP頁面中表示UI組件,以及將組件wire為服務器端對象。

    JSF和MVC
    JSF非常適合于基于MVC的表示層架構,它在行為和表示之間提供了清晰的分離,它使得你可以采用熟悉的UI組件和web層概念而無需受限于某種特殊的腳本技術或標記語言。

    JSF backing beans是JSF的Model層,此外,它同樣包含actions,action是controller層的擴展,用于將用戶的請求委派給業務邏輯層。這里請注意,從整體的應用構架看,業務邏輯層也被稱為model層。包含JSF標簽的JSP頁面是表示層,Faces Servlet提供了controller的功能。

    為什么選用JSF?

    JSF不僅僅是另外一個Web框架,下面這些特性是JSF區別于其他Web框架之所在:
    • 類Swing的面向對象的Web應用開發:服務器端有狀態的UI組件模型,配合event listeners和handlers,促進了面向對象的Web應用開發。
    • backing-bean管理: backing bean是與頁面中使用的UI組件相關聯的javabean組件,backing-bean管理將UI組件對象的定義同執行應用相關處理和擁有數據的對象分離開來。JSF在合適的范圍內保存和管理這些backing-bean實例。
    • 可擴展的UI模型:JSF的UI模型是可配置的、可重用的,用以構建JSF應用的用戶界面。你可以通過擴展標準的UI組件來開發出更為復雜的組件,例如菜單條、樹組件等。
    • 靈活的rendering模型:renderer分離了UI組件的功能和顯示,多個renderers可創建和用來為同一客戶端或不同的客戶端定義不同的顯示。
    • 可擴展的轉換和驗證模型:基于標準的converter和validator,你可以開發出自己的可提供更好的模型保護的converter和validator。
    盡管如此,JSF目前尚未成熟,隨同JSF發布的 components、converters和validators都是最基礎的,而且per-component驗證模型不能處理components 和validators間的many-to-many驗證。此外,JSF標簽不能與JSTL間無縫的整合在一起。

    在下面的章節中,我將討論幾個在JCatalog實現中的關鍵部分和設計決策。我首先解釋managed bean的定義和使用以及JSF中的backing bean,然后,我將說明如何處理安全、分頁、caching、file upload、驗證以及錯誤信息定制。

    Managed bean,backing bean,view object 和domain object model
    JSF中引入了兩個新的名詞:managed bean和backing bean。JSF提供了一個強大的managed-bean工具,由JSF來管理的JavaBean對象稱為managed-bean,一個 managed bean表述了一個bean如何被創建和管理,它不包含該bean的任何功能性描述。

    backing bean定義了與頁面中使用的UI組件相關聯的屬性和處理邏輯。每一個backing-bean屬性邦定于一個組件實例或某實例的value。一個 backing-bean同時定義了一組執行組件功能的方法,例如驗證組件的數據、處理組件觸發的事件、實施與組件相關的導航等。

    一個典型的JSF應用將其中的每個頁面和一個backing-bean結合起來,然而在現實應用中,強制的執行這種one-on-one的關系不是一種理想的解決方案,它可能會導致代碼重復等問題。在現實的應用中,多個頁面可以共享一個backing-bean,例如在JCatalog中, CreateProduct和EditProduct將共享同一個ProductBean定義。

    model對象特定于表示層中的一個view對象,它包含必須顯示在view層的數據以及驗證用戶輸入、處理事件和與業務邏輯層交互的處理邏輯等。在基于 JSF的應用中backing bean就是view對象,在本文中backing bean和view對象是可互換的名詞。

    對比于struts中的ActionForm和Action,利用JSF中的backing-bean進行開發將能更好的遵循面向對象方法,一個 backing-bean不僅包含view數據,而且還包含與這些數據相關的行為,而在struts中,Action和ActionForm分別包含數據和邏輯。

    我們都應該聽說過domain object model,那么,domain object model和view對象之間有什么區別呢?在一個簡單的Web應用中,一個domain object model能夠橫穿所有層中,而在復雜的應用中,需要用到一個單獨的view對象模型。domain object model應該屬于業務邏輯層,它包含業務數據和與特定業務對象相關的業務邏輯;一個view對象包含presentation-specific的數據和邏輯。將view對象從domain object model中分離出來的缺點是在這兩個對象模型之間必將出現數據映射。在JCatalog中,ProductBeanBuilder和 UserBeanBuilder利用reflection-based Commons BeanUtils來實現數據映射。

    安全
    目前,JSF沒有內建的安全特性,而對于范例應用來說安全需求是非常基礎的:用戶登錄到administration intranet中僅需用戶名和密碼認證,而無需考慮授權。
    針對于JSF的認證,已有幾種方法提出:
    • 利用一個backing bean:這一個方法非常簡單,然而它卻將backing bean與特殊的繼承關系結合起來了
    • 利用JSF的ViewHandler decorator:這一方法中,安全邏輯緊密地與一特定Web層技術聯系在了一起
    • 利用servlet filter:一個JSF應用與其他的Web應用沒有什么兩樣,filter仍是處理認證檢查的最好地方,這種方法中,認證邏輯與Web應用分離開來
    在我們的范例程序中,SecurityFilter類被用來處理用戶的認證,目前,受保護的資源只包含三個頁面,出于簡單的考慮,將它們的位置被硬編碼到Filter類中。

    分頁
    該應用中的Catalog頁面需要分頁,表示層可用來處理分頁,即它取出所有的數據并保存在這一層;分頁同樣可在business-logic層、 integration層、甚至EIS層中實現。由于在JCatalog中假設不超過500個產品,因此所有的產品信息能存放在一個user session中,我們將分頁邏輯放在了ProductListBean中,與分頁相關的參數將通過JSF managed-bean工具配置。

    Caching
    Caching是提高Web應用性能的最重要技術之一,在應用構建中的很多層中都可以實現caching。JSF managed-bean工具可以使在表示層實現caching非常容易。通過改變一個managed bean的范圍,這個managed bean中包含的數據可以在不同的范圍內緩存。

    范例應用中采用了兩級caching,第一級caching存在于業務邏輯層,CachedCatalogServiceImpl類維護了一個所有產品和目錄的讀寫cache,Spring將該類作為一個singleton service bean來管理,所以,一級cache是一個應用范圍的讀寫cache。

    為了簡化分頁邏輯并進而提高應用的速度,產品同樣在session范圍內緩存到表示層,每一個用戶維護著他自己的ProductListBean,這一方法的缺點是內存的消耗和數據的失效問題,在一個用戶session中,如果管理員更改了catalog,用戶可到的將是失效的數據,然而,由于我們假設應用的數據不會經常的改變,所以這些缺點將能夠忍受。

    File upload
    目前的JSF Sun參考實現中不支持file upload。Struts雖已具有非常不錯的file upload能力,然而要想使用這一特性需要Struts-Faces整合庫。在JCatalog中,一個圖像與一個產品相關聯,在一個用戶創建了新的產品后,她必須將相應的圖片上傳,圖片將保存在應用服務器的文件系統里,產品的ID就是圖像名稱。

    范例應用中采用 <input type="file">Servlet和Jakarta Common的file-upload API來實現簡單的文件上傳功能,該方法包含兩個參數:圖像路徑和圖像上傳結果頁面。它們將通過ApplicationBean來配置,詳細內容請參看 FileUploadServlet類。

    Validation
    JSF中發布的標準validator是非常基礎的,無法滿足現實的需要,但很容易開發出自己的JSF validator,在范例中,我開發了SelectedItemsRange validator,它用來驗證UISelectMany組件中選擇的數量:

     
    <h:selectManyListbox value="#{productBean.selectedCategoryIds}" id="selectedCategoryIds">
       
    <catalog:validateSelectedItemsRange minNum="1"/>
       
    <f:selectItems value="#{applicationBean.categorySelectItems}" id="categories"/>
    </h:selectManyListbox>

         
         
     


    詳細情況請參看范例。

    定制錯誤信息
    在JSF中,你可以為converters和validators創建resource bundle和定制錯誤信息,一個resource bundle可在faces-config.xml中創建:

     
    <message-bundle>catalog.view.bundle.Messages</message-bundle>


    并將錯誤信息的key-value對加到Message.properties文件中:

    #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.

    業務邏輯層和Spring Framework
    業務對象和業務服務存在于業務邏輯層中,一個業務對象不僅包含數據,而且包含相應的邏輯,在范例應用中包含三個業務對象:Product、Category和User。

    業務服務與業務對象交互并提供更高級的業務邏輯,需要首先定義一個正式的業務接口,它是直接與終端用戶交互的服務接口。在JCatalog中,通過在 Spring Framework幫助下的POJO實現業務邏輯層,其中共有兩個業務服務:CatalogService包含Catalog管理相關的業務邏輯, UserService中包含User管理邏輯。

    Spring是基于IoC概念的框架,在范例應用中用到的Spring特性包括:
    • Bean management with application contexts:Spring可以有效地組織我們的中間層對象,它能夠消除singleton的proliferation,并易于實現良好的面向對象編程方法,即“編程到接口”。
    • Declarative Transaction management: Spring利用AOP實現事務管理,而無需借助于EJB容器,利用這種方法,事務管理可以用于任何POJO中。Spring的事務管理不局限于JTA,而是可以采用不同的事務策略,在范例應用中,我們將使用declarative transaction management with Hibernate transaction。
    • Data-access exception hierarchy:Spring提供了非常好的異常來代替SQLException,為利用Spring的異常,必須在Spring的配置文件中定義以下異常轉換:
            
             
    <bean id="jdbcExceptionTranslator" class= "org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator"> 
       
    <property name="dataSource">
          
    <ref bean="dataSource"/>
       
    </property> 
    </bean>

                  
              

            


            在范例應用中,如果一個具有重復ID的新產品被插入,將會拋出DataIntegrityViolationException,這一異常將被
            catch并rethrown一個DuplicateProductIdException。這樣,該異常就可以與其它的異常區別處理。
    • Hibernate integration:Spring與Hibernate這樣的ORM框架整合的非常好,Spring提供了對Hibernate session的高效和安全的處理,它可通過application context配置Hibernate的SessionFactories和JDBC數據源,并使得應用易于測試。

    Integration層和Hibernate
    Hibernate是一個開源的ORM框架,它可以支持所有主流SQL數據庫系統,Hibernate的查詢語言為對象和關系架起了非常好的橋梁。Hibernate提供了強大的功能以實現:數據讀取和更新、事務管理、數據連接池、查詢和實體關系管理等。

    Data Access Ojbect(DAO)
    JCatalog中采用了Dao模式,該模式抽象和封裝了所有對數據源的訪問,該應用中包括兩個DAO接口:CatalogDao和UserDao,它們相應的實現HibernateCatalogDaoImpl和HibernateUserDAoImpl包含了Hibernate特定的邏輯來實現數據的管理和持久化。

    實現
    現在我們來看看如何將上面討論的這些東西包裝在一起以實現JCatalog,你可以從這個地址下載源碼:source code

    數據庫設計
    我們為該范例應用創建了包含4個表的數據庫,如圖5所示:


    類設計
    圖6顯示了JCatalog的類圖


    “編程到接口”的思想貫穿了整個設計實現中,在表示層,共用到四個backing bean:ProductBean、ProductListBean、UserBean和MessageBean;業務邏輯層包含兩個業務服務 (CatalogService和UserService)和三個業務對象(Product、Category和User);Integration層有兩個Dao接口和它們相應的Hibernate實現,Spring的application context用來管理絕大多數的業務邏輯層和integration層的對象;ServiceLocator將JSF和業務邏輯層整合在了一起。

    Wire everything up
    由于篇幅所限,我們僅舉例說明,范例中use case CreateProduct展示了如何裝配和構建應用,在詳細講述細節前,我們利用sequence圖(圖7)來說明所有層的end-tp-end整合。



    表示層
    表示層實現包括創建JSP頁面、定義頁導航、創建和配置backing bean以及將JSF與業務邏輯層整合。
    • JSP page:createProduct.jsp是用來創建新產品的頁面,它包含UI組件并將組件打包成ProductBean,ValidateItemsRange標簽用來驗證用戶選擇的種類數量,對每一個產品至少要有一個種類被選中。
    • 頁面導航:應用中的導航被定義在應用的配置文件faces-navigation.xml中,CreateProduct的導航準則如下:

     
    <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組件的屬性,還包括三個action: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;
    }

    • Managed-bean聲明: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>


    •  表示層和業務邏輯層之間的整合: 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);

    業務邏輯層
    • 業務對象:由于采用Hibernate提供持久化,因此Product和Category兩個業務對象需要為它們的所有field提供getter和setter。
    • 業務服務:CatalogService接口中定義了所有的與Catalog management相關的服務:
    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;
    }
    • Spring Configuration:這里是CatalogService的Spring配置:


      <!-- 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和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>
    Integration層
    Hibernate通過xml配置文件來映射業務對象和關系數據庫,在JCatalog中,Product.hbm.xml表示了Product對象的映射,Category.hbm.xml則用來表示Category的映射,Product.hbm.xml如下:
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
          
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
          
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
    <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  is wired with HibernateTemplate by Spring:  
             
             
    <!-- Catalog DAO Definition: Hibernate implementation -->
    <bean id="catalogDao" class="catalog.model.dao.hibernate.CatalogDaoHibernateImpl">
       
    <property name="hibernateTemplate"><ref bean="hibernateTemplate"/></property> 
    </bean>   

          
      


    結論
    本文主要講述了如何將JSF與Spring、Hibernate整合在一起來構建實際的Web應用,這三種技術的組合提供了一個強大的Web應用開發框架。在Web應用的高層設計中應該采用多層構架體系,JSF非常適合MVC設計模式以實現表示層,Spring可用在業務邏輯層中管理業務對象,并提供事物管理和資源管理等,Spring與Hibernate結合的非常出色,Hibernate是強大的O/R映射框架,它可以在integration層中提供最好的服務。

    通過將整個Web應用分割成多層,并借助于“編程到接口”,應用程序的每一層所采用的技術都是可替換的,例如Struts可以用來替換JSF,JDO可替換Hibernate。各層之間的整合不是不值得研究,采用IoC和ServiceLocator設計模式可使得整合非常容易。JSF提供了其它Web框架欠缺的功能,然而,這并不意味著你馬上拋棄Struts而開始使用JSF,是否采用JSF取決于項目目前的狀況和功能需求,以及開發團隊的意見等。


                                               ----------------[原作者] Derek Yang Shen
                                                          [原文鏈接] http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html
                                                          [源碼鏈接] http://www.javaworld.com/javaworld/jw-07-2004/jsf/jw-0719-jsf.zip
    posted on 2007-11-06 11:00 紫蝶∏飛揚↗ 閱讀(716) 評論(0)  編輯  收藏 所屬分類: Spring
    主站蜘蛛池模板: 67194国产精品免费观看| 久久精品国产亚洲av高清漫画| 2019中文字幕在线电影免费| 特级av毛片免费观看| 456亚洲人成影院在线观| 亚洲日本一区二区三区| 亚洲人JIZZ日本人| 免费中文字幕在线| 免费羞羞视频网站| 亚洲人成网站免费播放| 亚洲美女视频免费| 中文字幕免费不卡二区| 好猛好深好爽好硬免费视频| 精品亚洲福利一区二区| 中文有码亚洲制服av片| 亚洲码在线中文在线观看| 亚洲成人在线网站| 亚洲大尺度无码专区尤物| 亚洲AV无码专区日韩| 国产性生交xxxxx免费| 大学生美女毛片免费视频| 永久免费AV无码国产网站| 综合在线免费视频| av无码免费一区二区三区| 120秒男女动态视频免费| 99精品视频在线观看免费专区| 国产午夜免费高清久久影院| 国产伦精品一区二区免费| 国产国产人免费人成成免视频| 老司机午夜在线视频免费| 看免费毛片天天看| 免费福利资源站在线视频| 国产精品亚洲va在线观看| 在线精品自拍亚洲第一区| 日韩亚洲翔田千里在线| 国产产在线精品亚洲AAVV| 老湿机一区午夜精品免费福利| 无人视频在线观看免费播放影院| 欧亚一级毛片免费看| 一区在线免费观看| 99久久国产精品免费一区二区|