|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
什么时候上述的三种开发工具能和三为一,什么时候java的竞争力才更强,才有机会拉拢更多的程序员投入到对java的开发上,因为到时的开发工具将会比.net的更简单。还有一点也很关键,什么时候java推出的jsf能成为真正意义上的标准。js利用JavaServerFaces(JSF)、SpringFramework和Hibernate创建一个实在的Web使用程序
内容提要
利用JSF创建一个实在的Web使用程序不是没成心义的义务,这篇文章先容了怎样将JSF与SpingFramework和Hibernate集成,而且给出了利用这些手艺创建这个实在的Web使用程序的最好理论和计划引导
JavaServerFaces(JSF)手艺是J2EE使用程序的一个新的用户接口框架,它十分合适基于MVC(Model-View-Controller)系统布局的使用程序。已有大批的文章先容JSF。但是,良多文章都是站在实际研讨的层面上,没有应战一个实在的企业开辟。良多成绩没有办理,比方,JSF如何周全合适MVC系统布局?JSF怎样与其他JAVA框架集成?营业逻辑应当放在JSF的backingbeans内里吗?如何处置JSF内里的平安成绩?最主要的是你如何利用JSF创建一个实在的Web使用程序?
这篇文章触及一切这些成绩。它向你展现怎样集成其他特定的Java框架,SpringFramework和Hibernate,它树模如何往创立一个叫JCatalog的Web使用程序,一个在线的产物目次体系。这篇文章利用JCatalog例子,先容了Web使用程序计划的每个阶段,包含营业需求搜集,剖析,手艺选择,高层系统布局和具体计划。这篇文章叙述了JCatalog内里好的和欠好的手艺,树模了使用程序计划中一些关头方面的办法和步骤。
这篇文章是写给正在处置基于J2EEWeb使用程序的Java架构师,开辟者,它不是对JSF、SpringFramework和Hibernate的进门教程。假如您对这些范畴不熟习,请参考文章最初的资本链接。
例子使用程序的功效需求
这篇文章的例子使用程序JCatalog是一个实在的Web使用程序,例子充足实际是为了决意使用程序架构而举行语重心长的会商的基本。我经由过程先容JCatalog项目标需求入手下手。我在这里谈到前面贯串于全部文章的内容是为了演示手艺选择和系统布局计划。
计划Web使用程序的第一步是搜集体系的功效需求,这个例子使用程序是一个典范的电子商务使用体系。用户能扫瞄产物目次和检察产物细节,办理员能办理产物目次。功效还能够增添,举例来讲,为了开辟一个成熟的电子商务体系,能够增加库存办理和定单处置的功效。
用例
用例剖析被用于往会见例子使用程序的功效需求,是使用程序的用例图。
用例图
一个用例图断定在一个体系中的介入者和介入者能够实行的操纵。例子使用中7个用例必需被完成。介入者中的User能扫瞄产物目次和观察产物细节。一旦用户以Administrator身份毗连到体系,他就可以创立新产物,编纂存在的产物,删除老的产物。
营业划定规矩
JCatalog必需切合上面的营业划定规矩:
每一个产物有一个独一的产物ID
每一个产物最少属于一个目次
产物ID一旦被创立就不克不及改动
假定
关于产物的计划和完成,我们做上面的假定。
英语是默许言语;不请求国际化
目次中不凌驾500种产物
目次的更新不频仍
页面流
显现了一切JCatalog的页面和它们之间的转换。
页面流图
使用程序有两组页面:大众的国际互联网和办理员的企业外部网。企业外部网只要对那些乐成上岸到体系的用户无效。产物提要页面是公用的,它作为产物目次的内容包括在一个HTML框架内里。产物列表是一个特别的目次,只能被办理员瞥见,它包括创立、编纂和删除产物的链接。
是目次页的一个模子。幻想情形下,每个页面一切的把持和需要的内容明细的模子应当被包括在需求文档内里。
目次页面模子
初级系统布局计划
下一步的计划是Web使用程序的初级系统布局计划,它包含将使用程序细分红功效组件和将这些组件分别到各自所属的层。初级系统布局计划自力于利用的手艺。
多层系统布局
一个多层系统布局将全部体系分别成明晰的单位――客户端、暗示层、营业逻辑层、集成层和企业信息体系(EIS),这包管了明晰的义务分别和可保护性和可扩大性。三层或多层体系已被证实比没有营业逻辑层的客户-服务器体系具有更多的可晋级性和柔韧性。
客户端是数据模子被消耗和出现的中央。关于一个Web使用程序,客户层一般是Web扫瞄器。基于扫瞄器的瘦客户不包括暗示逻辑;它依附于暗示层。
暗示层利用营业逻辑层为用户服务,它晓得如何去向理一个客户哀求,如何往和营业逻辑层分离和如何往选择下一个试图往显现。
营业逻辑层包括一个使用程序的营业对象和营业服务。它从暗示层承受哀求,基于哀求处置营业逻辑,作为会见EIS层资本的的中介。营业逻辑层组件利用很多体系级其余服务,比方,平安办理、事物办理和资本办理。
集成层是营业逻辑层和EIS层之间的桥梁。它封装了与EIS层相分离的逻辑。偶然,集成层和营业逻辑层的分离是作为两头层被提到。
使用程序数据在EIS层被耐久化,包含干系数据库,面向对象数据库和遗留体系。
JCatalog的系统布局计划
显现了JCatalog的初级系统布局计划和它如何合适多层系统布局。
初级系统布局图
使用程序利用了一个多层的非散布式的系统布局,显现使用程序层和每层手艺选择的分别。它也用于使用程序的部署图。关于一个可设置的系统布局,暗示层、营业逻辑层和集成层被定位在一样的Web容器。界说优秀的接口断绝了每层的职责。可设置的系统布局使使用程序复杂和可晋级。
关于暗示层,履历告知我们,最好的理论是选择一个存在的,被考证的Web使用框架,远比计划开辟一个定制的框架好。我们有几个Web使用框架可供选择,举例来讲,Struts、WebWork和JSF。关于JCatalog项目,我们利用JSF。
关于营业逻辑层,不是利用EJB(EnterpriseJavaBeans)就是利用POJO(plainoldJavaobjects)。假如使用程序是散布式的,EJB具有远程接口是一个较好的选择。由于JCatalog是一个典范的没有远程会见哀求的Web使用程序,POJO在Spring框架的匡助下,用于完成营业逻辑层。
PureJDBC(JavaDatabaseConnectivity):这是最天真的完成办法;但是,初级的JDBC和欠好的JDBC代码事情是贫苦的,实行的欠好。
Entitybeans:一个容器办理耐久化(CMP,container-managedpersistence)的entitybean是断绝数据会见代码和处置O/R(object-relational)mapping数据耐久化的高贵的办法。它是一个以使用服务器为中央的办理举措。一个entitybean反面特定的数据库紧耦合,可是使用程序和EJB容器进耦合。
O/Rmappingframework:一个O/R暗射的框架接纳以对象为中央的办法完成数据耐久化。一个以对象为中央的使用程序是简单开辟和高度笨重的。在这个范畴内存在几个框架――JDO(JavaDataObjects),Hibernate,Toplink。CocoBase是一个新的例子。在例子使用程序中我们利用HIbernate。
如今,让我们会商将使用程序的每个层团结起来计划的成绩。由于JSF绝对来讲是一个新手艺,我夸大一下它的利用。
体现层和JavaServerFaces(JSF)
体现层搜集用户输出,出现数据,把持页面导航,取代用户与营业逻辑层交互。体现层也能校验用户输出,保护使用程序的会话形态。上面的章节,我会商体现层的计划思索和形式和我选择JSF往完成JCatalog项目标体现层的缘故原由。
MOdel-View-Controller(MVC)
MVC是Java蓝皮书(BluePrints)中保举的交互式使用程序系统布局计划形式。MVC分离计划存眷的成绩,因而削减了代码的反复,会合把持,使使用程序更具扩大性。MVC也匡助开辟者利用分歧的手艺汇合,会合他们中心的手艺,经由过程界说明晰的接口举行互助。MVC是体现层的系统布局计划形式。
JavaServerFace
JSF是一个基于Java的Web使用程序服务真个用户接口组件框架。JSF包含暗示UI组件和办理其形态的API;处置事务,服务端校验,数据转换;界说页面导航;撑持国际化和可会见性;供应一切这些特性的扩大才能。它还包含两个为JSP定制的标签库,一个用于暗示JSP页面内的UI组件,一个用于设置服务真个对象组件。
JSF和MVC
JSF很合适基于MVC的体现层系统布局。它供应举措和体现之间分明地分别。它影响了UI组件和Web层观点,不限制你往利用特定的剧本手艺大概标志言语。
JSFbackingbeans是model层(前面的章节有关于backingbeans的更多内容)。它们也包括举措,这是把持层的扩大,代办署理用户对营业逻辑层的哀求。请注重,从全体使用程序的系统布局来看,营业逻辑层也能被作为Model层提到。利用JSF定制标签的JSP页面是视图层。FacesServlet供应把持者的功效。
为何用JSF
JSF不单单只是另外一个Web框架,上面是JSF与其他Web框架分歧的特性:
象Swing一样面向对象的Web使用程序开辟:服务端有形态的UI组件模子,具有事务监听和操纵者,入手下手了面向对象Web使用程序开辟。
Backing-bean办理:Backingbeans是页面中JavaBeans组件和UI组件的团结。Backing-bean办理UI组件对象界说和对象实行使用程序特别历程和把持数据的分别。JSF在准确的局限内实行存储和办理这些backing-bean实例。
可扩大的UI组件模子:JSFUI组件是构成JSF使用程序用户接口可设置、可复用的元素。你能扩大尺度的UI组件和开辟更多的庞大组件。举例来讲,菜单条和树型构件。
天真的体现模子:一个renderer分开一个UI组件的功效和视图。多个renderer能被创立,用于界说不异或分歧客户端上一样组件的分歧表面。
可扩大的转化和校验模子:基于尺度的转换者和校验者,你能开辟定制的转换者和校验者,它们供应最好的模子回护。
只管JSF很壮大,可是如今还不成熟。组件、转换者和校验者是JSF基础的。每个校验模子不克不及处置组件和校验者之间多对多的校验。别的,JSF定制标签不克不及和JSTL(JSPStandardTagLibrary)无缝分离。
鄙人面的部分,我会商用JSF完成JCatalog项目时几个关头方面和计划决意。起首会商JSF中managedbeans和backingbeans的界说和利用。然后,我先容JSF中如何处置平安、分页、缓存、文件上传、校验和毛病动静定制。
Managedbean,backingbean,viewobject和domainobjectmodel
JSF先容了两个新的术语:managedbean和backingbean。JSF供应一个壮大的managed-bean工场。被JSF实行的JavaBean对象办理被叫做managedbeans。一个managedbean形貌一个bean如何被创立和办理。它没有益用bean的功效性。
Backingbean界说页面特征和处置逻辑与UI组件的团结。每个backing-bean属性被绑定到组件实例大概它的值中的一个。一个backingbean也界说一个组件可实行的功效的汇合,比方,校验组件的数据,处置组件触发事务,组件激活时与导航相干的实行历程。
一个典范的JSF使用程序在使用程序的每个页面中毗连一个backingbean。但是,偶然在实在的天下里,强制一个backingbean和一个页面一对一的干系不是一个幻想的办理计划。它能形成象代码反复如许的成绩。在实在天下的场景里,几个页面大概必要共享在背景的一样的backingbean。比方,在JCatalog项目里,CreateProduct和EditProduct页面共享一样的ProductBean的界说。
一个试图对象是在暗示层明白利用的模子对象。它包括了必需显现在视图层的数据和校验用户输出,处置事务和与营业逻辑层相分离的逻辑。backingbean是基于JSF使用程序的视图对象。
在这篇文章中Backingbean和视图对象是可互换的术语。
对照Struts中的Actionform和Action,在JSF中开辟backingbeans遵守面向对象计划的最好理论。一个backingbean不但包括视图数据,也包括与数据相干的举动。在Struts中,Action和ActionForm包括数据和逻辑分别。
我们都传闻过域对象模子。那末,域对象模子和视图对象有甚么分歧呢?在一个复杂的Web使用程序里,一个域对象模子能被用于一切的层,但是,在一些庞大的Web使用程序内里,一个独自的视图对象模子必要被利用。域对象模子是关于营业对象,应当回进营业逻辑层。它包括特定营业对象相干的营业数据和营业逻辑。一个视图对象包括特定命据和举动的暗示。JCatalog项目标ProductListBean供应了一个好的例子。它包括暗示层数据和逻辑细节,举例来讲,与分页相干的数据和逻辑。从域对象模子分别视图对象的弱点是数据映照必需产生在两个对象模子之间。在JCatalog项目中,ProductBeanBuilder和UserBeanBuilder利用基于反射的CommonsBeanUtils往完成数据映照。
平安
以后,JSF没有内置的平安特性。例子的平安需求是基础的:用户毗连到办理员利用的公司外部网必要的认证是基于用户名和暗码,不必要受权。
在JSF内里几个处置用户认证的办法已被提出:
Useabasebackingbean:这个办理方案是复杂的。但是,它使backingbeans与特别的遗产条理绑定。
UseJSFViewHandlerdecorator:这类办法使平安逻辑牢牢地加上一个特别的Web层手艺。
Useaservletfilter:一个JSF使用程序与其他基于Java的Web使用程序分歧。它在一个得当的中央利用一个过滤器处置认证反省。这类办法使Web使用程序中的认证逻辑削弱了。
在例子使用程序中,SecurityFilter类处置用户认证。以后,受回护的资本只要三个页面,为了复杂,它们被硬编码在Filter类内里。能够经由过程扩大平安划定规矩来改善它,把受回护的资本放到设置文件中。
分页
使用程序的目次页必要分页。体现层能处置分页,这意味着一切数据必需被从头失掉存储在这层。分页也能在营业逻辑层、集成层乃至是EIS层处置。JCatalog项目标假定是在目次中的产物不凌驾500种。一切产物信息合适保留在用户session中。分页逻辑存在ProductListBean类中。与分页有关的参数“每页的产物”经由过程JSF的managed-bean工具设置。
缓存
缓存是Web使用程序中改良功能的浩瀚主要手艺中的一种。缓存能在使用程序系统布局内的很多层完成。系统布局中的一层削减挪用它上面的层时,缓存长短常无益的。JSFmanaged-bean工具使在体现层完成缓存更简单。经由过程改动一个managedbean的局限,包括在managedbean中的数据能在分歧的局限内缓存。
例子使用程序利用二级缓存。第一级缓存在营业逻辑层内里。CachedCatalogServiceImpl类保护一切产物和目次的读/写缓存。Spring办理的类作为一个独自服务bean。以是,一级缓存是一个使用程序局限的读/写缓存。
关于复杂的分页逻辑和未来使用程序速率的进步,体现层的会话局限内的产物也被缓存。每一个用户保护他session内里本人的ProductListBean。弱点是占用体系内存和存在旧数据。在一个用户session的延续工夫里,假如办理员更新了目次,用户大概会看到旧的目次数据。但是,基于如许的假定,目次中部凌驾500种产物,并且目次更新不频仍,我们应当可以忍耐这些弱点。
文件上传
今朝,JSF的Sun参考完成中不撑持文件上传。Struts有很好的文件上传才能,但是,Struts表面集成库是必需利用。在JCatalog项目中,一个图片与每一个产物联系关系。一个用户创立一个新的产物以后,必需上传与之相干的图片。图片保留在使用服务器的文件体系内里。产物ID是图片名.
例子使用程序利用<inputtype="file">,Servlet和Jakarta通用的文件上传API,完成一个复杂的文件长传功效。这个功效利用两个参数:产物图片路径和图片上传了局页面。它们都经由过程ApplicatonBean设置。请参考FileUploadServlet类的具体材料。
校验
JSF具有的尺度校验是复杂基础的,不克不及满意实在的需求。开辟本人的JSF校验是简单的。我在例子使用程序中利用定制标签来开辟SelectedItemsRange校验。它校验经由过程UISelectManyUI组件选择的项目数目:
<h:selectManyListboxvalue="#{productBean.selectedCategoryIds}"id="selectedCategoryIds">
<catalog:validateSelectedItemsRangeminNum="1"/>
<f:selectItemsvalue="#{applicationBean.categorySelectItems}"id="categories"/>
</h:selectManyListbox>
更多的具体材料请参考例子使用程序。
毛病动静定制
在JSF内里,你能够设置资本包定制转换和校验时的毛病动静。资本包被设置在faces-config.xml内里:
<message-bundle>catalog.view.bundle.Messages</message-bundle>
Theerrormessageskey-valuepairsareaddedtotheMessage.propertiesfile:
#conversionerrormessages
javax.faces.component.UIInput.CONVERSION=Inputdataisnotinthecorrecttype.
#validationerrormessages
javax.faces.component.UIInput.REQUIRED=Requiredvalueismissing.
营业逻辑层和SpringFramework
营业对象和营业服务在营业逻辑层。一个营业对象不但包括数据,也有与特定对象联系关系的逻辑。在例子使用程序中标识了三个营业对象:Product,Category和User.
营业服务与营业对象相分离,供应初级的营业逻辑。一个包括间接利用的服务接口的尺度的营业接口层应当被界说。在SpringFramework的匡助下,POJO完成了Jcatalog项目营业逻辑层。有两个营业服务:CatalogService包括与目次办理相干的营业逻辑,UserService包括了用户办理逻辑。
Spring是基于把持反转观点(IOC,inversionofcontrol)。在例子使用程序中利用的Spring特性包含:
Beanmanagementwithapplicationcontexts:Spring能无效地构造我们的两头层对象,垂直处置。Spring能制止一个实体功效的分化,增进好的面向对象计划完成,举例来讲,接口计划。
Declarativetransactionmanagement:Spring利用AOP(aspect-orientedprogramming)往形貌不利用EJB容器的声明性事件处置。这类办法,事件办理能被使用就任何POJO。Spring事件办理反面JTA(JavaTransactionAPI)绑定,利用分歧的事物战略事情。在例子使用程序中声明性事件办理Hibernate中的事件。
Data-accessexceptionhierarchy:Spring供应一个值得回味的非常条理取代SQLException。利用Spring数据会见非常条理,Spring数据会见非常翻译者必需在Spring设置文件内里界说:
<beanid="jdbcExceptionTranslator"
class="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator">
<propertyname="dataSource">
<refbean="dataSource"/>
</property>
</bean>
在例子使用程序中,假如拔出的一个新产物的ID是反复的,一个DataIntegrityViolationException会被抛出。这个非常会被捕捉然后作为DuplicateProductIdException被抛出。这类办法,DuplicateProductIdException能处置分歧的数据会见非常。
Hibernateintegration:Spring不强制我们利用它壮大的JDBC笼统特性。它和O/R映照框架集成的很好,特别是Hibernate。Sping供应无效的、平安的Hibernate会话操纵。在使用程序高低文操纵Hibernate的设置SessionFactories和JDBC数据源,使使用程序简单测试。
集成层和HIbernate
Hibernate是一个开源O/R映照框架,它削减利用JDBCAPI的必要。Hibernate撑持一切支流的SQL数据库办理体系。HibernateQueryLanguage是SQL面向对象的最小的扩大来计划的,在对象和干系天下间供应了一个文雅的桥。Hibernate供应数据恢复和更新的工具,事件办理,数据毗连池,programmaticanddeclarativequeries,声明实体干系办理。
Hibernate和其他O/R映照框架比拟进侵性较小。利用反射和运转时发生字节码,SQL在体系入手下手时发生。它同意我们开辟切合Java习气的耐久对象,包含团结,承继,多态,聚合和Java汇合框架。在例子使用程序中的营业对象是POJO,不必要完成Hibernate的特别接口。
DataAccessObject(DAO)
JCatalog项目利用DAO形式。这个形式笼统和封装了一切对数据源的会见。使用程序有两个DAO接口。CatalogDao和UserDao。它们的完成类是HibernateCatalogdaoImpl和HibernateUserDaoImpl包括与Hibernate相干的办理和耐久化数据逻辑。
完成计划
如今,让我把每件事变都串起来,完成JCatalog项目。你能够冲资本列表中下载使用程序的完全源代码。
数据库计划
我们为例子使用程序创立指定目次的布局,它包括4个表,如:
数据布局图
类计划
图解了JCatalog项目标类图
类图
面向接口编程贯串于全部计划。在体现层,四个bean被利用:ProductBean,ProductListBean,UserBean和MessageBean。营业逻辑层包括两个服务(CatalogServiceandUserService)和三个营业对象(Product,Category,andUser)。集成层包含两个DAO接口和它们的Hibernate完成。Springapplicationcontexts包括和办理营业逻辑层和集成层的良多objectbeans。ServiceLocator使JSF和营业逻辑层分离到一同。
Wireeverythingup
由于这篇文章篇幅的限定,我们只看一个用例。CreateProduct用例树模了如何将每件事变串起来制作使用程序。深切细节之前,让我们利用一个序列图()树模一切层端到真个整合:
CreateProduct用例的序列图
如今,让我们经由过程对每层的先容会商怎样完成CreateProduct用例的更多细节。
体现层
体现层的完成包含创立JSP页面,界说页面导航,创立和设置backingbeans,将JSF与营业逻辑层分离。
JSPpage:createProduct.jsp是创立新产物的页面。它包含UI组件和绑缚这些组件的ProductBean。ValidateItemsRange自界说标签查验用户选择目次的数量。每一个新产物最少有一个目次被选择。
Pagenavigation:使用程序的导航界说在使用程序的设置文件内里,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>
Backingbean:ProductBean不但包括了页面中UI组件与数据映照的属性,也包括三个actions:createAction,editAction和deleteAction。这是createAction()办法的代码:
publicStringcreateAction(){
try{
Productproduct=ProductBeanBuilder.createProduct(this);
//Savetheproduct.
this.serviceLocator.getCatalogService().saveProduct(product);
//Storethecurrentproductidinsidethesessionbean.
//Fortheuseofimageuploader.
FacesUtils.getSessionBean().setCurrentProductId(this.id);
//RemovetheproductListinsidethecache.
this.logger.debug("removeProductListBeanfromcache");
FacesUtils.resetManagedBean(BeanNames.PRODUCT_LIST_BEAN);
}catch(DuplicateProductIdExceptionde){
Stringmsg="Productidalreadyexists";
this.logger.info(msg);
FacesUtils.addErrorMessage(msg);
returnNavigationResults.RETRY;
}catch(Exceptione){
Stringmsg="Couldnotsaveproduct";
this.logger.error(msg,e);
FacesUtils.addErrorMessage(msg+":InternalError");
returnNavigationResults.FAILURE;
}
Stringmsg="Productwithidof"+this.id+"wascreatedsuccessfully.";
this.logger.debug(msg);
FacesUtils.addInfoMessage(msg);
returnNavigationResults.SUCCESS;
}
在这个action内里,基于ProductBean的一个Product营业对象被创建。ServiceLocator查询CatalogService。最初,createProduct的哀求被委派给营业逻辑层的CatalogService。
Managed-beandeclaration:ProductBean必需在JSF的设置资本文件faces-managed-bean.xml中设置:
<managed-bean>
<description>
Backingbeanthatcontainsproductinformation.
</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实行为每个哀求创立ProductBean实例的义务。被办理的ID属性与productId这个哀求参数组装。JSF从哀求失掉参数,设置managedproperty。
Integrationbetweenpresentationandbusiness-logictiers:ServiceLocator笼统了查询服务的逻辑。在例子使用程序中,ServiceLocator被界说成一个一个接口。接口被JSFmanagedbean完成为ServiceLocatorBean,它从Springapplicationcontext查询服务:
ServletContextcontext=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中的一个属性。JSFmanagedbean简单毗连ServiceLocator实行必需会见ServiceLocator的那些managedbeans。利用了Inversionofcontrol(IOC,把持反转)
营业逻辑层
界说营业对象,创立服务接口和完成,在Spring中设置这些对象构成了这一层的义务。
Businessobjects:由于Hibernate供应了耐久化,Product和Category营业对象必要为它们包括的一切属性供应getter和setter办法。
Businessservices:CatalogService接口界说了一切与目次办理有关的服务:
publicinterfaceCatalogService{
publicProductsaveProduct(Productproduct)throwsCatalogException;
publicvoidupdateProduct(Productproduct)throwsCatalogException;
publicvoiddeleteProduct(Productproduct)throwsCatalogException;
publicProductgetProduct(StringproductId)throwsCatalogException;
publicCategorygetCategory(StringcategoryId)throwsCatalogException;
publicListgetAllProducts()throwsCatalogException;
publicListgetAllCategories()throwsCatalogException;
}
CachedCatalogServiceImpl服务的接话柄现,它包括CatalogDao对象的一个setter。Spring将CachedCatalogServiceImpl和CatalogDao毗连在一同。由于我们供应了接口,以是对完成的依附不是很严密。
Springconfiguration:上面是CatalogService的Springcomfiguration:
<!--HibernateTransactionManagerDefinition-->
<beanid="transactionManager"class="org.springframework.orm.hibernate.HibernateTransactionManager">
<propertyname="sessionFactory"><reflocal="sessionFactory"/></property>
</bean>
<!--CachedCatalogServiceDefinition-->
<beanid="catalogServiceTarget"class="catalog.model.service.impl.CachedCatalogServiceImpl"init-method="init">
<propertyname="catalogDao"><reflocal="catalogDao"/></property>
</bean>
<!--TransactionalproxyfortheCatalogService-->
<beanid="catalogService"class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<propertyname="transactionManager"><reflocal="transactionManager"/></property>
<propertyname="target"><reflocal="catalogServiceTarget"/></property>
<propertyname="transactionAttributes">
<props>
<propkey="get*">PROPAGATION_REQUIRED,readOnly</prop>
<propkey="save*">PROPAGATION_REQUIRED</prop>
<propkey="update*">PROPAGATION_REQUIRED</prop>
<propkey="delete*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
Spring声明事件办理是在CatalogService.CatalogService内里设置,它能完成分歧CatalogDao。Spring创立并办理单体实例Catalogservice,不必要工场。
如今,营业逻辑层筹办好了,让我们将它与集成层整合。
IntegrationbetweenSpringandHibernate:上面是HibernateSessionFactory的设置:
<!--HibernateSessionFactoryDefinition-->
<beanid="sessionFactory"class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<propertyname="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>
<propertyname="hibernateProperties">
<props>
<propkey="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
<propkey="hibernate.show_sql">true</prop>
<propkey="hibernate.cglib.use_reflection_optimizer">true</prop>
<propkey="hibernate.cache.provider_class">net.sf.hibernate.cache.HashtableCacheProvider</prop>
</props>
</property>
<propertyname="dataSource">
<refbean="dataSource"/>
</property>
</bean>
CatalogDao利用HibernateTemplate集成Hibernate和Spring.上面是HibernateTemplate的设置:
<!--HibernateTemplateDefintion-->
<beanid="hibernateTemplate"class="org.springframework.orm.hibernate.HibernateTemplate">
<propertyname="sessionFactory"><refbean="sessionFactory"/></property>
<propertyname="jdbcExceptionTranslator"><refbean="jdbcExceptionTranslator"/></property>
</bean>
集成层
Hibernate利用一个XML设置文件往映照营业对象到干系型数据库。在JCatalog项目中,Product.hbm.xml暗示Product营业对象的映照。Category.hbm.xml用于营业对象Category。设置文件和响应的营业对象在一样的目次下。上面是Product.hbm.xml:
<?xmlversion="1.0"?>
<!DOCTYPEhibernate-mappingPUBLIC
"-//Hibernate/HibernateMappingDTD2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mappingpackage="catalog.model.businessobject">
<classname="Product"table="product">
<idname="id"column="ID"unsaved-value="null">
<generatorclass="assigned"/>
</id>
<propertyname="name"column="NAME"unique="true"not-null="true"/>
<propertyname="price"column="PRICE"/>
<propertyname="width"column="WIDTH"/>
<propertyname="height"column="height"/>
<propertyname="description"column="description"/>
<setname="categoryIds"table="product_category"cascade="all">
<keycolumn="PRODUCT_ID"/>
<elementcolumn="CATEGORY_ID"type="string"/>
</set>
</class>
</hibernate-mapping>
CatalogDao经由过程Spring利用HibernateTemplate毗连:
<!--CatalogDAODefinition:Hibernateimplementation-->
<beanid="catalogDao"class="catalog.model.dao.hibernate.CatalogDaoHibernateImpl">
<propertyname="hibernateTemplate"><refbean="hibernateTemplate"/></property>
</bean>
结论
这篇文章先容了如何将JSF集成到SpringFramework和Hibernate,创建了一个实在的使用程序。这三种手艺的团结供应了一个牢靠的Web使用程序开辟框架。一个多层系统布局应当做为Web使用程序的初级系统布局。JSF很合适MVC计划形式,可以被用于完成暗示层。Spring框架能被用于营业逻辑层往办理营业对象,供应声明性事件办理和资本办理。Spring与Hibernate分离的很好。Hibernate是一个强无力的O/R映照框架,可以供应集成层的服务。
经由过程将Web使用程序分别成分歧的层和面向接口编程,每层的手艺能够被代替。比方,在暗示层Struts能代替JSF,在集成层JDO能代替Hibernate。使用程序层之间的整合不是没成心义的,利用inversionofcontrol和ServiceLocator计划形式能使这个事情简单。JSF供应了其他框架,如Struts所短少的功效。但是,这不料味着你应当立即丢弃Struts而入手下手利用JSF。不管如何,你的项目是不是利用JSF作为你的Web框架,取决于你项目标形态和功效需求和团队专家的定见。
Resources
DownloadtheJCatalogprojectsampleapplication:
http://www.javaworld.com/javaworld/jw-07-2004/jsf/jw-0719-jsf.zip
OfficialJavaServerFacessite:
http://java.sun.com/j2ee/javaserverfaces/index.jsp
AgoodJSFtutorialcanbefoundinTheJ2EE1.4Tutorial(Chapters17to21):
http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html
MorearticlesandbooksonJSF:
http://jsfcentral.com/reading/index.html
OfficialSpringFrameworksite:
http://www.springframework.org
GoodintroductiontotheSpringFrameworkbyRodJohnson:
http://www.theserverside.com/articles/article.tss?l=SpringFramework
RodJohnsonsbookExpertOne-on-OneJ2EEDesignandDevelopment(Wrox,October2002;ISBN:0764543857)isthecornerstoneoftheSpringFramework:
http://www.wrox.com/WileyCDA/WroxTitle/productCd-0764543857.html
OfficialHibernatesite:
http://www.hibernate.org
OnlinedocumentationofHibernate:
http://www.hibernate.org/hib_docs/reference/en/html/
IntroductiontotheintegrationbetweentheSpringFrameworkandHibernate:
http://hibernate.bluemars.net/110.html
"DesigningEnterpriseApplicationswiththeJ2EEPlatform,SecondEdition"isagoodintroductiontothemultitieredarchitectureandMVCdesignpattern:
http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/index.html
CommonsBeanUtils:
http://jakarta.apache.org/commons/beanutils/
CommonsFileUpload:
http://jakarta.apache.org/commons/fileupload/
FormoreonJavaServerFaces,readthefollowingJavaWorldarticlesbyDavidGeary:
"AFirstLookatJavaServerFaces,Part1"(November2002)
"AFirstLookatJavaServerFaces,Part2"(December2002)
"JavaServerFaces,Redux"(November2003)
BrowsetheJavaServerPagessectionofJavaWorldsTopicalIndex:
http://www.javaworld.com/channel_content/jw-jsp-index.shtml
BrowsetheEnterpriseJavasectionofJavaWorldsTopicalIndex:
http://www.javaworld.com/channel_content/jw-enterprise-index.shtml
C#跟java类似,但是在跨平台方面理论上可以跨平台,实际上应用不大,执行性能优于java,跟C++基本一致,但是启动速度还是慢.代码安全,但容易性能陷阱. |
|