文章
| 开发人员:J2EE
在现有 JSF 应用程序中使用 Oracle ADF Faces 了解如何将 Oracle ADF Faces 集成到现有 JSF 项目中以及如何利用由该框架提供的丰富的 UI 组件
JavaServer Faces (JSF) 是为 Java 开发人员提供的一种非常有用的标准框架 (JSR-127),这是因为它为构建基于 Web 的用户界面定义了一个 API 和一组基本标记。Oracle 应用程序开发框架 (ADF) Faces 基于 JSF 框架,增加了很多新的 UI 组件,简化了 Web 应用程序开发。 本文说明了如何将现有应用程序的 JSF 页改为使用 Oracle ADF Faces(后文中简称为 ADF Faces),并介绍了这种新 UI 框架的好处。您将会了解如何将 ADF Faces 添加到现有 JSF 项目中,以及如何通过使用由 ADF Faces 提供的丰富的 UI 组件增强您的 Web 应用程序。您还会了解到 Oracle JDeveloper 能够如何使您的工作变得更轻松。 使用入门 [ 基本设置 ] 本文分为两个不同的部分或阶段。第一部分概要讨论了各示例的编辑过程,说明如何将几个示例文件改为使用 ADF Faces 而非 JSF,并指出了 JSF 与 ADF Faces 的一些区别。 第二部分带您逐步完成示例的部署和测试过程。要运行本文中提供的示例,您需要 J2SE 1.4(或更高版本)、支持 Servlets 2.3 和 JSP 1.2(或更高版本)的应用服务器、JSF 1.1 的实现、ADF Faces EA13(或更高版本)、JSTL 1.0(或更高版本)、支持 JDBC 的数据库服务器以及 Oracle TopLink。 您不必安装和配置所有这些软件组件,可以使用 Oracle JDeveloper 10.1.3,它绑定了 J2SE、OC4J(Oracle Containers for J2EE,一种符合 J2EE 1.4 标准的应用服务器,它采用 Servlets 2.4 和 JSP 2.0 以及所有其他 J2EE 1.4 标准)、JSF、JSTL 以及 Oracle TopLink。Oracle JDeveloper 通过一个单独的包支持 ADF Faces,必须使用 Help 菜单的“Check for Updates...”向导安装该包。此外,Oracle JDeveloper 能够与 Oracle 数据库非常好地协作。 在任一情况下,如果您还没有安装和配置库文件和其他文件,则需要下载它们。 关于示例应用程序 本文所讨论的应用程序基于上一篇文章“使用 JSF 构建数据库驱动的应用程序 ”中的示例。该文章提供的示例 Web 应用程序查询并更新一个关系数据库(使用 TopLink 或 JDBC)。在本文中,我们将逐步修改该应用程序基于 JSF 的用户界面,代之以使用 ADF Faces。(在您尝试完成本项目之前,回顾“使用 JSF 构建数据库驱动的应用程序”可能对您有所帮助。) ADF Faces 建立在 JSF 的基础上,这意味着如果您希望逐步完成本文中的示例代码,您需要具备这两种技术,因此在开始之前,请根据需要下载、安装和配置这些库(参见“资源”),从建立 ADF Faces 框架开始。 ADF Faces 框架的服务器端设置 要使用 ADF Faces,您需要 JSF 1.1 规范的实现,如 Sun 的 Reference Implementation (RI) 或 Apache 的 MyFaces 。(虽然您可以将 ADF Faces 与 Oracle 的 ADF(应用程序开发框架)中的其他组件结合使用,但是 ADF 的其他部分并非必要 正如您在逐步完成本文所讨论的示例中所看到的,您可以单独使用 ADF Faces。) ADF Faces 和 JSF 可以部署在任何支持 Servlets 2.3 和 JSP 1.2(或更高版本)的应用服务器上。本文中的示例已经使用 JSF 1.1 RI 和 ADF Faces EA13 在 Oracle Containers for J2EE (OC4J) 10g 和 Tomcat 5.0 上进行了测试。(要使用不同的 ADF Faces 早期试用版本,替换所有 JSP 页面中 <%@taglib%> 指令的 EA13 字符串。) 对于 JSF,ADF Faces 还为 Web 页面提供了一个可以在 Java 类中使用的公用 API 以及两个 JSP 标记库(HTML 和 Core)。此外,ADF Faces 自带了一组由 UI 组件在内部使用的资源(图像、JavaScript 和 CSS 文件)。 将 ADF Faces 库和文件添加到开发环境 您可以从 Oracle 技术网 (OTN) 网站获得 .zip 存档格式的 ADF Faces 框架,它包含标记库、文档和一个 Web 应用程序示例。 在 lib 目录中您会找到 .jar 文件( adf-faces-api-ea13.jar、adf-faces-impl-ea13.jar 和 share-1_1_18.jar )。将这些 .jar 文件复制到您 Web 应用程序的 lib 目录中。此外,您会找到一个 .zip 文件 ( adf-faces-install-ea13.zip ),它包含图像、JavaScript 和 CSS 文件。您必须将 adf-faces-install-ea13.zip 文件解压缩到您 Web 应用程序的主目录中。 您还可以下载一个用于 JDeveloper 10.1.3 的 ADF Faces 包。在按照另一篇 OTN 文章(参见资源)中的说明安装该包后,单击几下鼠标就可以将 ADF Faces 库添加到现有 JDeveloper 项目中: 提示:您可以使用“The Check for Updates”向导下载 ADF Faces 并将其安装到 Oracle JDeveloper 10.1.3 中。(有关更多详细信息,请参见文章)
配置应用服务器以支持 ADF Faces 框架 在 J2EE 应用服务器上运行任何 JSF 应用程序之前,必须先配置 web.xml 应用程序描述文件使之包含 FacesServlet :
<servlet> <servlet-name>FacesServlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>FacesServlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>FacesServlet</servlet-name> <url-pattern>*.faces</url-pattern> </servlet-mapping> 此外,要在 JSF Servlet 上使用 ADF Faces,您必须配置一个映射到 FacesServlet 的过滤器(仍在 web.xml 文件中):
<filter> <filter-name>AdfFacesFilter</filter-name> <filter-class> oracle.adf.view.faces.webapp.AdfFacesFilter </filter-class> </filter> <filter-mapping> <filter-name>AdfFacesFilter</filter-name> <servlet-name>FacesServlet</servlet-name> </filter-mapping> 除了必须为 ADF Faces 更改 web.xml 部署描述文件外,您还必须提供一个单独的部署描述文件 ( adf-faces-config.xml) 来指定任何其他 ADF Faces 配置参数,如 accessibility-mode 和 look-and-feel。下面是一个例子:
<?xml version="1.0"?>
<adf-faces-config
xmlns="http://xmlns.oracle.com/adf/view/faces/config">
<debug-output>true</debug-output>
<accessibility-mode>
#{prefs.proxy.accessibilityMode}
</accessibility-mode>
<look-and-feel>
#{prefs.proxy.lookAndFeel}
</look-and-feel>
</adf-faces-config>
但是请注意,所有这些工作在您下载和安装 ADF Faces 插件 时即为您完成了。 将现有 JSF 页面改为使用 ADF Faces 在了解了基本设置的一些情况后,我们来开始查看一些实际代码。在我的上一篇 OTN 文章中(参见文章“使用 JSF 构建数据库驱动的应用程序”),我提供了一个 Web 应用程序,它使用 TopLink 或 JDBC 查询和更新一个关系数据库。在这里,我们将把该应用程序基于 JSF 的用户界面修改为使用 ADF Faces。按照以下几个步骤更新每个 JSF 页面:
a) 导入 ADF Faces 标记库 ADF Faces 定义了两个标记库 Core 和 HTML。Core 库包含 UI 组件:按钮、输入域、列表、菜单、表、树、面板以及许多其他组件。HTML 库包括几个标记,它们可用于生成 Web 页面的 <html>、<head> 和 <body> 标记以及其他与 HTML 相关的内容,如框架和表格。必须使用 <%@taglib%> 指令将这两个库导入到任何使用它们的页面中:
<%@ taglib prefix="af" uri="http://xmlns.oracle.com/adf/faces/EA13" %> <%@ taglib prefix="afh" uri="http://xmlns.oracle.com/adf/faces/EA13/html" %> 当您将 ADF Faces 组件添加到现有 JSF 页面(使用 Component Palette)时或者当您将 JSF 标记转换为 ADF Faces 标记(使用本节后面提到的 JDeveloper 的向导)时,Oracle JDeveloper 自动插入这两个 <%@taglib%> 指令。 . b) 使用 ADF Faces 的 HTML 标记 ADF Faces 的 <afh:html>、<afh:head> 和 <afh:body> 标记生成相应的 HTML 元素以及其他一些内容,如文档的 <title> 元素和 ADF Faces 组件的样式表。以下是一个使用 ADF Faces 的典型 JSF 页面的模板:
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="af"
uri="http://xmlns.oracle.com/adf/faces/EA13" %>
<%@ taglib prefix="afh"
uri="http://xmlns.oracle.com/adf/faces/EA13/html" %>
<f:view>
<f:loadBundle var="labels" basename="..."/>
<afh:html>
<afh:head title="#{labels...}"/>
<afh:body>
...
</afh:body>
</afh:html>
</f:view>
如果有必要,您可以在没有 ADF Faces 帮助的情况下在 JSF 页面中编写 <html>、<head> 和 <body> 标记,但这时您必须在 HTML 标题中包含一个 <af:styleSheet> 组件。 c) 重命名 JSF 标记以及它们的一些属性 ADF Faces 提供一组类似于标准 JSF 标记的标记以及很多在 JSF 中没有对应项的其他标记。您可以在同一页面中混合使用 JSF 和 ADF Faces 标记,这是因为所有 UI 组件都基于由 JSF 标准定义的同一个 API。在将 ADF Faces 添加到现有 JSF 应用程序时,您应该重命名那些在 ADF Faces 中具有对应项的 JSF 标记,以确保前后一致的观感并从其他特性(如客户端验证)中获益。ADF Faces 标记还帮助您减少代码的行数。例如,一个 ADF Faces 标记(如 <af:inputText> )就可以生成一个输入组件、一个标记和一个错误消息:
<af:inputText id="email" required="true"
validator="#{subscriber.emailValidator}"
label="#{labels.email}"
value="#{subscriber.email}"
columns="40" maximumLength="80">
<f:validateLength minimum="1" maximum="80"/>
</af:inputText>
而对于 JSF,您需要三个标记( <h:outputLabel>、<h:message> 和 <h:inputText> )来达到同样的效果:
<h:outputLabel for="email"
value="#{labels.email}"/>
<h:message for="email" styleClass="message"/><br>
<h:inputText id="email" required="true"
validator="#{subscriber.emailValidator}"
value="#{subscriber.email}"
size="40" maxlength="80">
<f:validateLength minimum="1" maximum="80"/>
</h:inputText>
请注意, <af:inputText> 标记可以用于显示单行、多行和口令域,而 JSF 为这些类型的组件提供了三种不同的标记: <h:inputText>、<h:inputTextarea> 和 <h:inputSecret> 。ADF Faces 的 <af:inputText> 标记有两个名为 rows 和 secret 的属性,它们将确定域的类型。例如,您可以使用以下代码生成一个口令域:
<af:inputText id="password" secret="true" required="true"
label="#{labels.password}"
value="#{subscriber.password}"
columns="10" maximumLength="20">
<f:validateLength minimum="6" maximum="20"/>
</af:inputText>
ADF Faces 文档(参见“资源”)详细说明了 JSF 标记与其 ADF Faces 对应项之间存在的所有差别。在很多情况下,您只需将 h 前缀替换为 af,并可能要重命名一些属性。有时您还必须重命名标记。例如,您将使用 <af:goLink> 代替 <h:outputLink> ,使用 <af:selectOneChoice> 代替 <h:selectOneMenu>:
<af:selectOneChoice id="subscriptionType"
label="#{labels.subscriptionType}"
value="#{subscriber.subscriptionType}"
required="true">
<f:validateLongRange minimum="1" maximum="3"/>
<af:selectItem label="#{labels.daily}"
value="#{subscriber.dailyConst}"/>
<af:selectItem label="#{labels.weekly}"
value="#{subscriber.weeklyConst}"/>
<af:selectItem label="#{labels.monthly}"
value="#{subscriber.monthlyConst}"/>
</af:selectOneChoice>
当您使用 JDeveloper 执行所有这些工作时,可以使用向导来重命名标记:
d) 使用 ADF Faces 的面板标记 JSF 标记 <h:panelGrid> 和 <h:panelGroup> 可用于在 HTML 表格中排放 UI 组件。但是,ADF Faces 框架提供了一组更加丰富的面板。例如, <af:panelPage> 标记布置一个可以拥有多个部分(称为‘facet’)的整个 Web 页面。示例应用程序仅使用此标记来显示每页的标题。另一个有用的标记是 <af:panelForm> ,它在一个两列表格中放置标记和输入组件:
JSF 面板 ( <h:panelGrid> ) 仍然有用,可以生成一个对相关组件进行分组的表格,如一组单选按钮,并且您可以用 <af:panelLabelAndMessage> 将标记关联到组件的分组上:
<af:panelLabelAndMessage label="#{labels.newsletters}">
<h:panelGrid id="newsletters"
columns="3" border="0" cellspacing="5">
<af:selectBooleanCheckbox id="manager"
text="#{labels.manager}"
value="#{subscriber.manager}"/>
<af:selectBooleanCheckbox id="developer"
text="#{labels.developer}"
value="#{subscriber.developer}"/>
<af:selectBooleanCheckbox id="administrator"
text="#{labels.administrator}"
value="#{subscriber.administrator}"/>
</h:panelGrid>
</af:panelLabelAndMessage>
如果表单具有多个按钮,您应该将它们放在一个 <af:panelButtonBar> 中。ADF Faces 的 <af:commandButton> 标记使用 text 属性代替对应的 JSF 标记 ( <h:commandButton> ) 的 value 属性:
<af:panelButtonBar>
<af:commandButton id="command"
text="#{labels.unsubscribe}"
action="#{subscriber.unsubscribeAction}"/>
<af:commandButton id="cancel"
text="#{labels.cancel}"
action="#{subscriber.cancelAction}"/>
</af:panelButtonBar>
<af:panelGroup> 标记用于对一些必须分隔开的链接进行分组:
<af:panelGroup>
<f:facet name="separator">
<af:objectSpacer width="10" height="1"/>
</f:facet>
<af:goLink destination="unsubscribe.faces"
text="#{labels.unsubscribe}"/>
<af:goLink destination="logout.faces"
text="#{labels.logout}"/>
</af:panelGroup>
用丰富的 UI 组件增强 Web 应用程序 下面的例子说明了在构建一个允许用户查看和更新数据库表的 Web 表格时,如何组合使用几个 ADF Faces 组件。您将了解如何实现真实 Web 应用程序中所需的与表相关的典型功能:表示、分类、刷新、单行选择和多行选择。如果使用 JSF 标记,则所有这些功能的实现均需要很多手动编程工作。ADF Faces 则自动完成这项工作中的大部分操作,您只需通过设置一个属性或添加几行代码来启用这些功能即可。 使用 ADF Faces 的表格组件 在“使用 JSF 构建数据库驱动的应用程序”中提供的 JSF 应用程序有一个名为 list.jsp 的页面,它利用 JSTL 的 <sql:query> 标记来查询数据库,如下所示:
<sql:query var="subscriberList" scope="request"> SELECT * FROM subscribers ORDER BY subscriberEmail </sql:query> (请注意,这种方式的内联查询对于原型设计很适用,但对于产品应用程序,由于安全性的原因,您不应该采用这种方式。此外,对于产品部署,建议使用稳健的中间层,如 EJB 3.0 或 Oracle Toplink。) <sql:query> 标记创建一个保存结果集的 JSP 变量 ( subscriberList )。必须使用 JSF 数据模型封装该变量才能由 ADF Faces 组件使用:
<jsp:useBean id="tableModel" scope="request"
class="javax.faces.model.ResultDataModel"/>
<c:set target="${tableModel}" property="wrappedData"
value="${subscriberList}"/>
ADF Faces 提供的 <af:table> 和 <af:column> 标记类似于 JSF 的 <h:dataTable> 和 <h:column> 标记,但是 ADF Faces 的表格组件提供了很多额外功能,如绑定、分页、排序和行选择。使用两个属性( banding 和 bandingInterval )即可很方便地启用绑定功能:
<af:table id="table" var="row" value="#{tableModel}"
banding="row" bandingInterval="1">
<af:column>
<f:facet name="header">
<af:outputText value="#{labels.email}"/>
</f:facet>
<af:outputText value="#{row.subscriberEmail}"/>
</af:column>
...
</af:table>
在辅助 Bean 中使用 ADF Faces API 在前面的示例中,利用行属性可以非常方便地启用表格分页功能,但在您使用 JSTL 标记时,为表格的每一页重新查询数据库的效率不高。因此,本文添加了一个 JavaBean ( ListBean ),它只在必要时才使用 DAO 方法来管理表格模型和访问数据库。这个新的 bean 在 faces-config.xml 文件中配置:
<managed-bean> <managed-bean-name>list</managed-bean-name> <managed-bean-class>adfdb.view.ListBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> ListBean 类有两个属性( table 和 tableModel ):
package adfdb.view;
...
import oracle.adf.view.faces.component.UIXTable;
import oracle.adf.view.faces.model.SortableModel;
...
public class ListBean implements java.io.Serializable {
private UIXTable table;
private SortableModel tableModel;
public UIXTable getTable() {
return table;
}
public void setTable(UIXTable table) {
this.table = table;
}
public synchronized SortableModel getTableModel() {
if (tableModel == null)
refreshAction();
return tableModel;
}
public synchronized void setTableModel(
SortableModel tableModel) {
this.tableModel = tableModel;
}
...
}
UIXTable 类是对 ADF Faces 所提供的表格组件的基本抽象,而 SortableModel 是用于 ADF Faces 表格组件的 JSF 数据模型。 getTableModel() 方法调用 refreshAction() ,它使用 selectAll() DAO 方法从数据库中检索所有订户。 refreshAction() 方法创建一个 ListDataModel ,然后创建一个 SortableModel:
package adfdb.view;
...
import adfdb.model.ModelUtils;
import adfdb.model.err.ListException;
import oracle.adf.view.faces.model.SortableModel;
import javax.faces.model.ListDataModel;
import java.util.List;
...
public class ListBean implements java.io.Serializable {
...
public synchronized String refreshAction() {
try {
List list = ModelUtils.getSubscriberDAO().selectAll();
ListDataModel listModel = new ListDataModel(list);
tableModel = new SortableModel(listModel);
if (table != null)
table.setFirst(0);
} catch (ListException x) {
ViewUtils.addExceptionMessage(x);
}
return null;
}
...
}
deleteAction() 方法获取一个表格组件的所有选定行,并将它们收集在一个列表中,该列表被传递给 delete() 方法,此方法由 SubscriberDAO 接口定义并由 TopLinkSubscriberDAO 和 JDBCSubscriberDAO 类实现。从数据库中删除所选定的行,然后用 refreshAction() 重新创建数据模型对象:
package adfdb.view;
...
import adfdb.model.Subscriber;
import adfdb.model.ModelUtils;
import adfdb.model.err.UnsubscribeException;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
import java.util.Set;
...
public class ListBean implements java.io.Serializable {
...
public String deleteAction() {
try {
List list = new LinkedList();
Set selection = table.getSelectionState().getKeySet();
Iterator iterator = selection.iterator();
while (iterator.hasNext()) {
String rowKey = (String) iterator.next();
table.setRowKey(rowKey);
Subscriber subscriber
= (Subscriber) table.getRowData();
list.add(subscriber);
}
table.getSelectionState().clear();
ModelUtils.getSubscriberDAO().delete(list);
refreshAction();
} catch (UnsubscribeException x) {
ViewUtils.addExceptionMessage(x);
}
return null;
}
...
}
由 ListBean 实现的最后一个 JSF 操作是 profileAction() 。当用户通过单击一个链接选择一个行时执行该方法。用 ModelUtils.copy() 将 selectedSubscriber 的属性复制到 subscriber bean 中:
package adfdb.view;
...
import adfdb.model.Subscriber;
import adfdb.model.ModelUtils;
...
public class ListBean implements java.io.Serializable {
...
public String profileAction() {
SubscriberBean subscriber
= (SubscriberBean) ViewUtils.eval("#{subscriber}");
Subscriber selectedSubscriber
= (Subscriber) ViewUtils.eval("#{selectedSubscriber}");
ModelUtils.copy(selectedSubscriber, subscriber);
subscriber.setLoggedIn(true);
return "profile";
}
...
}
profileAction() 返回 profile 的结果,根据在 faces-config.xml 中定义的以下规则,从 list2.jsp 导航到 profile.jsp:
<navigation-rule> <from-view-id>/list2.jsp</from-view-id> <navigation-case> <from-outcome>profile</from-outcome> <to-view-id>/profile.jsp</to-view-id> </navigation-case> </navigation-rule> 将 ADF Faces 表格绑定到辅助 Bean list2.jsp 页面包含一个表格组件,它每次只显示 5 行,允许用户浏览表格的内容。 value 和 binding 属性指定 ListBean 的 tableModel 和 table 属性:
<af:table id="table" var="row"
value="#{list.tableModel}"
binding="#{list.table}"
rows="5" banding="row" bandingInterval="1">
...
</af:table>
名为 actions 的 facet 包含一个用于刷新该表模型的按钮:
<af:table ...>
...
<f:facet name="actions">
<af:commandButton id="refresh"
text="#{labels.refresh}"
action="#{list.refreshAction}"/>
</f:facet>
...
</af:table>
另一个名为 selection 的 facet 包含一个为每行生成一个复选框的 <af:tableSelectMany> 组件。用户将能选择多个行并使用一个删除按钮将这些行从数据库中删除:
<af:table ...>
...
<f:facet name="selection">
<af:tableSelectMany>
<af:commandButton id="delete"
text="#{labels.delete}"
action="#{list.deleteAction}"/>
</af:tableSelectMany>
</f:facet>
...
</af:table>
所有表格列均由 <af:column> 组件表示,该组件包含一个 header facet 和一个 <af:outputText value="#{row...}"/> 组件。某些列有两个属性( sortProperty 和 sortable ),这样用户可以通过单击列表头对表格进行排序。此外, email 列包含一个 <af:commandLink> ,它允许用户查看每个订户的概要信息。 <af:setActionListener> 组件在用户单击链接时设置一个名为 selectedSubscriber 的变量:
<af:table ...>
...
<af:column sortProperty="email" sortable="true">
<f:facet name="header">
<af:outputText value="#{labels.email}"/>
</f:facet>
<af:commandLink action="#{list.profileAction}">
<af:outputText value="#{row.email}"/>
<af:setActionListener from="#{row}"
to="#{sessionScope.selectedSubscriber}"/>
</af:commandLink>
</af:column>
...
</af:table>
以下是由 list2.jsp 页面生成的表格的屏幕截图:
用 Oracle JDeveloper 测试 Web 应用程序 在做完所有这些更改之后,就该测试应用程序并查看我们已经完成的任务了。在本文开始时曾经提到,您需要相当多的软件基础架构来部署该示例应用程序,但是您可以在 Oracle JDeveloper 的环境中完成所有工作。这里,如果您尚未下载后端应用程序的源代码,请立即下载它,以便开始测试。 第 1 步:获取源代码 随文章(参见资源 )提供的可下载存档包括 Java 源代码以及在名为 src 的目录中的一些 SQL 脚本。 web 目录对 JSP 页面和 Web 配置文件进行了分组。您不必编译 Java 代码,这是因为 .class 文件已经位于 jsfadf_src/web/adfdb/WEB-INF/classes 中了,并且您在该目录中还会找到用于 TopLink 的 XML 文件。(如果您要修改该对象模型,请参见“使用 JSF 构建数据库驱动的应用程序”,以获得重新创建 TopLink 文件的详细说明。 该 Web 应用程序有两个用于访问数据库的 DAO 实现:一个基于 TopLink,而另一个使用 JDBC。您可以通过修改 jsfadf_src\web\adfdb\WEB-INF\classes\adfdb\model\res 中的 ModelResources.properties 文件选择您要使用的 DAO 实现。此文件包含一个 DAO 键,它接受两个值: adfdb.model.dao.TopLinkSubscriberDAO 或 adfdb.model.dao.JDBCSubscriberDAO 。 第 2 步:创建一个 Web 项目 启动 JDeveloper 并确保正确安装了 ADF Faces 包。如果您选择 Help 菜单中的 About,则会在 Extensions 选项卡中看到 ADF Faces:
使用 File 菜单中的 New 选项创建一个新的应用程序:
为您的应用程序提供一个名称,如“ADF Faces App”,选择一个目录并单击 OK:
为项目提供一个名称和一个目录,并单击 OK:
JDeveloper 将会在 JDEVELOPER_HOME/jdev/mywork (其中 JDEVELOPER_HOME 是您安装 JDeveloper 的目录)中创建一个名为 AdfFacesApp 的目录和一个 ADFDB 子目录。 第 3 步:配置该 Web 项目 右键单击“Applications”导航器中的“ADFDB Project”,并单击该项目弹出菜单的“Project Properties”选项。在“Project Properties”窗口的左侧面板中选择“JSP Tag Libraries”,在右侧面板中选择“Distributed Libraries”:
单击“Add”按钮,在“Choose Libraries”中选择 ADF Faces、JSF 和 JSTL 标记库,并单击 OK:
当您返回“Project Properties”窗口时,在左侧面板中单击“Libraries”。因为您添加了相应的标记库,所以您会在这里看到 ADF Faces、JSF 和 JSTL 运行时库:
单击“Add Library...”按钮,选择 JSP Runtime 和 TopLink 库,并单击 OK:
当您返回“Project Properties”时单击 OK。由于该项目使用了 JSP 库,JDeveloper 将会在 JDEVELOPER_HOME/jdev/mywork/AdfFacesApp/ADFDB 中创建一个 public_html 目录和一个 WEB-INF 子目录。 第 4 步:复制 Web 页面 将示例 Web 应用程序的内容从 jsfadf_src/web/adfdb 复制到 JDEVELOPER_HOME/jdev/mywork/AdfFacesApp/ADFDB/public_html 。不要担心 WEB-INF 中由 JDeveloper 创建的 web.xml 和 faces-config.xml 文件。这两个文件会被 Web 应用程序的 web.xml 和 faces-config.xml 文件所覆盖。 解压缩 ADF Faces 的 adf-faces-install-ea13.zip 文件,并将所得到的 adf 目录移动到 JDEVELOPER_HOME/jdev/mywork/AdfFacesApp/ADFDB/public_html 中。 返回到 JDevelop,选择 View 菜单的 Refresh 选项。您会在 JDeveloper 中看到 Web 应用程序的内容:
您可以使用类似的操作将 Java 文件导入到 JDeveloper 应用程序中。File 菜单的 Import 选项还允许您根据现有的源来创建项目:
第 5 步:配置数据源 在运行应用程序之前,您必须配置一个数据源和创建一个表。确保您的数据库服务器已启动,然后选择 Connections 导航器,右键单击 Database 并单击“New Database Connection...”
单击 Next 跳过 Welcome 页面并在“Connection Name”域中输入 Oracle :
为一个现有数据库输入数据库服务器所接受的用户名和口令:
提供连接参数:
单击“Test Connection”按钮,查看连接是否工作正常,然后单击 Next 和 Finish:
当运行 Web 应用程序时,JDeveloper 将会配置一个名为 OracleDS 的数据源。 第 6 步:创建表 现在您必须创建一个由 Web 应用程序使用的表。右键单击 Connections 导航器中的 Oracle,然后单击“SQL Worksheet”。从 jsfadf_src/src/sql/create.sql 中粘贴 SQL 语句并单击“Execute SQL Statement”(工具栏的第一个图标):
(如果您已经在 JDeveloper 中启用了 SQL*Plus,并且 .sql 文件是您项目的一部分,则您只需在导航器中右键单击 .sql 文件即可从 JDeveloper 中执行该脚本。) 第 7 步:运行应用程序 返回到 Applications 导航器,右键单击 index.jsp 并单击 Run。
index.jsp 页面将浏览器重导向到 Login 表单:
单击“Subscribe”链接并注册几个用户。然后返回到登录页面并单击“View All Subscribers”查看表格组件。在实际的应用程序中,应该有口令保护订户列表,但这里只是一个原型,没有添加安全性约束,以便使测试过程更简单。作为一项练习,您可以试着使用菜单和其他 ADF Faces 组件来提高应用程序的可用性。 总结 JSF 和 ADF Faces 是功能非常强大的组合。JSF 标准定义了用于构建基于组件的 Web 界面的基础架构,但切记 JSF 并非要成为一个完整的解决方案,这为工具供应商和开放源代码开发人员提供了构建组件库的机会。到目前为止,ADF Faces 是令人印象最深刻的基于 JSF 的框架,它提供了丰富的 UI 组件、对文件上载的支持、客户端验证以及很多其他有用的功能。Oracle JDeveloper 为 ADF Faces 和 JSF 框架提供了一个可视的开发环境,从而简化了很多任务,提高了您的生产率。本文说明了如何在 Oracle JDeveloper 的帮助下将 ADF Faces 集成到现有 JSF 项目中。
Andrei Cioroianu ( devtools@devsphere.com ) 是 Devsphere 的创始人,这是一家 Java 框架、XML 咨询和 Web 开发服务的供应商。Cioroianu 编写了许多 Java 文章,分别由 Oracle 技术网、 ONJava 、 JavaWorld 和 Java Developer's Journal 发表。他还与别人合著了 Java XML Programmer's Reference 和 Professional Java XML 两书(均由 Wrox Press 出版)。 |