A first look at JavaServer Faces(jsf 1)

A first look at JavaServer Faces(jsf 1)

Summary In  September 2002,  the early  access (EA)  draft of the JavaServer Faces specification was released under Java Specification Request (JSR) 127. JavaServer Faces,  with a  well-defined request  processing lifecycle  and a rich component hierarchy, will profoundly  affect the development of Java  2 Platform, Enterprise Edition (J2EE) applications. In Part 1 of this two-part series, David Geary introduces JavaServer Faces and explores its fundamental concepts. (3,000 words; November 29, 2002) 
    
摘要:在2002年9月的127次JSR会议上发表了JavaServer Faces规范的早期草稿版本。具有良好定义的请求处理生命周期和丰富的组件层次结构的JSR将会深远的影响到J2EE应用的开发。在本篇分为两部分的文稿的第一部分中,David Geary将介绍JSR并初步探讨它的基本概念。
    
    Recently, I had the good fortune of training and mentoring a group of novice Java developers  as we implemented  a complex Web application using  Struts,  Enterprise  JavaBeans (EJB), servlets, JavaServer  Pages (JSP), and  the JSP  Standard  Tag Library (JSTL). As it  turned out, the project was a  success;  it  came in  under budget  and on   time, and   had numerous   features not originally  envisioned.  As  you might  imagine,  we   faced many  technical challenges along the  way; the most significant were: 

最近,我在使用Struts、EJB、JSP和JSTL开发一个复杂的Web应用的过程中能有幸培训和指导一组共同参与开发的初级Java开发人员。当开发完成以后,整个项目非常成功并且是在经费预算和进度规划内完成的,而且实现了很多原先没有设想到的功能特性。当然我们在开发的过程中也遇到了相当多的技术挑战,最典型的有:

    1. Implementing custom  components, Which   included a   tree/table viewer   and a  query  builder   that  lets    users  dynamically  add   and  remove fundamental  components such as   text    fields and  drop-down lists used  to build database queries. 

    1. 实现客户端组件,诸如树型、列表的视图和允许用户在创建数据库查询时动态的增加和删除类似于文本输入框或者下拉列表等基本元素的查询构造器的客户端组件。

    2. Supporting hand-held devices, such as PDAs and radio frequency devices. 
    
    2. 支持手持设备,例如PDA和射频设备。

    3. Lack  of  an  IDE   for  effective  rapid  application   development  (RAD).
    
    3. 缺乏有效的能够支持快速应用开发的集成环境。
    
    Implementing custom components and supporting hand-held  devices—especially  the latter—consumed  a great  deal of  our time  and effort. Also, although some  of the  developers used  the Eclipse  open source  IDE, we  lacked an effective RAD tool for implementing the Web application's user interface. 

    实现客户端组件和支持手持设备消耗了大量的时间精力。尽管一部分开发人员使用了开    放源码的Eclipse基层开发环境,但是我们在Web应用的客户界面开发方面还是没有有效的RAD工具。

    Unless you've been living in a cave for the past few years, I'm sure  you're  aware that  tools exist  for creating  custom Web  components and supporting  markup languages other than HTML, all of which are wrapped up in a very nice IDE. That software, of course, is Microsoft's .Net with WebForms; the IDE is Visual Studio. 

    我确信除非你不韵世事,否则你肯定知道用于开发用户Web组件和支持HTML以外的标记语言的工具已经被集成到了一个非常不错的开发工具中了。当然这个工具就是Microsoft's .Net with WebForms,而这个开发环境就是Visual Studio。

    In  spite of  those attractive  .Net features,  the company  I was  working
for—like many software development companies nowadays—opted to go with the Java  2 Platform,  Enterprise Edition  (J2EE) because  of its  platform and
vendor independence  and the  wealth of  available open  source software for   Java and J2EE. 

    尽管.NET具有很多引人瞩目的特性,我所工作的公司和目前的许多软件开发公司一样,因为J2EE的平台无关性和大量可以利用的开放源码的软件而倾向于在J2EE上进行开发
    Wouldn't it  be nice  if you  could take  advantage of  Java and .Net's best features, platform and vendor independence, open source products such as Ant and log4j, and the ability to easily create custom Web components and render them to multiple devices, all wrapped up in a killer IDE? That's the promise of JavaServer Faces. 

    如果我们能把所有这些Java和.NET各自的优点,平台无关的特性,类似Ant和Log4j这样优秀的开放源码的软件产品以及能够简便的生成客户Web组件并发布到多种设备上的能力组合到一个独一无二的集成开发环境中,那这个开发环境将是非常的优秀啊?这就是    JSF将提供给我们的东西。

JSF是什么?


    JavaServer Faces (JSF)  is an application  framework for creating  Web-based user interfaces.  If you are  familiar with  Struts (a popular   open source JSP-based Web  application  framework)  and Swing   (the standard Java  user interface  framework for desktop  applications),  think of JavaServer  Faces as a  combination of  those two  frameworks. Like  Struts,  JSF provides Web application lifecycle  management through  a controller   servlet; and  like Swing, JSF  provides a  rich component  model complete  with event  handling and component rendering. 

JSR是生成基于Web的用户界面的应用程序框架。如果你对Struts(流行的开放源码的Web应用程序框架)和Swing(标准的用于桌面应用的Java用户界面框架)都很熟悉的话,可以认为JSF是他们二者的集成。类似于Struts,JSF通过一个控制器Servlet提供了Web应用的生命周期管理;同时类似于Swing,JSF提供了包括事件处理和组件生成在内的丰富的组件模型。

    In a nutshell, JSF eases Web-based application development because it: 
    Lets you create user interfaces from a set of standard, reusable server-side components   Provides  a  set  of   JSP  tags  to  access  those components Transparently  saves  state  information  and  repopulates  forms  when they redisplay  Provides  a   framework  for   implementing  custom   components  Encapsulates event handling and component rendering so you can use  standard  JSF components or custom components  to support markup languages other  than  HTML Lets tool vendors develop IDEs for a standard Web application framework
    
简单的说,JSF基于以下的原因简化了基于Web的应用的开发:
◆使你能够利用一些标准的可重用的服务器端组件来创建客户界面。 
◆提供了一组JSP 标签来获取(访问)这些组件。 
◆开发人员不用关心当页面刷新的时候页面状态数据的存储和重现。 
◆提供了一个用于实现定制组件的框架 
◆封装了事件处理和组件显示,所以你可以使用标准的或者定制的JSF组件支持HTML以外的标记语言。
◆开发工具提供商可以开发针对标准Web应用框架的集成环境。

    Besides being a conceptual combination of Struts and Swing, JSF is a  direct competitor to Microsoft's WebForms. The frameworks are very similar, both in concept and implementation. And because  JSF represents a standard for  Java-based  Web  application  frameworks,   tool  vendors  can  concentrate   on  developing  IDEs  for  JSF  instead   of  developing  an  IDE  for   one  of approximately 35 existing  Java-based Web application  frameworks, including Struts. 
    
除了作为Struts和Swing概念上的统一体外,JSF还将成为Microsoft的WebForms的直接    竞争对手。这两种框架不论从概念或者实现上都非常相似。由于JSF作为基于Java的Web    应用框架的标准,工具开发商们可以专注于为JSF开发集成环境,而不仅仅为包括Struts在内的大约35种基于Java的Web应用框架的其中之一开发集成环境。
    
    Note: Struts developers needn't worry; although JSF and Struts have much  in common, JSF will not make Struts obsolete. See Resources for a discussion of an integration strategy for Struts and JavaServer Faces. 
    
注:Struts开发人员不用担忧;尽管JSF和Struts很相像,但JSF并不会放弃Struts。在参考资料中有关于集成两者的讨论。

    Currently,  JSF  is an  early  access (EA)  release,  and, as  a  result, is somewhat immature. The specification leaves some functionality  unspecified, and  the specification  and reference  implementation are  currently out  of sync, with  the former  specifying new  syntaxes and  functionality not  yet implemented in the latter. On the  other hand, JSF is mature enough  for you to  write code  against—although much  of that  code is  guaranteed to  be obsolete (see  the disclaimer  below)—and the  reference implementation  is fairly  complete  and  relatively   bug-free.  You  can  download   the  JSF specification, the reference implementation, two sample applications, and  a JSF tutorial from Resources. 
    
目前JSF还仅仅是EA版本,所以不是很成熟。规范当中还有很多功能没有阐述,规范和    参考实现也不同步,规范中描述的语法和功能还没有得到实现。另一方面,JSF已经足够成熟得让你根据它进行编程——尽管有些代码将会被废弃(参看下文声明)——而且参考实现已经基本完成而且比较可靠。你可以从参考资源中下载JSF的规范、参考实现、两个样例应用和一份JSF教程。

    The two  articles in  this series  provide a  code-intensive introduction to JavaServer Faces. In this  article, I begin with  a short discussion of  the JSF  lifecycle  and  then  dive  into  some  example  code  that illustrates implementation of Web-based  user interfaces with  JSF and how  you can take advantage of built-in  validation. In Part  2, I will  explain more advanced JSF concepts such as:  implementing custom validation; using  model objects; internationalization; creating  custom components;  and finally,  delegating  event handling and  rendering so you  can use components  to generate markup languages other than HTML. 

本系列的两篇文章提供的是并不偏重编码的JSF介绍。在本篇中,我在简短的介绍了JSF的生命周期以后将通过一些示例代码来说明如何通过JSF来实现基于Web的用户界面以及如何利用内建的验证功能。下一篇中,我将阐述一些JSF的高级概念:实现定制验证、使用模型对象、国际化支持、生成定制组件和便于你使用组件生成HTML以外的标记语言的事件的代理和处理机制。

    Disclaimer: The code discussed in  this article was written against  the EA2 JSF  reference implementation.  As mentioned  above, the  specification and  reference implementation are in a state of flux, and therefore, the code  in  this article is guaranteed to be  obsolete in the near future; however,  the  code  works as  advertised with  the EA2  reference implementation  and was  tested with both Tomcat 4.0.6 (the latest production release of Tomcat)  and  Resin 2.1.6. Furthermore, you can read the JSF specification until the  cows come home, but  to really grasp  the concepts, you  must ruminate over  some code. 

    声明:本文中的代码均针对EA2版本的JSF参考实现编写。前面已经说明,规范和参考实现目前还在修订当中,这些代码将很快会被废弃;然而这些代码可以在EA2版本的参考实现上运行,并且在Tomcat 4.0.6和Resin 2.1.6上通过了测试。当然你也可以研读规范直至领会,但是如果你想真正掌握概念,就应该做一些深入的编码实践。

JSF的运行周期(The JavaServer Faces lifecycle)


    JSF handles HTTP requests with seven distinct phases, as shown in Figure  1.  The normal flow of control is shown with solid lines, whereas  dashed  lines show alternate  flows depending  on  whether  a component  requests  a  page redisplay  or validation  or  conversion errors occur. 
    
JSF通过7个步骤来处理一个HTTP请求,如图1。正常的处理流程通过实线标识,虚线表示一些诸如刷新显示、验证错误、转换错误等特殊情况的可选的处理流程。


    The  Reconstitute  Request  Tree  phase creates  a  component  tree  for the  requested page. If that page  previously displayed and JSF saved  the page's  state information, the state information is added to the request. This means that JSF automatically retains form information when a form redisplays;  for example, when a user does not correctly fill out a form. This handy  feature is  a  fundamental  capability  provided  by  Microsoft's  WebForms,  but is otherwise absent from J2EE. 
    
重建请求树阶段为被请求的页面创建组件树。如果这个页面曾经被访问过,JSF会保存    上次访问时的状态信息和数据,在此时将这些状态数据加入到当前的请求。这意味着当重复访问某个表单的时候JSF将自动的恢复表单数据。这个便利的功能在Microsoft的WebForms中是基本功能,但是在J2EE中则被遗漏了。

    During the Apply Request Values phase, the JSF implementation iterates  over the components  in the  component tree  and calls  each component's decode()  method. That method extracts information  from the request and stores  it in  the component. Optionally, components may delegate decoding to a renderer. 
    
在请求数据解析阶段中,JSF实现遍历组件树中所有的组件调用所有组件的decode()方    法。decode()方法将从请求中提取信息并存储到组件当中。某些情况下,组件可用于为响应合成器提取数据。

    In addition to decoding request information during the Apply Request  Values  phase, components or their  renderers may create request  events. Typically,  request  events signal  a visual  change for  one or  more components;  for  example, clicking on a graphic in a tree control may expand a branch of  the  tree.  Alternatively,  an  event  in one  component  may  update  the visual  representation of another component; for example, clicking on a leaf node in  a tree may cause an associated list to change its contents and redisplay. In either situation, a request event is generated and added to the JSF context. 
    
另外在请求数据解析阶段提取请求信息的过程中,组件或者他们的响应合成器可能会生成一些请求事件。最典型的有请求事件可能会触发了一个或多个组件的显示变化;例如当点击一个树型控件可能会展开它的分支。另外,某个组件的事件可能会更新另一个组件的显示;例如当点击一个树型控件的叶节点可能会导致和它关联的列表控件改变它的内容和显示。在任何一种情况下,都会产生一个请求事件加入到JSF的运行环境中。

    Request events, which are generated  during the Apply Request Values  phase, are  handled  during the  Handle  Request Events  phase.  During the  Handle Request  Events  phase,  the JSF  implementation  calls  the processEvents()  method for each  component that has  one or more  request events. Components  may handle request events themselves,  or they may choose to  delegate event handling to  an event  handler. The  processEvents() method  is a  boolean() method. If that method returns  false, lifecycle processing advances to  the Process Validations phase; otherwise, lifecycle processing advances directly to the Render Response phase. 

请求数据解析阶段产生的请求事件都在请求事件处理阶段处理。在请求事件处理阶段JSF实现为那些有一个或多个请求事件的组件调用processEvents()方法。这些组件将自行处理这些事件或者提交给某个事件处理器代理处理。processEvents()方法返回值为boolean。如果返回false,处理周期将前进到验证处理阶段,否则将直接跳转至响应合成阶段。

    During  the  Reconstitute Request  Tree  phase, the  JSF  implementation may register one or more validators for  any of the components in the  component  tree. In the Process Validations  phase, the JSF implementation invokes  the validate() method for each validator. Validators perform correctness  checks and return  a boolean  value from  their validate()  method; if  that method returns  true,  the  JSF lifecycle  proceeds  normally;  otherwise, the  JSF implementation invokes the Render Response phase directly. 

在重建请求树阶段,JSF实现会为请求树上的组件注册一个或多个验证器。在验证处理阶段,JSF实现调用每一个验证器的validate()方法。验证器执行validate()方法进行正确性检验以后返回一个boolean值;如果为true,JSF处理周期将继续前进;否则将直接跳转至响应合成阶段。

    Each JSF user interface component can  be associated with a field in  a Java object (known as a model  object). During the Update Model  phase, component values  are  copied   to  the  component's   model  object.  A   component's updateModel() method carries out  that data transfer. Conversion  errors can occur during this  phase because request  parameters are strings,  but model values can represent any type of Java object. If a conversion error  occurs, the JSF implementation invokes the Render Response phase directly. 
    
每一个JSF用户界面组件都关联于一个Java对象(被称为模型对象)的某个字段。在模型更新阶段,组件的值将被复制到对应的组件当中。数据传递通过模型对象的updateModel()方法调用完成。由于请求参数都是字符串而模型对象字段有可能是任何Java对象类型,如果发生转换错误,JSF实现将直接跳转至响应合成阶段。

    In a JSF application, if you submit a form or click on a link (both of which must be  represented by  JSF components),  the JSF  implementation creates a  form event or a command event, respectively. Those events are handled in the  Invoke  Application  phase by  an  application-specific handler.  Typically,  those  handlers  specify a  URL,  and the  JSF  implementation forwards  the request to  that URL.  Currently, application-specific  handlers handle form and command events  in a single  method, typically with  a switch statement. The JSF expert  group is aware  of this approach's  ugliness, and therefore, it's almost certain to change in the JavaServer Faces 1.0 release. 
    
在JSF应用中,如果你通过提交一个表单或者点击一个连接(都需要是通过JSF组件提供的),JSF实现将分别生成一个表单事件和命令事件。这些事件将在调用Web应用阶段由一个应用声明的处理器进行处理。典型的情况是处理器声明了一个URL,JSF实现将这个请求前转到这个URL中。目前应用声明的处理器对此的处理都是通过一个包含一个switch语句的单一方法进行的。JSF专家组意识到这样的方案不是很合理,因此在JSF 1.0的正式发行版将肯定会有所改变。

    Finally, the  Render Response  phase creates  a response  component tree and forwards the  response. When  a user  submits a  form, clicks  on a link, or otherwise generates a request, the cycle starts anew. 
    
最后,响应合成阶段生成一个响应组件树并发送响应。当用户再次提交一个表单或点击一个链接,总之生成一个请求,那么处理流程将重新开始。

    Now that we have  a general overview of  JavaServer Faces and a  rudimentary understanding of the JSF lifecycle, let's take a look at some code. 

现在我们已经对JSF和处理流程有了一个粗略的认识,下面将研究一些代码。


Seegeris,Bruce

你可能感兴趣的:(A first look at JavaServer Faces(jsf 1))