[转载]利用JSF、SpringFramework和Hibernate构建Web应用的实例讲述

利用JSFSpringFrameworkHibernate构建Web应用的实例讲述


(
来源:http://blog.csdn.net/ylong/archive/2004/07/24/50810.aspx) [原作者] 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

该文是我看的第一篇讲述JSFSpring整合的文章,是一个很好的范例,比较适合于对Spring有了一定了解人学习。其中大量篇幅讲述的JSF,对JSF感兴趣的也可以来看看。

[@more@]JSF是一种新的用于构架j2ee应用用户界面的技术,它尤其适合于基于MVC架构的应用中。虽已有很多文章介绍过了JSF,然而它们大多从理论高度来介绍JSF而不是面向于实际应用。目前对于实际应用,JSF仍有很多问题没有解决,例如:如何使JSF适应于MVC整体构架中?如何将JSF与其他Java 框架整合起来?是否应该将业务逻辑放置在JSFbacking beans中?如何处理JSF中的安全机制?更为重要的是如何利用JSF构架现实世界的Web应用?

本文将涉及到上面的这些问题,它将演示如何将JSFSpringHibernate整合在一起,构架出一个名为JCatalog的在线产品价目系统。利用该Demo,本文涵盖了Web应用开发的每一个阶段,包括需求收集、分析,技术选择,系统架构和实现。本文讨论了在JCatalog中涉及到的各种技术的优点和缺点并展示了一些关键部分的设计方法。本文的对象是从事基于J2eeWeb应用架构人员和开发人员,它并不是对JSFSpringFrameworkHibernate的简单介绍,如果对这些领域不甚了解,请参看相关资源。该范例的功能需求
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 flow2显示了所有的JCatalogpages以及它们之间的transitions关系:

该应用中存在两组pages:公开的internet和用于管理的intranet,其中intranet只能被那些成功登录到系统的用户访问。 ProductSummary不作为一个单独的page展示给用户,它显示在Catalog page中的frame中。ProductList只对管理员可视,它包含用于创建、编辑和删除产品的链接。

3是一个Catalog页面的示意图,理想状况下,在需求文档中应该包含每一页的详细示意图。

构架设计
Web
应用开发的下一个阶段是构架设计,它包括将应用划分为多个功能组件并将这些组件分割组合成层,高层的构架设计应该中立于所选用的特定技术。多层架构多层架构是将整个系统清晰的分为多个功能单元:clientpresentationbusiness-logicintegration EIS,这将确保职责得到清晰的划分,使得系统更易于维护和扩展。具有三层或等多层的系统被证明比C/S模型具有更好的伸缩性和灵活性。

client
层是使用和表示数据模型的地方,对于一个Web应用,client层通常是浏览器,基于浏览器的瘦客户端不包含任何表示逻辑,它依赖于presentation层。

presentation
层将business-logic层的服务展示给用户,它应知道如何处理用户的请求,如何同business-logic层交互,并且知道如何选择下一个视图显示给用户。

business-logic
层包含应用的business objectsbusiness services。它接受来在于presentation层的请求、基于请求处理业务逻辑。业务逻辑层组件将受益于系统级的服务,如安全管理、事务管理和资源管理等。

integration
层是介于business-logic层和EIS层之间的桥梁,它封装了与EIS层交互的逻辑。有时,将integration层和business-logic层合称为中间层。应用的数据被保存在EIS层中,它包括关系数据库、面向对象数据库和以及遗留系统等。JCatalog的构架设计4显示了JCatalog的构架设计以及如何应用于多层构架系统中。

该应用采用了多层非分布式的构架,图4展示了系统的分层以及每一层中选择的技术,它同时又是该范例的部署图,它的presentation business-logicintegration层将存在于同一个web容器中。定义良好的接口将孤立每一层的职责,这一架构使得应用更为简单和更好的伸缩性。对于presentation层,经验表明,最好的方法是选择已存在的并已得到证明了的Web应用框架,而不是自己去设计和开发新的框架。我们拥有多个可选择的框架,如StrutsWebWorkJSF等,在JCatalog中,我们选择采用JSF

EJB
POJO都可以用来创建业务逻辑层,如果应用是分布式的,采用具有remote接口的EJB是一个好的选择;由于JCatalog是一个典型的不需要远程访问的Web应用,因此选用POJO,并充分利用Spring Framework的帮助,将是实现业务逻辑层的更好选择。

integration
层利用关系型数据库事先数据的持续化,存在多种方法可用来实现:

  • JDBC:这是最为灵活的方法,然而,低级的JDBC难以使用,而且质量差的JDBC代码很难运转良好
  • Entity beansCMPEntity bean是一种分离数据访问代码和处理ORM的昂贵的方法,它是以应用服务器为中心的方法,即entity bean不是将应用与某种数据库类型而是EJB容器约束在一起。
  • O/R mapping framework:一个ORM框架采用以对象为中心的方法实现数据持续化,一个以对象为中心的应用易于开发并具有高度的可移植性。在该领域中存在几个框架可用—JDOHibernateTopLink以及CocoBase等。在我们的范例中将选用Hibernate

现在,我们将讨论每一层中的设计问题,由于JSF是一个相对较新的技术,因此将着重于它的使用:presentation层和JSF表示层的功能是收集用户的输入、展示数据、控制页面导航并将用户的输入传递给业务逻辑层,表示层同时需要验证用户的输入以及维护应用的session状态。在下面几部分中,我将讨论表示层设计时的考虑和模式,并说明选择JSF作为JCatalog表示层的原因。

MVC
MVC
Java-Blueprints推荐的架构设计模式,MVC将几个方面分离开来,从而减少代码的重复,它以控制为中心并使得应用更具扩展性。MVC同时可帮助具有不同技能的用户更关注于自己的技能,通过定义良好的接口进行相互合作。MVC是表示层的架构设计模式。

JSF
JSF
Web应用的服务器端用户组件框架,它包含以下API:表示UI组件、管理它们的状态、处理事件、服务器端验证、数据转换、定义页面导航、支持国际化,并为这些特性提供扩展能力。它同时包括两个JSPtag库以在JSP页面中表示UI组件,以及将组件wire为服务器端对象。

JSF
MVC
JSF
非常适合于基于MVC的表示层架构,它在行为和表示之间提供了清晰的分离,它使得你可以采用熟悉的UI组件和web层概念而无需受限于某种特殊的脚本技术或标记语言。

JSF backing beans
JSFModel层,此外,它同样包含actionsactioncontroller层的扩展,用于将用户的请求委派给业务逻辑层。这里请注意,从整体的应用构架看,业务逻辑层也被称为model层。包含JSF标签的JSP页面是表示层,Faces Servlet提供了controller的功能。为什么选用JSF
JSF
不仅仅是另外一个Web框架,下面这些特性是JSF区别于其他Web框架之所在:

  • Swing的面向对象的Web应用开发:服务器端有状态的UI组件模型,配合event listenershandlers,促进了面向对象的Web应用开发。
  • backing-bean管理: backing bean是与页面中使用的UI组件相关联的javabean组件,backing-bean管理将UI组件对象的定义同执行应用相关处理和拥有数据的对象分离开来。JSF在合适的范围内保存和管理这些backing-bean实例。
  • 可扩展的UI模型:JSFUI模型是可配置的、可重用的,用以构建JSF应用的用户界面。你可以通过扩展标准的UI组件来开发出更为复杂的组件,例如菜单条、树组件等。
  • 灵活的rendering模型:renderer分离了UI组件的功能和显示,多个renderers可创建和用来为同一客户端或不同的客户端定义不同的显示。
  • 可扩展的转换和验证模型:基于标准的convertervalidator,你可以开发出自己的可提供更好的模型保护的convertervalidator

尽管如此,JSF目前尚未成熟,随同JSF发布的 componentsconvertersvalidators都是最基础的,而且per-component验证模型不能处理components validators间的many-to-many验证。此外,JSF标签不能与JSTL间无缝的整合在一起。在下面的章节中,我将讨论几个在JCatalog实现中的关键部分和设计决策。我首先解释managed bean的定义和使用以及JSF中的backing bean,然后,我将说明如何处理安全、分页、cachingfile upload、验证以及错误信息定制。

Managed bean,backing bean,view object
domain object model
JSF
中引入了两个新的名词:managed beanbacking beanJSF提供了一个强大的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中, CreateProductEditProduct将共享同一个ProductBean定义。

model
对象特定于表示层中的一个view对象,它包含必须显示在view层的数据以及验证用户输入、处理事件和与业务逻辑层交互的处理逻辑等。在基于 JSF的应用中backing bean就是view对象,在本文中backing beanview对象是可互换的名词。对比于struts中的ActionFormAction,利用JSF中的backing-bean进行开发将能更好的遵循面向对象方法,一个 backing-bean不仅包含view数据,而且还包含与这些数据相关的行为,而在struts中,ActionActionForm分别包含数据和逻辑。我们都应该听说过domain object model,那么,domain object modelview对象之间有什么区别呢?在一个简单的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与特殊的继承关系结合起来了
  • 利用JSFViewHandler decorator:这一方法中,安全逻辑紧密地与一特定Web层技术联系在了一起
  • 利用servlet filter:一个JSF应用与其他的Web应用没有什么两样,filter仍是处理认证检查的最好地方,这种方法中,认证逻辑与Web应用分离开来

在我们的范例程序中,SecurityFilter类被用来处理用户的认证,目前,受保护的资源只包含三个页面,出于简单的考虑,将它们的位置被硬编码到Filter类中。分页该应用中的Catalog页面需要分页,表示层可用来处理分页,即它取出所有的数据并保存在这一层;分页同样可在business-logic层、 integration层、甚至