对于RAD 工具的四个层次, JavaServer Faces 定义了其中3个:一个组件架构,一个标准的UI 部件集,以及一个应用架构。JSF的组件架构定义了通用的方式来建立UI 部件。此架构能驱动标准的JSF UI 组件(按钮,超链接,复选框,文本框等等),也为第3方组件留了空间。组件是面向事件的,所以JSF 允许你处理客户产生的事件 (如,文本框中值的变化或者点击了按钮)。
因为对Web应用来说,不象其桌面应用堂兄弟,它必须总是要满足多个客户 (比如桌面浏览器,移动电话和PDA等), JSF 有一个强大的架构来以不同的方式显示组件。它也有一个可扩展的机制来进行输入校验 (如字段长度) 以及在显示字符串和对象之间进行转换。
Faces 也能够自动的保持你的UI 组件和收集用户输入值的Java 对象之间的同步,并且通过调用后台Bean来对事件进行响应。另外,它有一个强大的导航系统并且全面支持多语言特征。这些特征构成了JSF的应用基础架构—即对新应用系统必不可少的基本构建块。
JavaServer Faces 定义了工具支持的基础,但是其实现留给了工具厂商,这是Java的习惯。你可以自行选择业界领导提供的工具,它们都可以是你能够像使用其他RAD 开发工具如Visual Studio. NET一般可视化的布局和设计你的Web UI。 (如图1.1, 1.2, 和 1.3 分别展示了在IBM, Oracle, 和 Sun的IDE开发工具中开发JSF是什么样子) 。或者,如果你愿意在没有设计工具下开发Faces 应用。
在这些赞美之词之后,我们应该指出JavaServer Faces 和桌面UI 框架如Swing 或者SWT之间的关键不同之处: JSF 是运行在服务器之上。因此, Faces 应用将运行在一个标准的Java web 容器之中,如Apache Tomcat [ASF, Tomcat],Oracle Application Server [Oracle, AS],或者IBM WebSphere Application Server [IBM, WAS],然后向客户显示HTML 或者其他标记语言。
如果你点击一个Swing 应用中的按钮,它将产生一个事件,而你可以直接在驻留在桌面中的代码来处理该事件。相反, web 浏览器并不知道JSF组件和其事件的任何东西;它仅仅知道显示HTML而已。所以当你点击一个Faces 应用按钮,它将产生一个请求,有浏览器发送到服务器。Faces 负责将该请求转换成一个可以被服务器中的应用逻辑所处理的事件。它也负责保证你在服务器所定义的每一个UI 部件都正确显示给浏览器。
图1.4 显示了一个Faces 应用的高阶视图。你可以看到,应用运行在服务器上可以和其他子系统集成,如EJB服务或者数据库服务。当然, JSF还提供许多其他服务可以帮助你你更小的代价构建强大的Web应用。
JavaServer Faces 有一个特定的目标:使web 开发更快更容易。它允许开发人员以组件,事件,后台Bean以及它们之间的交互来进行思考,而不是请求,响应和标记。换句话说,它掩盖了Web开发的大量的复杂性,是开发人员能够集中于如何使他们的应用做的最好。
工业支持
对JCP社区和Sun 扩展Java的方式来说,最好的事情莫过于有大量的公司,组织和个人投身其中。通过JCP 产生一种规范实际上算不上快速,但结果却是非常好的。JavaServer Faces 在2001年5月通过Java 规范请求(JSR) 127 引入;规范的最终版本,JSF 1.0,在2004年3月3日才发布。而JSF 1.1 (维护发布版) 则是2004年5月27日发布的。参与开发Faces的公司和组织 (除Sun之外)包括Apache软件基金, BEA 系统, Borland 软件,IBM,Oracle,Macromedia,等等。
这些公司开发的产品可分为3类(某些可能适合不止一类):J2EE 容器,开发工具,和UI 框架。因为JavaServer Faces是一个与工具一起工作和运行于J2EE 容器中的UI框架,这样做则非常之好。最重要的是这些公司中包括许多业界巨头。这意味着你可以期望JSF 具有大量的工业支持。并且,如果你的供应商不支持JSF,你也可以免费下载Sun的参考实现 [Sun, JSF RI]。
要跟踪最新的JSF 新闻,文章,产品和供应商,请访问JSF Central [JSF Central],本书作者所运作的一个社区站点。
JSF,Struts,和其他框架
我们面对这一情况:有大量的Java web 框架可用。它们中某些,如Struts [ASF, Struts] 和 WebWork [OpenSymphony, WebWork],有助于表单处理和其他问题,比如遵循Model 2,集成数据源,以及通过XML配置文件中心化控制引用的所有应用资源。这些基本框架提供了广泛的基础设施,但是还没有屏蔽基本的HTTP请求响应处理。
其他框架,象Tapestry [ASF, Tapestry],Oracle的应用开发框架 (ADF) UIX [Oracle, ADF UIX],以及SOFIA [Salmon, SOFIA],都提供一个UI 组件模型和某些事件处理机制。这些UI 框架,包括JSF,目的是简化整体变成模型。经常,基础架构和UI 框架具有重叠的功能。
为了理解这种重叠,你可以想象web 应用架构师一个服务栈。靠近栈底部的服务没能抽象基础协议的许多细节;它们更像粗加工品。栈中靠近顶部的服务则隐藏了更多讨厌的细节,提供更高级别的抽象。最低层的服务由web servers,Servlet API,和JSP处理。大部分框架都提供一些附加服务的子集。图1.6显示了这个栈,以及与JSF,Struts,servlets,JSP,和典型的web server的关系。
你可以从图中看到JSF 支持足够多的服务,这也使得它自己成为强大的框架。在大多数情况下,这就是你需要的东西。后续发布的Faces极有可能也会包括传统的服务。
然而,即使Faces 与Struts这样的框架有些重叠,也并不是必须替代它们。 (事实上,如Struts的领导, Craig McClanahan, 是JavaServer Faces的开发指导) 如果你将他们集成起来,你就可以访问栈中的所有服务(第 14 章将包含Struts 集成)。你也可以和其他框架一起使用JSF,比如Spring [Spring-Faces]。
对于面向UI的框架,JSF 和他们很多功能都有重叠。这些项目的某些申明将在其未来版本中支持JSF。Faces 的独特之处在于有通过JCP的工业巨头参与的开发联盟,以及将成为J2EE的一部分。作为结果,它将分享受强有力的工具支持,并将随很多J2EE server一起交付。
组件无处不在
令人悲哀的是,“组件”一词的过度使用在今天已经到处蔓延了。操作系统是一个组件,应用程序是一个组件,EJBs 是组件,库是组件,甚至厨房的水槽也是。有大量的书论及组件,有好的书指出组件有好多定义存在。
如果你知道他的确实意义,对这个词的滥用,你就不会感到陌生。如果你在词典中查找“组件(component)”这个词,你就会看到他有一个同义词供选—整体的一个部分。因此,如果你使用这个词的字面意思,在一个分布式应用欢迎用,操作系统确实是一个组件。
更有趣的是,从概念上讲,厨房水槽对操作系统相比对Faces组件来说更有共通之处。你不用自己从头制造它—你只需要购买一个符合你需要的水槽:尺寸,颜色,材料,容器数,等等。对其他厨房用品也是如此,比如橱柜和工作台面。所有这些组件都有特定的接口可以使他们能够和其他东西进行集成,但是依赖于特定的环境服务。(例如,接口管)。最终结果可能是独特的,但整体是由独立可重用的部件组成。
如果我们采用厨房组件的概念,并应用到软件商,我们会得出这个定义:
厨房的“环境依赖性”就是诸如房间本身,配管,电路等等的因素。本质上,环境是所有组件的容器。一个容器是拥有组件,并且提供一系列允许进行组件操作的服务的系统。有时,这种操作在IDE (设计时)中进行,有时则在部署环境中运行,比如J2EE server之中 (运行时)。
短语“独立部署” 意味着一个组件是一个自包含的单元,可以被安装到一个容器中。厨房水槽是一个独立的,自包含的组件,可以安装在工作台中。
当你改造你的厨房时,你雇用一个承包商,由他来组装你所选择的组件 (橱柜,抽屉,水槽等等) 成为一个完整的厨房。我们使用组件构建软件时,我们也是将各种组件组装起来,创建能够运行的软件系统。
JSF 组件, Swing 组件, servlet, EJB, JavaBean, ActiveX 控件,以及Delphi 可视组件库 (VCL) 组件都符合这个定义。但这些组件却集中于不同的事情。JSF 和Swing 组件单独针对UI 开发,而ActiveX 和 VCL 控件可以也可以不影响UI。Servlets 和 EJBs 则更粗糙一些— 他们在应用和业务逻辑领域提供大量的功能。
因为JSF 着眼于UI 组件,我们来相应窄化我们的组件定义。
如果你是在开发传统的GUI应用,那么UI 组件的概念应该对你非常熟悉了。JavaServer Faces 的精彩之处在于将标准的UI 组件模型引入到Web世界。