在Java EE 6中使用JSF 2.0简化页面制作(1)

来源:互联网 发布:网络教育文凭和函授 编辑:程序博客网 时间:2024/06/05 15:25

在Java EE 6中使用JSF 2.0简化页面制作(1)

2010-01-18 09:37 黄永兵 译 51CTO.com我要评论(0) 字号:T | T
一键收藏,随时查看,分享好友!

Java EE 6中使用了JSF 2.0,即JSR 314规范。最新的JavaServer Faces视图声明语言令创建一个JSF页面更加容易。本文介绍了新的Facelets,模板,混合组件以及行为监听器,并介绍了JSF 2.0的Ajax支持以及其他的一些新特性。

AD:


    【51CTO精选译文】过去几个星期,51CTO对Java EE 6的新特性进行了一系列介绍。除了Servlet 3.0的特性,Java EE 6也使用了新的JSF 2.0标准。下面我们来看一看JSF 2.0是如何简化页面制作并提供Ajax支持的。最后,我们对Servlet 3.0和JSF 2.0的新特性进行了总结。

    简化JSF 2.0页面制作

    JavaServer Faces技术提供了一个服务端组件框架,简化了Java EE应用程序用户界面的开发,其中最显著的改进是页面制作,通过使用标准的JavaServer Faces视图声明语言(JavaServer Faces View Declaration Language,俗称Facelets)创建一个JSF页面更加容易。

    Facelets

    Facelets是一个强大的轻量级声明语言,可以使用它展示一个JSF页面,使用Facelets时,你可以使用HTML风格的模板展示一个JSF页面,也可以构建一个组件树,JSF应用程序中的用户界面通常是由JSF组件构成的JSF页面,Facelets在JSP之上提供了更多优点。

    在JSP中,Web页面中的元素是按照渐进顺序处理和渲染的,而JSF提供了它自己的处理和渲染顺序,这可能会导致不可预测的行为发生,Facelets解决了这个问题,通过模板,Facelets也允许代码复用,可以大大减少开发UI的时间,现在Facelets已经成为构建JSF应用程序的首选技术。

    Facelets通常是使用XHTML标记语言编写的,因此Facelets是可以跨不同开发平台的,下面是Java EE 6教材中提供的JSF页面的Facelets XHTML代码部分:

    1. <xml version="1.0" encoding="UTF-8"?> 
    2.            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
    3.            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    4.    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" 
    5.            xmlns:f="http://java.sun.com/jsf/core" 
    6.            xmlns:h="http://java.sun.com/jsf/html" 
    7.            xmlns:ui="http://java.sun.com/jsf/facelets"> 
    8.    <head> 
    9.            <title>Guess Number JSF Application</title> 
    10.    </head> 
    11.    <body> 
    12.       <h:form> 
    13.        <h2> 
    14.        Hi. My name is Duke. I am thinking of a number from <b> 
    15.               <h:outputText value="#{UserNumberBean.minimum}"/> to  
    16.               &nbsp;&nbsp;<b> 
    17.        <h:outputText value="#{UserNumberBean.maximum}"/>.  
    18.        <p> 
    19.          Can you guess it ?  
    20.        </p> 
    21.        <h:graphicImage id="waveImg" url="/wave.med.gif" /> 
    22.        <h:inputText id="userNo" 
    23.              value="#{UserNumberBean.userNumber}"> 
    24.           converterMessage="#{ErrMsg.userNoConvert}"> 
    25.        <f:validateLongRange 
    26.              minimum="#{UserNumberBean.minimum}" 
    27.              maximum="#{UserNumberBean.maximum}"/> 
    28.        </h:inputText> 
    29.        <h:commandButton id="submit" 
    30.              action="success" value="submit" /> 
    31.        <h:message showSummary="true" showDetail="false" 
    32.                   style="color: red;  
    33.                    font-family: 'New Century Schoolbook', serif;  
    34.                    font-style: oblique;  
    35.                    text-decoration: overline"  
    36.                    id="errors1" 
    37.                    for="userNo"/> 
    38.        </h2> 
    39.       </h:form> 
    40.    </body> 
    41.    </html> 
    42.  

    页面渲染效果如图1所示。

    使用Facelets创建的用户界面 
    图 1 使用Facelets创建的用户界面

    这个Facelets XHTML页面和普通JSP页面并没有多大不同,Facelets支持JSF和JSTL标签库,它也包括一个Facelets标签库,支持功能丰富的页面模板。命名空间声明xmlns:ui="http://java.sun.com/jsf/facelets"就是针对facelets标签库的,但这里没有使用facelets标签库的标签,facelets也支持统一的表达式语言。

    模板

    使用模板,你可以创建一个页面作为应用程序中其它页面的模板,这样可以避免多次创建结构类似的页面,同时也可以统一应用程序中多个页面的视觉风格。

    Facelets标签库包括一个模板标签<ui:insert>,为了实施模板化,首先创建一个包括<ui:insert>标签的模板页面,然后创建一个使用这个模板的客户端页面,在客户端页面中,使用<ui:composition>标签指定模板,使用<ui:define>标签指定插入到模板中的内容。

    下面是一个模板页面的内容:

    1. <xml version="1.0" encoding="UTF-8"?> 
    2.    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
    3.    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    4.  
    5.    <html xmlns="http://www.w3.org/1999/xhtml" 
    6.          xmlns:ui="http://java.sun.com/jsf/facelets" 
    7.          xmlns:h="http://java.sun.com/jsf/html" 
    8.  
    9.       <head> 
    10.          <title><ui:insert name="title">Page Title</ui:insert</title><body> 
    11.       </head> 
    12.       <body> 
    13.           <div> 
    14.               <ui:insert name="Links"/> 
    15.           </div> 
    16.           <div> 
    17.               <ui:insert name="Data"/> 
    18.          </div> 
    19.       </body> 
    20.    </html> 
    21.  

    下面是使用这个模板的客户端页面代码:

    1. <xml version="1.0" encoding="UTF-8"?> 
    2.     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
    3.  
    4.     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    5.  
    6.     <html xmlns="http://www.w3.org/1999/xhtml" 
    7.           xmlns:ui="http://java.sun.com/jsf/facelets" 
    8.           xmlns:h="http://java.sun.com/jsf/html" 
    9.      <body> 
    10.        <ui:composition template="/template.xhtml"> 
    11.            This text will not be displayed.  
    12.            <ui:define name="title"> 
    13.                Welcome page  
    14.            </ui:define> 
    15.            <ui:define name="Links"> 
    16.                ... [Links should be here]  
    17.            </ui:define> 
    18.            <ui:define name="Links"> 
    19.                ... [Data should be here]  
    20.            </ui:define> 
    21.        </ui:composition> 
    22.            This text also will not be displayed.  
    23.      </body> 
    24.     </html> 

    当客户端调用这个模板时,它使用标题Welcome Page渲染这个页面,这个页面显示了两部分内容,一个显示客户端中指定的链接列表,另一个显示客户端中指定的数据。

    混合组件

    混合组件时JSF中的一个新特性,通过它创建自定义JSF组件会更加容易。你可以使用JSF页面标记和其它JSF组件创建混合组件。在Facelets的标注下,任何XHTML页面都可以变成一个混合组件。此外,混合组件可以有验证器,转换器和监听器。

    创建好混合组件后,你可以将它保存到库中,以后有需要时就可以调用了。

    让我们创建一个渲染为登录面板的混合组件,用户登录时,组件反馈一个登录事件,如图2所示。

    登录面板混合组件 
    图 2 登录面板混合组件

    下面是混合组件的源代码:

    1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
    2.    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    3.    <html xmlns="http://www.w3.org/1999/xhtml" 
    4.       xmlns:h="http://java.sun.com/jsf/html" 
    5.       xmlns:f="http://java.sun.com/jsf/core"> 
    6.       xmlns:f="http://java.sun.com/jsf/facelets"> 
    7.       xmlns:composite="http://java.sun.com/jsf/composite"> 
    8.  
    9.    <h:head> 
    10.    <title>This content will not be displayed in the rendered output</title> 
    11.    </h:head> 
    12.  
    13.    <h:body> 
    14.     <composite:interface> 
    15.            <composite:actionSource name="loginEvent"/> 
    16.     </composite:interface> 
    17.     <composite:implementation> 
    18.      <table> 
    19.     <tr> 
    20.        <td>Username:  <h:inputText id="username" /> </td> 
    21.     </tr> 
    22.     <tr> 
    23.        <td>Password: <h:inputSecret id="password" /></td> 
    24.     </tr> 
    25.     <tr> 
    26.        <td><h:commandButton value="Login" id="loginEvent" /></td> 
    27.     </tr> 
    28.      </table> 
    29.     </composite:implementation> 
    30.    </h:body> 
    31.    </html> 
    32.  

    xmlns:composite="http://java.sun.com/jsf/composite"声明了混合UI组件的命名空间,<composite:interface>标签声明混合组件的使用契约,<composite:attribute>标签在使用契约中指定<composite:actionSource>标签,这个表示组件可以暴露一个事件,让使用这个混合组件的页面可以轻松访问它。
    <composite:implementation>标签定义了混合组件的实现,这里的实现是一个简单的表,它包括用户名、密码和登录按钮JSF组件。

    为了让混合组件可用,将代码保存为XHTML文件,将文件放到应用程序根目录下resources目录的子目录中即可。子目录的名字可以采用包含混合组件的资源库名字,JSF运行时通过向混合组件的标签名后追加.xhtml后缀查找混合组件。例如,如果你将标签命名为loginPanel,那么保存为混合组件的文件名就是loginPanel.xhtml。然后你就可以在Web页面中使用混合组件了,下面就是一个使用混合组件的Web页面代码示例:

    1. <!DOCTYPE html  
    2.    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
    3.    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    4.    <html xmlns="http://www.w3.org/1999/xhtml" 
    5.       xmlns:h="http://java.sun.com/jsf/html" 
    6.       xmlns:f="http://java.sun.com/jsf/core" 
    7.       xmlns:ui="http://java.sun.com/jsf/facelets" 
    8.       xmlns:ez="http://java.sun.com/jsf/composite/ezcomp"> 
    9.  
    10.    <head> 
    11.    <title>Example 01>/title> 
    12.    <style type="text/css"> 
    13.    .grayBox { padding: 8px; margin: 10px 0; border: 1px solid #CCC; background-color: #f9f9f9;  }  
    14.    </style> 
    15.    </h:head> 
    16.  
    17.    <h:body> 
    18.      <p>Usage of Login Panel Component</p> 
    19.  
    20.         <ui:debug hotkey="p" rendered="true"/> 
    21.  
    22.      <h:form> 
    23.          <div id="compositeComponent" class="grayBox" style="border: 1px solid #090;"> 
    24.             <ez:loginPanel> 
    25.                 <f:actionListener for="loginEvent" type="example01.LoginActionListener" /> 
    26.  
    27.             </ez:loginPanel> 
    28.          </div> 
    29.      <p><h:commandButton value="reload" /></p> 
    30.  
    31.      <p><h:outputText value="#{loginActionMessage}" /></p> 
    32.      </h:form> 
    33.  
    34.    </h:body> 
    35.    </html> 
    36.  

    注意声明xmlns:ez="http://java.sun.com/jsf/composite/ezcomp",它指定了混合组件的命名空间和前缀,这里的ezcomp是资源目录的子目录名,JSF使用下面的约定:所有命名空间URI都以http://java.sun.com/jsf/composite/开头,使用资源库的名称结束。

    <f:actionListener>

    标签关联混合组件的行为监听器,标签中的for属性表示这个监听器是为混合组件上名为loginEvent行为事件准备的,你需要编写代码来处理事件,例如:

    1. import javax.faces.component.UIComponent;  
    2.  import javax.faces.component.ValueHolder;  
    3.  import javax.faces.context.FacesContext;  
    4.  import javax.faces.event.AbortProcessingException;  
    5.  import javax.faces.event.ActionEvent;  
    6.  import javax.faces.event.ActionListener;  
    7.  
    8.  public class LoginActionListener implements ActionListener {  
    9.  
    10.      public void processAction(ActionEvent event) throws AbortProcessingException {  
    11.          FacesContext context = FacesContext.getCurrentInstance();  
    12.          context.getExternalContext().getRequestMap().put("loginActionMessage",  
    13.                  "Login event happened");  
    14.      }  
    15.  }  
     
     
     
     

    JSF 2.0对Ajax的支持

    JSF 2.0天生就支持Ajax,利用Ajax技术,Web应用程序在后台以异步的方式从服务器获取数据。支持Ajax后,允许页面局部刷新,允许选择视图中的一个组件进行处理而不影响其它组件。

    要在JSF中使用Ajax,需要访问有资源标识符的JavaScript资源jsf.js,它存在于javax.faces资源库中,包含让JSF与Ajax交互的JavaScript API,JavaScript API由一组标准的JavaScript函数组成,使JavaServer Faces框架中的Ajax操作变得简单了,你几乎不用直接包括这个文件,当你使用任何开启Ajax的标签或组件时,JSF会自动包括它。然后你就可以使用<f:ajax>标签或调用JavaScript API中的函数了。

    下面是一个使用<f:ajax>标签的示例:

    1. <h:commandButton id="button1"> 
    2.       <f:ajax execute="..." render="..."/> 
    3.    </h:commandButton> 
    4.  

    这里的<f:ajax>标签是嵌套在<h:commandButton>标签内的,这样会结合在execute属性中指定的Ajax行为和<h:commandButton>标签呈现的命令按钮,你也可以指定一个event属性来识别JavaScript DOM事件,如果你不指定event属性,JSF使用组件的默认行为,这里的默认行为是onclick,因此JSF结合execute属性中指定的Ajax请求和呈现按钮的onclick事件。用户点击该按钮时,JSF提交Ajax请求给服务器。

    使用<f:ajax>标签的一个好处是不用在页面中指定载入jsf.js,它会自动为你载入,相比之下,如果你调用JavaScript API,首先需要使用<h:outputScript>让jsf.js对当前视图可用,例如:

    1. <f:view contentType="text/html"/> 
    2.      <h:head> 
    3.        <meta... 
    4.        <title... 
    5.      </h:head> 
    6.      <h:body> 
    7.        ...  
    8.        <h:outputScript name="jsf.js" library="javax.faces" target="body"/> 
    9.        ...  
    10.      </h:body> 
    11.      ...  
    12.  

    然后才可以使用JavaScript API中的函数产生Ajax请求。例如,你使用JavaScript函数jsf.ajax.request向服务器发送一个请求,如下面的代码:

    1. <h:commandButton id="button1" value="submit"> 
    2.    onclick="jsf.ajax.request(this,event);" /> 
    3.  

    代码包括一个<h:commandButton>标签,它呈现为一个按钮,用户点击这个按钮时,向服务器提交一个Ajax请求。

    Servlet 3.0和JSF2.0中的更多新特性

    Servlet 3.0中另一个新特性是允许你使用ServletContext类中的方法通过编程在Web应用程序启动时向其添加Servlet和Servlet过滤器,使用addServlet()方法添加Servlet,使用addFilter()添加Servlet过滤器。结合可插拔式共享框架特性,Web框架可以在无开发人员介入的情况下实现自我配置。

    • Java EE 6总览:平台的主要目标
    • Java EE 6引入的三大新技术之JAX-RS
    • Java EE 6数据验证新框架:Bean验证
    • Java EE 6增强的可扩展性:Web分片和可插
    • Java EE 6新特性之Servlet 3.0的异步处理
    此外Servlet 3.0加入了许多安全特性,除了声明安全外,Server 3.0通过HttpServletRequest接口提供了编程安全,例如,你可以在应用程序中使用HttpServletRequest的authenticate()方法执行用户名和密码的收集,或者使用login()方法指向容器验证一个非强制请求上下文中的请求调用者。有关Servlet 3.0的更多特性,请参阅JSR 315规范。

    JSF 2.0中的一些额外增强与资源如何打包和处理有关,JSF 2.0标准化了打包哪里的资源。所有资源都放在resources目录或一个子目录下,资源需要按顺序正确地进行渲染,例如CSS文件和JavaScript文件,图3显示了Netbeans中的一个JSF项目部分结构及文件,注意其中的resources目录,CSS和images目录。

    JSF应用程序中resources目录下的资源 
    图 3  JSF应用程序中resources目录下的资源

    JSF 2.0也包括显示和处理资源的API,使用javax.faces.application.Resource类显示一个资源,使用javax.faces.application.ResourceHandler类创建资源的实例。有关JSF 2.0的更多信息,请参阅JSR 314规范。

    【51CTO.com译稿,非经授权请勿转载。合作站点转载请注明原文译者和出处为51CTO.com,且不得修改原文内容。】

    原文:Introducing the Java EE 6 Platform 作者:Ed Ort

    原创粉丝点击