Facelets 简介
本文档介绍在 NetBeans IDE 中使用 JavaServer Faces 视图定义框架的基本知识。此框架被更普遍地称作 "Facelets"。
在本教程结束时,您将完成一个简单的 Facelets 应用程序。其同官方 Facelets 开发者文档中的“入门”部分提供的完全一样。部署完整的应用程序之后,程序将提示您猜一个数字:

当您输入数字并单击“提交”之后,JavaBean 将充当应用程序控制器,如果数字太小,则返回如下消息:

如果数字太大则显示以下消息:

最终,如果提交了正确的数字,它将祝贺您:

在本教程中,您将利用由 Petr Pisl 和 Po-Ting Wu 创建并维护的针对 NetBeans IDE 的 Facelets 支持模块。
目录

要学习本教程,您需要具备以下软件和资源。
有关 Facelets 的更多信息,请参见 https://facelets.dev.java.net/有关 NetBeans IDE 中支持 Facelets 的详细信息,请参见 https://nbfaceletssupport.dev.java.net/此处描述了针对 NetBeans 的 Facelets 支持模块提供的所有功能。如果您熟悉 Facelets,欢迎您向 NetBeans IDE 的 Facelets 支持模块贡献代码。
设置环境
在开始编写 Facelets 应用程序之前,您必须确保具备所有必要的软件并且正确设置了项目。安装 NetBeans IDE 的 Facelets 支持模块之后,您将用一个向导来设置 Facelets 应用程序所需的基本文件。
安装 Facelets 插件
开始之前,您必须安装构成针对 NetBeans IDE 的 Facelets 支持模块的插件。这些插件来自 NetBeans IDE 6.5 Beta 更新中心。要下载并安装插件,打开“工具”->“插件”,并在“可用插件”标签中找到 Facelets。安装以下插件:
- Facelets 支持
- 简单 JSF/Facelets 代码片段
- Facelets 库 1.1.14 版(隐藏)
- Facelets 核心库(隐藏)
目录结构和项目设置
您的应用程序的源文件结构必须包含 Facelets JAR 文件、Web.xml 文件中的 Facelets servlet 的注册以及主页等标准页面。因为您使用的是 IDE,因此不需要手动创建所有这些文件。相反,您可以使用向导来完成这些任务。特别地,在 Facelets 应用程序的上下文中,Web 应用程序向导的最后一个面板将非常有用。
- 选择“文件”>“新建项目”。在“类别”下,选择 "Java Web"。在“项目”下,选择“Web 应用程序”。单击“下一步”。
- 在“名称和位置”面板的“项目名称”中键入 NumberGuess。将项目位置更改为计算机上的任意目录。
- 在“服务器”下拉列表中,确保您选择的是 GlassFish v2。
- 保留其他设置不变。或者,如果愿意,您可以更改它们。Facelets 支持 J2EE 1.4,也支持 Java EE 5。单击“下一步”。
- 在“框架”面板中,选择 Facelets。您将看到以下选项:
上面“配置”面板中的字段提供了以下信息:
- 调试。指定在呈现过程中出现错误时,在易于使用的屏上输出调试信息的 FaceletViewHandler。
- 创建样例 Facelets 文件。指定单击“完成”按钮时将创建两个 Facelets 模板文件。
- 跳过注释。通知编译器跳过注释,该值缺省为 true。尽管您在页面中注释了代码,标记将不会被编译,但是表达式(EL)仍然会被编译并求值,输出到文档,就像它们被内嵌到代码一样。跳过注释将从文档中彻底删除所有注释。
- Faces 后缀。将用于 Facelets 文件来显示用的后缀。
- Faces Servlet 映射。显示 servlet 将在Web.xml 文件中出现的映射。
上面“库”面板中的字段提供了以下信息:
- 注册库。指定一个在“库管理器”中注册的特定库,向导会将该库置于应用程序的类路径中。
- 创建新库。允许您浏览至包含 Facelets JAR 文件的文件夹。
- 不追加任何新库。指定向导不会将任何 JAR 文件附加到应用程序的类路径中。结果是,在源码结构创建了之后,需要由您自己通过“库管理器”把 JAR 文件关联到类路径。
- 保留所有缺省值不变。单击“完成”。
IDE 将创建 NumberGuess 项目。此项目包含所有源代码和项目 meta 数据,例如项目的 Ant 生成脚本。此项目将会在 IDE 中打开。可以在“项目”窗口中查看项目的逻辑结构 (Ctrl-1)。

尽管没有编写任何代码,但您已经能运行应用程序了。右键单击项目节点,然后选择“运行”。如果服务器还未启动,则启动它,并且应用程序已被部署。IDE 的缺省浏览器启动,并显示概览页。
NumberBean
本节引用自 Facelets 开发者文档 的 NumberBean 部分。您将为应用程序创建一个 JavaBean 作为控制器,拷贝自 Facelets 开发者文档。
- 在 NumberGuess 项目中,在 tutorial 包中,创建一个名为 NumberBean.java 的 Java 类。将它替换为以下内容:要理解以下代码,请阅读嵌入在其中的注释。
package tutorial;
import java.io.Serializable;
import java.util.Random;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
public class NumberBean implements Serializable {
protected final static Random rand = new Random();
protected int min;
protected int max;
protected int guess;
protected int actual;
// Default Constructor: public NumberBean() {
this.min = 1;
this.max = 10;
}
// called by JSF to validate user input:
public void validate(FacesContext context, UIComponent component, Object value)
throws ValidatorException {
// coerce the value to an int:
try {
int param = Integer.parseInt(value.toString());
// validate param:
if (param > this.max || param < this.min) {
FacesMessage msg = new FacesMessage("Guess must be between "+this.min+" and "+this.max);
throw new ValidatorException(msg);
}
} catch (NumberFormatException e) {
FacesMessage msg = new FacesMessage("Must be a number");
throw new ValidatorException(msg);
}
}catch (NumberFormatException e) {
FacesMessage msg = new FacesMessage("Must be a number");
throw new ValidatorException(msg);
}
}
// lazy generate your actual value:
public synchronized int getActual() {
if (this.actual == 0) {
this.actual = rand.nextInt(this.max-this.min);
this.actual += this.min;
}
return this.actual;
}
// your message for the response:
public String getMessage() {
if (this.guess == this.getActual()) {
return "Sweet, you got it right!";
} else if (this.guess < this.getActual()) {
return "Sorry, try something higher";
} else {
return "Too bad, go lower";
}
}
// other bean properties:
public int getMin() { return this.min; }
public int getMax() { return this.max; }
public int getGuess() { return this.guess; }
public void setMin(int min) { this.min = min; }
public void setMax(int max) { this.max = max; }
public void setGuess(int guess) { this.guess = guess; }
}
- 展开“Web 页”> "Web-INF" 节点并打开 face-config.xml 文件。打开文件的 XML 视图。右键单击文件并选择 "JavaServer Faces">“添加受管 Bean”,如下所示:

- 在“添加受管 Bean 对话框”中,输入 NumberBean 作为 Bean 名称并在 Bean 类处输入 tutorial.NumberBean。在“范围”下拉菜单中,选择“会话”。在完成之后,单击“添加”。
当您完成向导时,您应该看到如下条目被添加到了 faces-config.xml 文件中。
<managed-bean>
<managed-bean-name>NumberBean</managed-bean-name>
<managed-bean-class>tutorial.NumberBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
在本节中,您将参考 Facelets 开发者文档的创建 Web 页部分。
- 在 template-client.xhtml 文件中,将 <ui:composition> 部分替换成以下内容:
<ui:composition template="/template.xhtml">
此文本不会被显示。
<ui:define name="title">
我在琢磨一个 #{NumberBean.min} 到 #{NumberBean.max}之间的数。您能猜到吗?此文本不会被显示。<ui:define name="body">
<h:form id="helloForm">
<h:inputText type="text" id="userNo" value="#{NumberBean.guess}" validator="#{NumberBean.validate}"/>
<br/>
<h:commandButton type="submit" id="submit" action="success" value="Submit" />
<br/>
<h:message showSummary="true" showDetail="false" style="color: red; font-weight: bold;" id="errors1" for="userNo"/>
</h:form>
</ui:define>
此文本不会被显示。
</ui:composition>
- 右建单击项目,选择“新建”>“其他”,然后在 "Java Server Faces" 分类下选择“ Facelets 模板”。单击“下一步”。此时将打开“新建 Facelets 模板”向导。
- 在“名称和位置”面板中,您可以为模板选择一个布局,如下所示:
- 该 response 模板的名称。在“文件夹”字段中,浏览至 Web 文件夹,或者输入“Web”。接受其他缺省选项并单击完成。
- 使用下面内容替换 response.xhtml 的缺省内容。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<body>
<ui:composition template="/template.xhtml">
<ui:define name="title">
#{NumberBean.message}
</ui:define>
<ui:define name="body">
<form jsfc="h:form">
<input jsfc="h:commandButton" type="submit" id="back" value="Back" action="success"/>
</form>
</ui:define>
</ui:composition>
</body>
</html>
处理导航
在本节中,您将参考 Facelets 开发者文档的处理导航部分。这里,您需要通过 faces-config.xml 文件把您的页面连接起来。
- 在 faces-config.xml 文件中单击鼠标右键,并选择 "Java Server Faces" >“添加导航用例”。此时将打开“添加导航用例”对话框。
- 在“源视图”字段,浏览至 template-client.xhtml。在“目标视图”字段,浏览至 response.xhtml。在“源结果”字段中输入 "success"。在完成之后,单击“添加”。
当您完成对话框,您将会看到如下编辑器。
<navigation-rule>
<from-view-id>/template-client.xhtml</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/response.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
- 在 faces-config.xml 文件中单击鼠标右键,并再一次选择“添加导航用例”。这次,在“源视图”字段,浏览至 response.xhtml。在“目标视图”字段,浏览至 template-client.xhtml。在“源结果”字段中输入 "success"。在完成之后,单击“添加”。
当您完成对话框,您将会看到如下编辑器。
<navigation-rule>
<from-view-id>/response.xhtml</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/template-client.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
- 按住 Ctrl 键,如下所示,将鼠标移到到您应用程序中指向某一个文档的引用之上。注意到指向文档的引用变成了超链接了。
单击超级链接之后,引用文档将在“源编辑器”中打开,这样您无需查找便可直接编辑它。
部署
在本节中,您将参考 Facelets 开发者文档的部署部分。部署您的应用程序意味着,您想让它在服务器上可用。如果服务器未运行,服务器就应当启动。并且, Web 浏览器应当打开,显示 Web 应用程序的欢迎页。
- 在这种情况下,您的项目应该如图所示。
在上面的屏幕快照中,加亮的文件是惟一被添加到原始生成的项目结构中的文件。
- 右键单击项目并选择“运行”。
此时将生成项目,启动服务器(如果没有运行的话)。应用程序将被部署到服务器,并打开 IDE 中指定的浏览器,显示指向 Facelets 样例页面的链接。单击该链接,你应该能看到如文档开头所示的应用程序的客户端页。

未来计划
本文介绍了如何在 NetBeans IDE 中使用 Facelets 进行 Web 开发。 注意,本文只例举了 Facelets 支持模块提供的众多功能中的一部分。有关详细信息,请参见 http://nbfaceletssupport.dev.java.net/。
鼓励您阅读 Facelets 主页上的其他教程,继续 Facelets 框架之旅。