一个简单的JSF例子

一个简单的JSF例子(

A simple JavaServer Faces example)
    Figures  2a,  2b,  and  2c   show  a  very   simple  JSF   application.  The application's opening  page contains  a link  that  starts  the application.  That link points  to a JSP  page that displays  a simple form.  Because this  simple application does  not perform  validation, you can  click the  Log In button  without  filling  in  the  name  and  password  fields,  which  will transport  you  to  another  JSP  page  that  welcomes  you  to  JavaServer Faces. 
    
图2a、2b、2c展示了一个简单的JSF应用。这个应用的入口页面包含一个启动应用的链接。这个链接指向一个显示一个简单表单的JSP页面。由于这个简单的应用不进行验证操作,所以你在表单的姓名和密码域中不用输入任何内容直接点击Log In按钮,你将被引导到另外一个欢迎你使用JSF的JSP页面。

图 2a 一个简单的JSF应用

图 2b JSF登录界面

图 2c欢迎信息

    First, let's explore the logistics of implementing this simple application,
and JavaServer Faces applications in general. JSF requires the following jar files in the WEB-INF/lib directory: 
    
首先,我们浏览一下这个简单的应用和通常的JSF应用需要的支持。JSF需要在WEB-INF/lib目录下存放有一下文件:

WEB-INF/lib/commons-beanutils.jar 
WEB-INF/lib/commons-collections.jar 
WEB-INF/lib/commons-digester.jar 
WEB-INF/lib/commons-logging-api.jar 
WEB-INF/lib/jsf-api.jar 
WEB-INF/lib/jsf-ri.jar 
WEB-INF/lib/jstl.jar 
WEB-INF/lib/standard.jar 

    The jar  files listed  above are  all you  need for  JSF applications.  Even though, as  we will  see shortly,  JSF applications  typically use  JSP tags implemented by  the JSF  implementation, there  are no  separate tag library descriptor (TLD)  files because  that information  is contained  in the  jar files. 

JSF应用需要的所有内容就是上面列举的这些jar文件。当然,我们很快会注意到,JSF应用通常会使用JSF实现中实现的JSP 标签,但是并不需要额外的标签库描述符(TLD)因为这些信息也包含在上面的jar文件中。

    Here's a listing of the other  files that comprise the application shown  in  Figure 2: 

下面是一些我们这个JSF应用需要的其他文件的清单。

WEB-INF/web.xml 
WEB-INF/classes/com/sabreware/listeners/SimpleContextListener.java 
WEB-INF/classes/com/sabreware/appHandlers/SimpleApplicationHandler.java 
/index.html 
/index.jsp 

示例1 WEB-INF/web.xml


Example 1. WEB-INF/web.xml 

<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC
  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
   <!-- Context Listener creates and sets the application handler -->
   <listener>
      <listener-class>
         com.sabreware.listeners.SimpleServletContextListener
      </listener-class>
   </listener>

   <!-- Faces Servlet -->
   <servlet>
      <servlet-name>Faces Servlet</servlet-name>
      <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet>

   <!-- Faces Servlet Mapping -->
   <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>/faces/*</url-pattern>
   </servlet-mapping>

   <welcome-file-list>
      <welcome-file>index.html</welcome-file>
   </welcome-file-list>
</web-app>


    The deployment descriptor listed above declares four things: 
    A servlet context listener 
    A controller servlet 
    A mapping for the controller servlet 
    A welcome file 
    
上面的部署描述符声明了四项内容:
    1. 一个Servlet环境(Context)监听器
    2. 一个控制器Servlet
    3. 控制器Servlet的映射
    4. 一个欢迎页面

    The deployment descriptor listed in Example 1 associates the JSF controller servlet with the URL /faces/*, which causes the servlet container to map all URLs that  start with  /faces to  the JSF  controller servlet.  JSF uses the controller servlet to control the JSF lifecycle. 
    
    部署描述符将/faces/*这样的URL请求和JSF控制器servlet关联起来,这使得servlet容器将把所有以/faces开头的URL请求映射到这个JSF控制器servlet页面。JSF使用这个控制器servlet控制JSF处理流程。

示例2 servlet运行环境监听器


Example 2. WEB-INF/com/sabreware/listeners/SimpleServletContextListener 

  1. package com.sabreware.listeners;
  2.  
  3. import javax.servlet.*;
  4. import javax.faces.*;
  5. import javax.faces.lifecycle.*;
  6. import com.sabreware.appHandlers.SimpleApplicationHandler;
  7.  
  8. public class SimpleServletContextListener implements ServletContextListener {
  9.    public void contextInitialized(ServletContextEvent e) {
  10.       LifecycleFactory factory = (LifecycleFactory)
  11.         FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
  12.  
  13.       Lifecycle lifecycle = factory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
  14.  
  15.       lifecycle.setApplicationHandler(new SimpleApplicationHandler());
  16.    }
  17.    public void contextDestroyed(ServletContextEvent e) {
  18.       // Nothing to do here
  19.    }
  20. }



    Servlet containers create servlet  context listeners at application  startup and invoke the listener's contextInitialized() method. When the  application shuts down, the servlet container invokes the listener's  contextDestroyed() method. The  servlet context  listener listed  above creates  an application handler  and  associates it  with  the JSF  lifecycle.  Application handlers handle application  events and  specify a  URL that  the JSF  implementation subsequently forwards to, as illustrated by the application handler  created in Example 2 and listed in Example 3. 
    
servlet容器在应用启动时生成servlet运行环境监听器并调用监听器的contextInitialized()方法。当应用终止时servlet容器调用监听器的contextDestroyed()方法。上文中的servlet运行环境监听器生成一个应用句柄并把它和运行流程关联。应用句柄处理应用事件并且声明JSF实现后续将要将请求前转的URL,过程在示例2和示例3中说明。

示例3 SimpleApplicationHandler


Example 3. WEB-INF/com/sabreware/appHandlers/SimpleApplicationHandler 

  1. package com.sabreware.appHandlers;
  2.  
  3. import javax.faces.FactoryFinder;
  4. import javax.faces.context.FacesContext;
  5. import javax.faces.event.FacesEvent;
  6. import javax.faces.lifecycle.ApplicationHandler;
  7. import javax.faces.tree.TreeFactory;
  8.  
  9. public class SimpleApplicationHandler implements ApplicationHandler {
  10.    public boolean processEvent(FacesContext context, FacesEvent facesEvent) {
  11.       TreeFactory treeFactory = (TreeFactory)FactoryFinder.
  12.         getFactory(FactoryFinder.TREE_FACTORY);
  13.       context.setResponseTree(
  14.         treeFactory.getTree(context.getServletContext(),
  15.                             "/welcome.jsp"));
  16.       return true;
  17.    }
  18. }

    In  the  JSF  lifecycle's  Render  Response  phase,  the  JSF implementation forwards to a URL. That URL  represents a component tree, which is  known as  the response tree.  The application handler  listed above sets  the response tree to /welcome.jsp,  and the JSF  implementation subsequently forwards  to that URL after the application handler is invoked (in the Invoke Application phase  of  the  JSF  lifecycle).  Our  simple  example  only  generates  one  application  event—a  form  event  generated  when  the  Log  In  button is  activated. JSF applications  can generate two  types of application  events: form events and command events. Command events are generated when you  click on a link. 

在JSF处理流程中的响应合成阶段,JSF实现将请求前转到一个URL中。这个URL创建一个叫做响应树的组件树。上文的应用句柄将这个响应树赋予/welcome.jsp,在应用句柄被激活(在调用Web应用阶段)以后JSF实现紧接着前转到这个URL。我们的这个简单的应用仅生成一个应用事件——当Log In按钮被按下时触发的表单事件。JSF应用可以生成两种类型的应用事件:表单事件和命令事件。命令事件通过点击链接生成。

    The servlet context listener listed in Example 2 and the application handler listed in  Example 3  work hand  in hand.  The context  listener creates the  application handler, and  the application handler  specifies a URL  that the  JSF implementation forwards to when the login form is submitted.
    
示例2中的servlet运行环境监听器和示例3中的应用句柄协同工作。运行环境监听器生
成应用句柄,而应用句柄声明了当login表单提交时JSF实现所应当前转的URL。

The welcome file, /index.html, is listed in Example 4. 

示例4 欢迎文件,/index.html


Example 4. /index.html 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
   <head>
      <title>A Simple JavaServer Faces Application</title>
   </head>

   <body>
      <font size='4'>Welcome to a simple JavaServer Faces Application</font>
      <p>
      <a href='faces/index.jsp'>Click here to start the application</a>
   <body>
</html>


    The welcome file listed above creates a link to the first JSP page displayed by  the application.  All JSF  applications must  route the  first JSP  page  displayed by  the application  through the  JSF controller  servlet. You can  either  provide an  HTML page  that contains  a link  to that  JSP page,  as  illustrated in this example, or you can rely on the user to type the correct URL  to  start  the application.  Unfortunately,  neither  solution is  very appealing;  hopefully, JSF  1.0 will  provide a  mechanism to  obviate this requirement. 
    
上文的欢迎文件包含一个指向这个JSF应用显示的第一个JSP页面的链接。所有的JSF应都必须通过JSF控制器导向到各自应用所显示的第一个JSP页面。你可以象示例一样提供一个包含指向这个JSP页面的链接的HTML页面,或者让用户直接输入正确的URL地址以便激活应用。不幸的是,它们都不是很方便;希望在JSF 1.0版本中能提供满足这个需求的机制。

The application's initial JSP page is listed in Example 5. 

示例 5 应用的初始JSP页面


Example 5. /index.jsp 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
   <head>
      <title>A Simple JavaServer Faces Application</title>
   </head>

   <body>
      <%@ taglib uri="http://java.sun.com/j2ee/html_basic/" prefix="faces" %>

      <font size="4">Please enter your name and password</font>
      
      <faces:usefaces>
         <faces:form id="simpleForm" formName="simpleForm">
            <table>
               <tr>
                  <td>Name:</td>
                  <td><faces:textentry_input id="name"/></td>
               </tr>

               <tr>
                  <td>Password:</td>
                  <td><faces:textentry_secret id="password"/></td>
              </tr>
            </table>

            <p><faces:command_button id="submit" commandName="Log In"/>
         </faces:form>
      </faces:usefaces>
   </body>
</html>

    The preceding JSP page is where most of the action takes place in our simple application. JSF provides JSP tags  for all of the standard  components that  JSF  supports.  Those  tags  must   be  contained  within  the  body   of  a  <faces:usefaces> tag. The JSP page  listed above uses the <faces:form>  tag,  which   creates  an   HTML  form,   and  the   <faces:textentry_input>  and  <faces:textentry_secret> tags, which render an HTML text element and an HTML  password   element,   respectively.   The    JSP   page   also   uses    the  <faces:command_button> tag, which renders an HTML Submit button. 
    
前面的这个JSP页面包含了我们这个简单的应用中大多数的动作。JSF提供了所有JSF支持的标准的组件的JSP 标签。这些tags都必须包含在一个<faces:usefaces>标签所标记的块中。上面的页面通过<faces:form>标签生成一个HTML的表单,<faces:texentry_input> 标签和<faces:textentry_secret>标签分别生成一个HTML的文本输入框和密码输入框。同样通过<faces:command_button>标签提供一个HTML的提交按钮。

    When the  form in  the preceding  JSP page  is submitted,  the JSF lifecycle begins,  and  the  application handler  subsequently  invokes.  That handler  specifies  /welcome.jsp as  the response  tree, and  the JSF  implementation subsequently forwards to that JSP page, which is listed in Example 6. 
    
当前面这个JSP页面中的表单被提交时,JSF的处理流程开始了,应用句柄被调用。这个应用句柄声明/welcome.jsp作为响应树,并且JSF实现随之将请求前转到这个JSP页面中,示例 6说明了这个处理过程。

示例6 /welcome.jsp


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
   <head>
      <title>A Simple JavaServer Faces Application</title>
   </head>

   <body>
      Welcome to JavaServer Faces!
   </body>
</html>


    Now that we've seen  how a simple JSF  application works, let's extend  that application by adding field validation. 
    
现在我们已经看到了一个简单的JSF应用是如何工作的,下面让我们扩展一下加入字段的验证。

用JSF进行验证


    JavaServer Faces provides built-in  validation and a framework  for creating custom validators. Built-in validation is discussed below; custom validation will be discussed in Part 2. 
    
JSF提供了内建的验证和创建定制的验证的框架。我们首先讨论内建的验证,定制的验证将在第二部分讨论。

内建的验证(Built-in validation)


    JavaServer Faces provides the following built-in validators: 

JSF提供了以下内建的验证器:

    DoubleRangeValidator 
    LengthValidator 
    LongRangeValidator 
    RequiredValidator 
    StringRangeValidator 
    
    The preceding list of validators represent class names. Those classes reside  in   the   javax.faces.validator  package.   The  DoubleRangeValidator  and LongRangeValidator  validate that  a request  parameter (which  is always  a  string) can convert to either a double or long, respectively, and that those  values fall within a specified range. The LengthValidator checks the  string length  of  a  request  parameter against  minimum  or  maximum  values. The RequiredValidator  requires  a  non-null  value  for  a  given  field.   The StringRangeValidator converts a  string into either  a long or  a double and  checks that value against specified minimum or maximum values. 
    
前面罗列的是验证器的类名。这些类都在javax.faces.validator包中。DoubleRangeValidator    和LongRangeValidator验证一个请求参数是否可以转换成为一个双精度浮点数或长整数    并且在某个指定的范围内。LengthValidator验证阐述的长度是否在指定的最小和最大值之间。RequiredValidator检验必须提供的字段是否有非空的数值。StringRangeValidator将一个字符串转换为长整数或者双精度浮点数同时验证是否在指定的最小和最大值之间。

图 3 JSF内建的验证器
    Figure 3 shows an error message generated by a length validator. The minimum length was specified  as three, but  the value entered  in the corresponding field was only two characters, so a validation error and corresponding error  message were generated when the field's corresponding form was submitted. 
    
图3显示了长度验证器生成的错误信息。最短长度声明为3,但是输入的数据的长度为2,所以当该页面提交的时候出现一个验证错误同时生成了错误信息。

    Example 7 lists the JSP page shown in Figure 3. 
    
示例 7 图 3中的JSP页面。

示例 7. 使用长度验证器(Use the LengthValidator)


<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN'>
<html>
   <head>
      <title>A Simple JavaServer Faces Application</title>
   </head>

   <body>
      <%@ taglib uri='http://java.sun.com/j2ee/html_basic/' prefix='faces' %>

      <font size='4'>Please enter your name and password</font>

      <faces:usefaces>
         <faces:form id='simpleForm' formName='simpleForm'>
            <table>
               <tr>
                  <td>Name:</td>
                  <td>
                     <faces:textentry_input id='name'> 
                        <faces:validator 
                          className='javax.faces.validator.LengthValidator'/>
                           <faces:attributename=
                             'javax.faces.validator.LengthValidator.MINIMUM'
                              value='3'/>
                      </faces:textentry_input>
                  </td>

                  <td>
                     <faces:validation_message componentId='name'/>
                  </td>
               </tr>

               <tr>
                  <td>Password:</td>
                  <td>
                     <faces:textentry_secret id='password'/> 
                  </td>
               </tr>
            </table>

            <p><faces:command_button id='submit' commandName='Log In'/>
         </faces:form>
      </faces:usefaces>
   </body>
</html>


    As evidenced  by the  preceding JSP  page, JSF  validators are  easy to use: simply add a <faces:validator> tag and one or more <faces:attribute> tags to the  body of  the component  you want  to validate.  Validators store  error
messages in  the JSF  context when  validation fails;  you can extract those error messages with the  <faces:validation_message>, which lets you  specify the component to which those messages apply. 
    
就像前面的JSP页面所说明的,JSF的验证器是非常易于使用的:简单的添加一个<faces:validator>标签和一个或几个<faces:attribute>标签到你希望进行验证的组件中。当验证失败的时候,验证器会将错误信息存储于JSF的运行环境中;你可以使用<faces:validation_message>解析这些信息,它是用于标识具体哪个组件将使用这些信息的。

仍有更多(More to come)


    JSF  represents a  new paradigm  for developing  J2EE applications.With    a well-defined     request    processing     lifecycle,    event     handling, validation, and  a rich  component hierarchy  for developing  complex custom  components that can write to  multiple devices, JSF will greatly  facilitate   the development of J2EE application Web tiers. 
    
JSF提出了一种新的开发J2EE应用的框架。通过良好定义的请求处理流程、事件处理、验证机制和可以用于多种设备的用于开发复杂的定制组件的丰富的组件库,JSF将极大的推动基于Web的多层的J2EE应用的开发。

    In this article, I introduced basic JavaServer Faces concepts, including the JSF lifecycle,  using JSF  standard components  and their  corresponding JSP  tags, and built-in validation. In Part  2, I will discuss more advanced  JSF features,  including  custom validation,  internationalization,  using model objects, and implementing custom components. 

通过本文,我介绍了基本的JSF概念,包括JSF处理流程、使用JSF标准组件和对应的标签和内建的验证机制。在第二部分中,我将讨论更多的JSF高级特性,包括定制验证、国际化支持、使用模型对象和实现定制组件。

About the author


David Geary is the author of Core JSTL Mastering the JSP Standard Tag Library (Prentice Hall, 2002; ISBN: 0131001531); Advanced JavaServer Pages (Prentice Hall, 2001; ISBN: 0130307041); and the Graphic Java series (Sun Microsystems Press). David has been developing object-oriented software with numerous object-oriented languages for 18 years. Since the GOF Design Patterns book was published in 1994, David has been an active proponent of design patterns and has used and implemented design patterns in Smalltalk, C++, and Java. In 1997, David began working full-time as an author and occasional speaker and consultant. David is a member of the expert group defining the JSP Standard Tag Library, and is a contributor to the Apache Struts JSP framework. He writes JavaWorld's Java Design Patterns column.

Resources 


•    Download the source code that accompanies this article: 
http://www.javaworld.com/jw-11-2002/jsf/jw-1129-jsf.jar 
•    An integration strategy for Struts and JavaServer Faces: 
http://www.mail-archive.com/struts-dev@jakarta.apache.org/msg08457.html 
•    Download the JSF specification, the reference implementation, two sample applications, and a JSF tutorial from: 
http://java.sun.com/j2ee/javaserverfaces 
•    Browse the JavaServer Pages section of JavaWorld's Topical Index: 
http://www.javaworld.com/channel_content/jw-jsp-index.shtml 
•    Browse the Enterprise Java section of JavaWorld's Topical Index: 
http://www.javaworld.com/channel_content/jw-enterprise-index.shtml 
•    David Geary's Java Design Patterns column in JavaWorld: 
http://www.javaworld.com/columns/jw-java-design-patterns-index.shtml 
•    Visit JavaWorld's Enterprise Java discussion: 
http://forums.devworld.com/webx?50@@.ee6b80a 
•    Sign up for JavaWorld's free weekly Enterprise Java email newsletter: 
http://www.javaworld.com/subscribe 
•    You'll find a wealth of IT-related articles from our sister publications at IDG.net  
 
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页