原文地址:http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html
内容概要
使用JSF建立一个真实的Web应用程序不是没有意义的任务,这篇文章介绍了如何将JSF与Sping Framework和Hibernate集成,并且给出了使用这些技术建立这个真实的Web应用程序的最佳实践和设计指导
JavaServer Faces(JSF)技术是J2EE应用程序的一个新的用户接口框架,它非常适合基于MVC(Model-View-Controller)体系结构的应用程序。已经有大量的文章介绍JSF。然而,很多文章都是站在理论研究的层面上,没有挑战一个真实的企业开发。很多问题没有解决,例如,JSF怎样全面适合MVC体系结构?JSF如何与其他JAVA框架集成?业务逻辑应该放在JSF的backing beans里面吗?怎样处理JSF里面的安全问题?最重要的是你怎样使用JSF建立一个真实的Web应用程序?
这篇文章涉及所有这些问题。它向你展示如何集成其他特定的Java框架,Spring Framework和Hibernate,它示范怎样去创建一个叫JCatalog的Web应用程序,一个在线的产品目录系统。这篇文章使用JCatalog例子,介绍了Web应用程序设计的每一个阶段,包括业务需求收集,分析,技术选择,高层体系结构和详细设计。这篇文章论述了JCatalog里面好的和不好的技术,示范了应用程序设计中一些关键方面的方法和步骤。
这篇文章是写给正在从事基于J2EE Web应用程序的Java架构师,开发者,它不是对JSF、Spring Framework和Hibernate的入门教程。如果您对这些领域不熟悉,请参考文章最后的资源链接。
例子应用程序的功能需求
这篇文章的例子应用程序JCatalog是一个真实的Web应用程序,例子足够现实是为了决定应用程序架构而进行意味深长的讨论的基础。我通过介绍JCatalog项目的需求开始。我在这里谈到后面贯穿于整个文章的内容是为了演示技术选择和体系结构设计。
设计Web应用程序的第一步是收集系统的功能需求,这个例子应用程序是一个典型的电子商务应用系统。用户能浏览产品目录和查看产品细节,管理员能管理产品目录。功能还可以增加,举例来说,为了开发一个成熟的电子商务系统,可以添加库存管理和订单处理的功能。
用例
用例分析被用于去访问例子应用程序的功能需求,图1是应用程序的用例图。
图1 用例图
一个用例图确定在一个系统中的参与者以及参与者可以执行的操作。例子应用中7个用例必须被实现。参与者中的User能浏览产品目录和察看产品细节。一旦用户以Administrator身份连接到系统,他就能创建新产品,编辑存在的产品,删除老的产品。
业务规则
JCatalog 必须符合下面的业务规则:
每个产品有一个唯一的产品ID
每个产品至少属于一个目录
产品ID一旦被创建就不能改变
假定
对于产品的设计和实现,我们做下面的假定。
英语是默认语言;不要求国际化
目录中不超过500种产品
目录的更新不频繁
页面流
图2显示了所有JCatalog的页面和它们之间的转换。
图2 页面流图
应用程序有两组页面:公共的国际互联网和管理员的企业内部网。企业内部网只有对那些成功登陆到系统的用户有效。产品概要页面是公用的,它作为产品目录的内容包含在一个HTML框架里面。产品列表是一个特殊的目录,只能被管理员看见,它包含创建、编辑和删除产品的链接。
图3是目录页的一个模型。理想情况下,每一个页面所有的控制和必要的内容明细的模型应该被包含在需求文档里面。
图3 目录页面模型
高级体系结构设计
下一步的设计是Web应用程序的高级体系结构设计,它包括将应用程序细分成功能组件以及将这些组件划分到各自所属的层。高级体系结构设计独立于使用的技术。
多层体系结构
一个多层体系结构将整个系统划分成清晰的单元——客户端、表示层、业务逻辑层、集成层和企业信息系统(EIS),这保证了清晰的责任划分以及可维护性和可扩展性。三层或多层系统已经被证明比没有业务逻辑层的客户-服务器系统具有更多的可升级性和柔韧性。
客户端——是数据模型被消费和呈现的地方。对于一个Web应用程序,客户层通常是Web浏览器。基于浏览器的瘦客户不包含表示逻辑;它依赖于表示层。
表示层使用业务逻辑层为用户服务,它知道怎样去处理一个客户请求,怎样去和业务逻辑层结合以及怎样去选择下一个试图去显示。
业务逻辑层——包含一个应用程序的业务对象和业务服务。它从表示层接受请求,基于请求处理业务逻辑,作为访问EIS层资源的的中介。业务逻辑层组件使用许多系统级别的服务,例如,安全管理、事物管理和资源管理。
集成层——是业务逻辑层和EIS层之间的桥梁。它封装了与EIS层相结合的逻辑。有时,集成层和业务逻辑层的结合是作为中间层被提到。
应用程序数据在EIS层被持久化,包括关系数据库,面向对象数据库和遗留系统。
JCatalog 的体系结构设计
图4显示了JCatalog的高级体系结构设计以及它怎样适合多层体系结构。
图4 高级体系结构图
应用程序使用了一个多层的非分布式的体系结构,图4显示应用程序层和每一层技术选择的划分。它也用于应用程序的部署图。对于一个可配置的体系结构,表示层、业务逻辑层和集成层被定位在同样的Web容器。定义良好的接口隔离了每一层的职责。可配置的体系结构使应用程序简单和可升级。
对于表示层,经验告诉我们,最好的实践是选择一个存在的,被验证的Web应用框架,远比设计开发一个定制的框架好。我们有几个Web应用框架可供选择,举例来说,Struts、WebWork和JSF。对于JCatalog项目,我们使用JSF。
对于业务逻辑层,不是使用EJB(Enterprise JavaBeans)就是使用POJO(plain old Java objects)。如果应用程序是分布式的,EJB具有远程接口是一个较好的选择。因为JCatalog是一个典型的没有远程访问请求的Web应用程序,POJO在Spring框架的帮助下,用于实现业务逻辑层。
Pure JDBC(Java Database Connectivity):这是最灵活的实现方法;然而,低级的JDBC和不好的JDBC代码工作是麻烦的,执行的不好。
Entity beans:一个容器管理持久化(CMP,container-managed persistence)的entity bean是隔离数据访问代码和处理O/R(object- relational) mapping数据持久化的昂贵的方法。它是一个以应用服务器为中心的解决办法。一个entity bean不和特定的数据库紧耦合,但是应用程序和EJB容器进耦合。
O/R mapping framework:一个O/R影射的框架采用以对象为中心的方法实现数据持久化。一个以对象为中心的应用程序是容易开发和高度轻便的。在这个领域内存在几个框架——JDO(Java Data Objects),Hibernate, Toplink。CocoBase是一个新的例子。在例子应用程序中我们使用HIbernate。
现在,让我们讨论将应用程序的每一个层联合起来设计的问题。因为JSF相对来说是一个新技术,我强调一下它的使用。
表现层和JavaServer Faces(JSF)
表现层收集用户输入,呈现数据,控制页面导航,代替用户与业务逻辑层交互。表现层也能校验用户输入,维护应用程序的会话状态。下面的章节,我讨论表现层的设计考虑和模式以及我选择JSF去实现JCatalog项目的表现层的原因。
MOdel-View-Controller(MVC)
MVC是Java蓝皮书(BluePrints)中推荐的交互式应用程序体系结构设计模式。MVC分别设计关注的问题,因此减少了代码的重复,集中控制,使应用程序更具扩展性。MVC也帮助开发者使用不同的技术集合,集中他们核心的技术,通过定义清晰的接口进行合作。MVC是表现层的体系结构设计模式。
JavaServer Face
JSF是一个基于Java的Web应用程序服务端的用户接口组件框架。JSF包括表示UI组件和管理其状态的API;处理事件,服务端校验,数据转换;定义页面导航;支持国际化和可访问性;提供所有这些特点的扩展能力。它还包括两个为JSP定制的标签库,一个用于表示JSP页面内的UI组件,一个用于配置服务端的对象组件。
JSF和MVC
JSF很适合基于MVC的表现层体系结构。它提供动作和表现之间清楚地划分。它影响了UI组件和Web层概念,不限定你去使用特定的脚本技术或者标记语言。
JSF backing beans 是model层(后面的章节有关于backing beans 的更多内容)。它们也包含动作,这是控制层的扩展,代理用户对业务逻辑层的请求。请注意,从整体应用程序的体系结构来看,业务逻辑层也能被作为Model层提到。使用JSF定制标签的JSP页面是视图层。Faces Servlet提供控制者的功能。
为什么用JSF
JSF不仅仅只是另一个Web框架,下面是JSF与其他Web框架不同的特点:
象Swing一样面向对象的Web应用程序开发:服务端有状态的UI组件模型,具有事件监听和操作者,开始了面向对象Web应用程序开发。
Backing-bean管理:Backing beans是页面中JavaBeans组件和UI组件的联合。Backing-bean管理UI组件对象定义和对象执行应用程序特殊过程以及控制数据的分离。JSF在正确的范围内执行存储和管理这些backing-bean实例。
可扩展的UI组件模型:JSF UI组件是组成JSF应用程序用户接口可配置、可复用的元素。你能扩展标准的UI组件和开发更多的复杂组件。举例来说,菜单条和树型构件。
灵活的表现模型:一个renderer分隔一个UI组件的功能和视图。多个renderer能被创建,用于定义相同或不同客户端上同样组件的不同外观。
可扩展的转化和校验模型:基于标准的转换者和校验者,你能开发定制的转换者和校验者,它们提供最好的模型保护。
尽管JSF很强大,但是现在还不成熟。组件、转换者和校验者是JSF基本的。每一个校验模型不能处理组件和校验者之间多对多的校验。另外,JSF定制标签不能和JSTL(JSP Standard Tag Library)无缝结合。