集成 Ajax 与 EJB 3.0/JPA — 使用 ICEFaces、JPA 和 Oracle JDeveloper 构建 Web 应用程序
作者:Juan Camilo Ruiz 和 Shay Shmeltzer
2007 年 3 月
简介
在本教程中,我们将构建一个使用新 Java 持久性 API (JPA) 的 Web 页面,该 JPA 结合了 JSF 及开放源代码的 ICEFaces 的丰富 UI 组件。JPA 提供一个简单的数据模型,而 ICEFaces 为 Web 用户界面提供基于 Ajax 的组件。
本教程包括下列主题:
您将创建一个基本的 ICEFaces 数据表,用以查看部门信息。模型的底层详细信息将通过 EJB 3.0 和 JPA 来构建。然后,您将向数据表中添加分页以创建更具吸引力的外观。最后,您将用 JDeveloper 的嵌入式服务器试运行该应用程序。
您可以从此处下载一份完整的 JDeveloper 项目副本作为参考。
注意 — Oracle JDeveloper 随 JSF 组件的 Oracle ADF Faces 集一起预先打包。这些组件还提供了许多 AJAX 类型的功能。可从此处了解有关这些功能的更多信息。
返回主题列表
开始本教程之前,您应该:
|
1.
|
可以访问或已经安装了 Oracle JDeveloper 10g 第 3 版 (10.1.3.2) 生产版。Oracle JDeveloper 是一个免费的 Java IDE,为构建企业 Java 应用程序提供特别支持。可以从 Oracle 技术网上下载。
|
|
2.
|
可以访问或已经安装了 Oracle HR 示例模式。 此模式内置于 Oracle 数据库和免费的 Oracle XE 数据库的默认安装中,这样可以确保数据库中的 HR 用户是解除锁定的。可在此处获取有关安装 HR 模式和在 JDeveloper 中为其创建连接的指导。
|
|
3.
|
启动 JDeveloper。双击 JDeveloper 可执行文件 (jdeveloper.exe),该文件可以在您解压缩它的根目录下找到。
如果 Migrate User Settings 对话框打开,则单击 No。
|
返回主题列表
|
1.
|
从此处下载 ICEfaces-v1.5.3-JDeveloper.zip

|
|
2.
|
在 JDeveloper 中,从 JDeveloper 的主菜单进入 Help | Check for Updates ,选择 Install from Local file 并查找 ICEfaces-v.1.5.3-jDeveloper.zip

单击 Next 继续
|
|
3.
|
JDeveloper 需要重新启动。执行此操作之后,转至 Tools | Manage Libraries 以验证 ICEFaces 库安装成功。

还是在这个地方,验证 JSP Tag Libraries 是否安装成功

|
返回主题列表
如果还没有创建到 HR 模式的 JDBC 连接,则执行下列步骤:
|
1.
|
单击 Connections 选项卡。如果未显示 Connections 选项卡,则从 JDeveloper 主菜单中选择 View | Connection Navigator。

|
|
2.
|
右键单击 Database 节点,从上下文菜单中选择 New Database Connection。

|
|
3.
|
如果打开了 Create Database Connection 向导的 Welcome 页面,则单击 Next。
在该向导的 Type 页面上,在 Connection Name 域中输入 hrconn。单击 Next 继续。
|
|
4.
|
在该向导的 Authentication 页面中,在 Username 域中输入 hr,并在 Password 域中输入 hr。选中 Deploy password 框。
单击 Next 继续。
|
|
5.
|
在该向导的 Connection 页面中,默认的连接值应如下所示:
Driver:thin
Host Name:localhost
JDBC Port: 1521
SID:ORCL(对于 Oracle XE 数据库,SID 的值为 XE)
如果将数据库安装到本地,则保留域的这些默认值。如果您使用的是远程数据库,为到数据库的连接输入适当的值。如果您不知道这些值,请联系您的数据库管理员。
单击 Next 继续。
|
|
6.
|
单击 Test Connection。
如果数据库可用且连接的详细信息正确,您将看到 Status 窗口中显示 Success! 这个词。
如果发生错误,则确认这些设置是否正确。单击 Back 进行任何必要的更改,然后重新测试该连接。
如果连接成功,则单击 Finish 完成该连接。
这样您就创建了一个数据库连接,该数据库为您在本教程中构建的应用程序提供数据。注意,数据库导航器允许你浏览甚至编辑您的数据库连接中的对象。
|
返回主题列表
业务模型为应用程序提供数据访问和验证功能。无论客户端如何实施,该模型始终对数据进行验证。它将验证和业务规则与用户界面设计进行了清晰划分。
要在 JDeveloper 中创建应用程序,并为该应用程序创建 JPA 模型,执行以下任务:
返回主题列表
创建新的应用程序和项目
在 JDeveloper 中,一个应用程序通常包含多个项目。
应用程序是 JDeveloper 控制结构中的最高级别。它是您在工作时需要的所有相关对象的视图。在开发 Java 程序时,应用程序将跟踪项目。
JDeveloper 项目是一个按逻辑将相关文件分类的组织结构。可以将多个项目添加到应用程序中,以便轻松地组织、访问、修改以及重用源代码。在 Applications Navigator 中,项目作为层次结构的第二层显示为应用程序的子节点。
创建任何应用程序组件之前,必须首先创建应用程序和初始项目。为此,执行以下步骤:
|
1.
|
单击 Applications Navigator 选项卡,返回 Applications Navigator。
右键单击 Applications 节点,从上下文菜单中选择 New Application。
|
|
2.
|
在 Create Application 对话框中,在 Application Name 域中输入 iceFacesDemo。注意,当您输入应用程序名时,目录名将自动改变。
在 Application Package Prefix 域中输入 oracle.com。
从 Application Template 下拉列表中选择值 Web Application [JSF, EJB, Toplink]。
单击 OK。
|
|
3.
|
创建应用程序的同时还创建了 Model (JPA) 和 ViewController (用户界面)项目。向 ViewController 项目中添加 ICEFaces 集成。右键单击 ViewController 节点并选择 ICEFaces Integration

查看操作,单击 YES。
|
|
4.
|
执行此操作后,检查 ICEFaces 库是否已被添加到 Project Properties

|
|
5.
|
单击 OK。
单击工具栏上的 Save All 以保存您的工作。或者,您可以从菜单中选择 File | Save All。
|
返回主题
返回主题列表
使用 JPA 和 EJB 创建业务逻辑
在本部分中,您将基于 Java 持久性体系结构 (JPA) 从一个名为 Departments 的关系数据库表创建一个实体 bean。在该实体 bean 中,您可以实施与您的数据源进行交互的方法和命名查询。
创建该实体 bean 之后,您将创建一个 EJB 会话 bean,该会话 bean 将充当会话外观并将封装业务逻辑和业务数据,公开任何必要的接口。
要创建应用程序的数据模型,执行以下步骤:
|
1.
|
在 Applications Navigator 中,右键单击 Model 项目并从上下文菜单中选择 New。

|
|
2.
|
在 New Gallery 的 Categories 列表中展开 Business Tier,然后选择 EJB 节点。在 Items 列表中,选择 Entity From Tables (JPA/EJB3.0) 并单击 OK。
|
|
3.
|
如果显示 Create Entity from Tables 向导的 Welcome 页面,则单击 Next。
在 Database Connection Details 页面上,选择以前创建的 hrconn

单击 Next。
|
|
4.
|
在 Select Tables 上,单击 Query 显示数据库连接中的所有表。将 Departments 表从 Available 表列表选择到 Selected 列表。

单击 Next。
|
|
5.
|
选择 java.util.List 作为 Collection Type for Relationship Fields。

单击 Next。
单击 Finish。
|
|
6.
|
查看使用生成的代码创建的 Departments.java bean

我们已经基于表创建了一个基本的 EJB 3.0 实体 bean。现在,我们将创建一个会话外观 bean,以封装业务逻辑并向外界公开展示方法和接口。
|
|
7.
|
在 Applications Navigator 中,右键单击 Model 项目并从上下文菜单中选择 New。

|
|
8.
|
在 New Gallery 的 Categories 列表中展开 Business Tier,然后选择 EJB 节点。在 Items 列表中,选择 Session Bean (EJB 1.1/2.x/3.0) 并单击 OK。

|
|
9.
|
如果显示了 Create Session 向导的 Welcome 页面,则单击 Next。
在该向导的 EJB Name and Options 页面上,将值设置为如下所示的值。
|
域
|
值
|
|
EJB Name
|
DepPublicFacade
|
|
Session Type
|
Stateless
|
|
Transaction Type
|
Container
|
|
Generate Session Facade Methods
|
选中复选框(以便生成用于查询和持久保存数据的方法)
|
|
Entity Implementation
|
EJB 3.0 Entities
|
无状态会话 bean 没有内部状态。它们不记录从一个方法调用传递到另一个方法调用的信息。无状态业务方法的每个调用都独立于它的前一个调用。只有需要在方法调用之间维护会话状态的应用程序(如在线购物车)才需要有状态会话 bean。
通过指定一个事务类型的容器,您将启用容器来管理事务,因此不必编写事务机制的代码。仅当您要编写自己的事务机制时才需要更改此设置。

单击 Next。
|
|
10.
|
在该向导的 Session Facade 页面上,确保选中了所有复选框,因为您需要此会话 facade 并入所有方法和命名查询。单击 Next。

|
|
11.
|
在该向导的 Class Definitions 页面上,确保将 Bean Class 设置为 oracle.com.model.DepPublicFacadeBean。默认目录是可接受的。单击 Next。

|
|
12.
|
在该向导的 EJB Component Interfaces 页面上:
单击 Next。

单击 Finish 完成该过程。
|
|
13.
|
查看生成的代码

单击 JDeveloper 工具栏上的 Save All ,或者从菜单中选择 File | Save All。
|
返回主题
返回主题列表
您在创建该应用程序时创建了两个项目:数据模型和用户界面。Data Model 项目包含用作应用程序业务模型的 JPA 持久性。User Interface 项目用于应用程序的视图部分,视图部分定义了用户界面组件。
我们将使用 JSF 开发我们的用户界面层。首先,我们将创建一个辅助 bean,它提供从 UI 层访问模型层的桥梁。我们的辅助 bean 提供一个简单的 java 类,该 java 类可以由多个 JSF 页面用来从模型层调用方法或者保证数据变量为多个页面所用。
我们将验证项目的结构,然后创建一个辅助 bean。执行以下步骤:
|
1.
|
右键单击 ViewController 项目并选择 Project Properties
转至 Dependencies ,选中 Model.jpr 以确保我们可以在视图内通过 Model 调用方法。

在 J2EE Application 中,更改 iceFacesDemo 的应用程序名和上下文根

单击 Save All 保存您的工作。
|
|
2.
|
在 Applications Navigator 中,右键单击 ViewController 项目并从上下文菜单中选择 Open JSF Navigation。
|
|
3.
|
JDeveloper 为我们提供了三种 编辑 faces-config.xml 配置文件的方式,这是 JSF 控制器层的核心。在设计编辑模式下,您可以可视地设计应用程序的页面流。您可以通过底部的 Source 选项卡直接编辑 XML 代码。我们将使用 Overview 选项卡对文件进行声明式编辑。
选择左下侧 Overview 选项卡
从左侧选择 Managed Beans,然后在右侧选择 New
|
|
4.
|
指定值
|
域
|
值
|
|
Name
|
DepartmentBean
|
|
Class
|
oracle.com.view.DepartmentsBean
|
|
Scope
|
session
|
|
Generate Class if It Does Not Exist
|
选中复选框(这样就生成了类)
|

单击 OK
单击 JDeveloper 工具栏上的 Save All ,或者从菜单中选择 File | Save All。
|
|
5.
|
打开 DepartmentsBean.java,在 ViewController 项目上展开 Application Sources->oracle.com.view 并双击 DepartmentsBean.java

|
|
6.
|
下面的代码创建一个从您的实体 bean 返回一个部门列表的方法,用此代码替换类代码。 注意 — 用于访问 EJB 的代码与您在 JDeveloper 中通过右键单击会话外观并创建“sample EJB client”所生成的代码类似。
package oracle.com.view;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import oracle.com.model.DepPublicFacade;
public class DepartmentsBean {
private DepPublicFacade model;
public DepartmentsBean() {
try {
final Context context = getInitialContext();
model = (DepPublicFacade)context.lookup("DepPublicFacade");
} catch (Exception ex) {
ex.printStackTrace();
}
}
public List getDepartments() {
return model.queryDepartmentsFindAll();
}
private static Context getInitialContext() throws NamingException {
// Get InitialContext for Embedded OC4J
// The embedded server must be running for lookups to succeed.
return new InitialContext();
}
}
导入所必需的程序包,在您使用的不同对象上按 CTRL+ENT
如果没有错误警告,单击 Save All 保存您的工作。
|
返回主题列表
现在您可以创建用户界面了。您使用 JDeveloper 的 JSF 导航图设计和创建应用程序的页面,并在使用多个页面时定义它们之间的导航。您还将使用 dataTable ICEFaces 组件显示来自模型的数据。
重要注意事项:与 JDeveloper 进行的 ICEFaces 集成不适用于 JDeveloper 为 JSF 和 JSP 开发提供的 WYSIWYG 编辑器。然而,您仍然可以使用 Structure 窗格、Component Palette 和 Property Inspector 的组合来定义您的 JSF。您还可以使用代码编辑器,体验代码洞察以及它为 JSF 开发人员提供的其他编码特性。
要创建页面,执行以下步骤:
|
1.
|
切换到 faces-congig.xml 文件和该文件的图表视图。确保从 Component Palette 的下拉列表中选择 JSF Navigation Diagram
选择 JSF Page 并单击该图上要显示该页面的位置。

注意,该页面显示了一个黄色的警告符号。这是因为您在该图上绘制了一个尚不存在的页面。以后在您创建页面时,此黄色警告将消失。
|
|
2.
|
键入 departments 以对该页面进行重命名。
您只需键入名称;JDeveloper 将在你按 [Enter] 时自动添加一个前导斜线和 .jsp 扩展名。
单击 Save All 保存您的工作。
|
|
3.
|
在 JSF Navigation Diagram 上,双击 departments.jsp 启动 Create JSF JSP 向导。
如果显示该向导的 Welcome 页面,请单击 Next。
在该向导的 JSP File 页面上,选择 JSP Document 选项。这将创建 JSP 页面的 XML 表示,以确保该页面使用格式良好的 XML 语法。
单击 Next 继续。
|
|
4.
|
在 Component Binding 页面上,选择 Do Not Automatically Expose UI Components in a Managed Bean 选项。保留其他值的默认值,然后单击 Next。

|
|
5.
|
确保 Selected Libraries 列表中显示如下所示的库。
JSF Core 1.0
JSF HTML 1.0
ICEFaces Component Suite 1.5.3
否则,请在 Available Libraries 列表中选择它们,然后单击 Add 将其加入 Selected Libraries 列表中。注意,库版本号可能与以上所示的版本号不同。
单击 Next 接受您需要的库,以便在页面上创建 ICEFaces 组件。
|
|
6.
|
单击 Next 接受默认的 HTML 选项,然后单击 Finish 创建新 JSF JSP。

将在编辑器中打开空的 departments.jspx 页面。在随后的步骤中,您将在该页面中添加一个数据绑定的 ICEFaces dataTable 组件。该组件显示各个部门。
|
|
7.
|
单击 Save All 保存您的工作。
|
|
8.
|
返回到 Design 视图。单击空白屏幕。
写入一个标题 List of Departments Using JPA and ICEFaces

现在写入一些附加文本
 切换到页面的源视图,查看您刚才可视化修改后的页面的 JSF 源。
|
|
9.
|
ICEFaces 组件使用 ice:form 组件封装其他组件。我们将把 h:form 组件转换成一个正确的组件。 在 Structure 窗格中,右键单击 h:form 组件并选择 Convert

现在,从组件库的下拉列表中选择 ICE Faces Components Suite,然后选择 Form 作为要转换的组件。

单击 Save All 保存您的工作。
|
|
10.
|
接下来,我们将使用 Component Palette 向页面添加一个数据表。在 Component Palette 窗口(按 ctrl+shift+p 弹出)中,确保您正在查看 ICEFaces Components Suite 组件集,然后找到 DataTable 组件。
将该组件从 Component Palette 拖到 Structure 窗格窗口中的 ice:forms 节点上。 接下来,单击 Structure 窗口中的 dataTable 节点并使用 Property Inspector 窗口设置 DataTable 组件的以下属性。 -
Border: 1
-
Id:depTable
-
Var:dep
将光标放在 Value 属性处,单击 Bind to data 按钮。
 这将弹出了表达式创建器对话框。在 Variables 窗口中,导航到 JSF Managed Beans - DepartmentBean - departments 并将其添加到右侧,然后单击 OK。该操作将该表绑定到从我们以前创建的托管 bean 返回的 departments 列表。 
接下来,我们将向该数据表添加列,您也可以通过相同的拖放过程来完成该操作,您可能会发现,复制并粘贴以下代码的速度更快。删除 <ice:dataTable/> 标记中的结束标记“/”,转至下一行,键入 </ — 这将导致 JDeveloper 自动完成正确的结束标记。 在 <ice:dataTable></ice:dataTable> 之间添加以下代码:
<ice:column>
<f:facet name="header">
<ice:outputLabel value="Department ID"/>
</f:facet>
<ice:outputText value="#{dep.departmentId}"/>
</ice:column>
<ice:column>
<f:facet name="header">
<ice:outputLabel value="Department Name"/>
</f:facet>
<ice:outputText value="#{dep.departmentName}"/>
</ice:column>
<ice:column>
<f:facet name="header">
<ice:outputLabel value="Department Location"/>
</f:facet>
<ice:outputText value="#{dep.locationId}"/>
</ice:column>
您应得到如下所示的内容

单击 Save All 保存您的工作
|
返回主题列表
既然已经构建了新应用程序,您就希望对其进行测试。JDeveloper 使您可以轻松地通过内置 J2EE 服务器来测试 JSF/EJB 应用程序。当您从 JDeveloper 中测试页面时,OC4J 服务器将自动启动。
要完成测试过程,执行以下步骤。
|
1.
|
在 Applications Navigator(该页面的编辑器)或 JSF Navigation Diagram 中右键单击 departments.jspx,然后从上下文菜单中选择 Run。
嵌套式 OC4J 服务器随即启动并初始化,同时浏览器中将显示该页面。
|
|
2.
|
查看结果

提示 — 如果你收到一条错误信息 javax.faces.FacesException:Failed to execute JSP lifecycle.导航到 Web Content - WEB-INF 并打开 web.xml 文件。在文件中找到以下条目:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
用以下内容替换本条目:
<servlet-mapping>
<servlet-name>Persistent Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
现在再次尝试运行该页面。
|
返回主题列表
您拥有了自己的数据表之后,就要添加分页以显示较少的数据量。通过此方式,您可以看到与 AJAX 事件的直接交互。
要向刚创建的表中添加分页,执行以下步骤。
|
1.
|
转到 departments.jspx 设计编辑器。在 Structure 窗格中,展开 body 结构并选择 ice:dataTable。转到 Inspector 窗格,指定 Rows 值为 5。
单击 Save All 保存您的工作。
|
|
2.
|
转到 departments.jspx 源代码,在 </ice:dataTable> 后面添加以下代码
<ice:dataPaginator id="dataScroll_1" for="depTable" paginator="true" paginatorMaxPages="5">
<f:facet name="first"> <ice:outputLabel value="First"/>
</f:facet>
<f:facet name="next"> <ice:outputLabel value="Next"/>
</f:facet>
<f:facet name="previous"> <ice:outputLabel value="Prev"/>
</f:facet>
<f:facet name="last"> <ice:outputLabel value="Last"/>
</f:facet>
</ice:dataPaginator>
它应如下图所示

单击 Save All 保存您的工作
|
|
3.
|
在 Applications Navigator(该页面的编辑器)或 JSF Navigation Diagram 中右键单击 departments.jspx,然后从上下文菜单中选择 Run。
查看结果

|
|
4.
|
最后,在表的 footer 中添加一个导航范围分页。转到 departments.jspx 源代码编辑器,在最后一个 </ice:column> 后面、</ice:dataTable> 前面用以下代码添加一个页脚外观:
<f:facet name="footer"> <ice:dataPaginator id="dataScroll_2" for="depTable" rowsCountVar="rowsCount" displayedRowsCountVar="displayedRowsCount" firstRowIndexVar="firstRowIndex" lastRowIndexVar="lastRowIndex" pageCountVar="pageCount" pageIndexVar="pageIndex"> <ice:outputFormat value="{2} to {3} of {0} departments found" styleClass="standard"> <f:param value="#{rowsCount}"/> <f:param value="#{displayedRowsCount}"/> <f:param value="#{firstRowIndex}"/> <f:param value="#{lastRowIndex}"/> <f:param value="#{pageIndex}"/> <f:param value="#{pageCount}"/> </ice:outputFormat> </ice:dataPaginator>
</f:facet>
现在,您的页面应如下所示:

单击 Save All 保存您的工作
|
|
5.
|
在 Applications Navigator(该页面的编辑器)或 JSF Navigation Diagram 中右键单击 departments.jspx,然后从上下文菜单中选择 Run。
查看结果

|
总结
在本教程中,您使用 JDeveloper、JPA/Toplink Essentials 和 ICEFaces 创建了一个简单的端到端应用程序。您学习了如何:
|
安装 JDeveloper 的 ICEFaces 扩展并将 ICEFaces 与现有的 JSF 项目集成
|
|
使用 JPA 和 EJB 创建业务模型和会话外观
|
|
使用 jsf-config.xml 文件创建托管的 bean
|
|
使用 JSF 和 ICEFaces 组件并将其绑定到来自 JPA 实体的数据
|
|
在 JDeveloper 内测试应用程序
|
更多信息