File upload
目前的JSF Sun參考實現(xiàn)中不支持file upload。Struts雖已具有非常不錯的file upload能力,然而要想使用這一特性需要Struts-Faces整合庫。在JCatalog中,一個圖像與一個產(chǎn)品相關(guān)聯(lián),在一個用戶創(chuàng)建了新的產(chǎn)品后,她必須將相應(yīng)的圖片上傳,圖片將保存在應(yīng)用服務(wù)器的文件系統(tǒng)里,產(chǎn)品的ID就是圖像名稱。
范例應(yīng)用中采用 、Servlet和Jakarta Common的file-upload API來實現(xiàn)簡單的文件上傳功能,該方法包含兩個參數(shù):圖像路徑和圖像上傳結(jié)果頁面。它們將通過ApplicationBean來配置,詳細內(nèi)容請參看FileUploadServlet類。
Validation
JSF中發(fā)布的標(biāo)準(zhǔn)validator是非?;A(chǔ)的,無法滿足現(xiàn)實的需要,但很容易開發(fā)出自己的JSF validator,在范例中,我開發(fā)了SelectedItemsRange validator,它用來驗證UISelectMany組件中選擇的數(shù)量:詳細情況請參看范例。
定制錯誤信息
在JSF中,你可以為converters和validators創(chuàng)建resource bundle和定制錯誤信息,一個resource bundle可在faces-config.xml中創(chuàng)建:
catalog.view.bundle.Messages
并將錯誤信息的key-value對加到Message.properties文件中:
javax.faces.component.UIInput.CONVERSION=Input data is not in the correct type.
javax.faces.component.UIInput.REQUIRED=Required value is missing.
業(yè)務(wù)邏輯層和Spring Framework
業(yè)務(wù)對象和業(yè)務(wù)服務(wù)存在于業(yè)務(wù)邏輯層中,一個業(yè)務(wù)對象不僅包含數(shù)據(jù),而且包含相應(yīng)的邏輯,在范例應(yīng)用中包含三個業(yè)務(wù)對象:Product、Category和User。
業(yè)務(wù)服務(wù)與業(yè)務(wù)對象交互并提供更高級的業(yè)務(wù)邏輯,需要首先定義一個正式的業(yè)務(wù)接口,它是直接與終端用戶交互的服務(wù)接口。在JCatalog中,通過在 Spring Framework幫助下的POJO實現(xiàn)業(yè)務(wù)邏輯層,其中共有兩個業(yè)務(wù)服務(wù):CatalogService包含Catalog管理相關(guān)的業(yè)務(wù)邏輯, UserService中包含User管理邏輯。
Spring是基于IoC概念的框架,在范例應(yīng)用中用到的Spring特性包括:
◆Bean management with application contexts:Spring可以有效地組織我們的中間層對象,它能夠消除singleton的proliferation,并易于實現(xiàn)良好的面向?qū)ο缶幊谭椒?,?#8220;編程到接口”。
◆Declarative Transaction management: Spring利用AOP實現(xiàn)事務(wù)管理,而無需借助于EJB容器,利用這種方法,事務(wù)管理可以用于任何POJO中。Spring的事務(wù)管理不局限于JTA,而是可以采用不同的事務(wù)策略,在范例應(yīng)用中,我們將使用declarative transaction management with Hibernate transaction。
◆Data-access exception hierarchy:Spring提供了非常好的異常來代替SQLException,為利用Spring的異常,必須在Spring的配置文件中定義以下異常轉(zhuǎn)換:
在范例應(yīng)用中,如果一個具有重復(fù)ID的新產(chǎn)品被插入,將會拋出DataIntegrityViolationException,這一異常將被catch并rethrown一個DuplicateProductIdException。這樣,該異常就可以與其它的異常區(qū)別處理。
◆Hibernate integration:Spring與Hibernate這樣的ORM框架整合的非常好,Spring提供了對Hibernate session的高效和安全的處理,它可通過application context配置Hibernate的SessionFactories和JDBC數(shù)據(jù)源,并使得應(yīng)用易于測試。
Integration層和Hibernate
Hibernate是一個開源的ORM框架,它可以支持所有主流SQL數(shù)據(jù)庫系統(tǒng),Hibernate的查詢語言為對象和關(guān)系架起了非常好的橋梁。Hibernate提供了強大的功能以實現(xiàn):數(shù)據(jù)讀取和更新、事務(wù)管理、數(shù)據(jù)連接池、查詢和實體關(guān)系管理等。
Data Access Ojbect(DAO)
JCatalog中采用了Dao模式,該模式抽象和封裝了所有對數(shù)據(jù)源的訪問,該應(yīng)用中包括兩個DAO接口:CatalogDao和UserDao,它們相應(yīng)的實現(xiàn)HibernateCatalogDaoImpl和HibernateUserDAoImpl包含了Hibernate特定的邏輯來實現(xiàn)數(shù)據(jù)的管理和持久化。
實現(xiàn)
現(xiàn)在我們來看看如何將上面討論的這些東西包裝在一起以實現(xiàn)JCatalog,你可以從這個地址下載源碼:
http://www.javaworld.com/javaworld/jw-07-2004/jsf/jw-0719-jsf.zip數(shù)據(jù)庫設(shè)計
我們?yōu)樵摲独龖?yīng)用創(chuàng)建了包含4個表的數(shù)據(jù)庫,如圖5所示:
類設(shè)計
圖6顯示了JCatalog的類圖
“編程到接口”的思想貫穿了整個設(shè)計實現(xiàn)中,在表示層,共用到四個backing bean:ProductBean、roductListBean、UserBean和MessageBean;業(yè)務(wù)邏輯層包含兩個業(yè)務(wù)服務(wù) (CatalogService和UserService)和三個業(yè)務(wù)對象(Product、Category和User);Integration層有兩個Dao接口和它們相應(yīng)的Hibernate實現(xiàn),Spring的application context用來管理絕大多數(shù)的業(yè)務(wù)邏輯層和integration層的對象;ServiceLocator將JSF和業(yè)務(wù)邏輯層整合在了一起。