docs.oracle.com版权所有 © 2004 sun microsystems, inc., 4150 network circle, santa clara,...

192
Sun Microsystems, Inc. www.sun.com 请将有关本文档的意见和建议发送到:http://www.sun.com/hwdocs/feedback J2EE 应用程序教程 Sun Java Studio Enterprise 6 部件号码:817-6754-10 2004 4 月,修订版 A

Upload: others

Post on 19-Jul-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

Sun Microsystems, Inc.www.sun.com

请将有关本文档的意见和建议发送到:http://www.sun.com/hwdocs/feedback

J2EE ™ 应用程序教程

Sun Java™ Studio Enterprise 6

部件号码:817-6754-102004 年 4 月, 修订版 A

Page 2: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。

美国政府权利 - 商业软件。政府用户在使用时需遵守 Sun Microsystems, Inc. 的标准许可协议和 FAR 及其补充内容中的适用条款。

该发行版本中可能包含由第三方开发的内容。 Sun、 Sun Microsystems、 Sun 徽标和 Java 都是 Sun Microsystems, Inc. 在美国和其它国家(地区)的商标或注册商标。

所有的 SPARC 商标均须获得授权才能使用,它们是 SPARC International, Inc. 在美国和其它国家(地区)的商标或注册商标。带有 SPARC 商标的产品均基于由 Sun Microsystems, Inc. 开发的体系架构。

UNIX 是在美国和其它国家(地区)的注册商标,由 X/Open Company, Ltd. 独家授权。

该服务手册所涵盖的产品以及涉及的信息均受制于美国的出口控制法,并有可能要遵守其它国家 (地区)的出口或进口法规。严禁将产品用于核、导弹、生化武器或核海事等 终目的或交给有此类企图的 终用户,无论是直接还是间接。严禁将产品出口或再次出口到受美国禁运的国家(地区)或美国出口禁止清单上列出的实体,包括但不限于被拒绝的人员以及特别指明的公民清单。

本文档按“原样”提供,对所有明示或默示的条件、陈述和担保,包括对适销性、特殊用途的适用性或非侵权性的默示保证,均不承担任何责任,除非此免责声明的适用范围在法律上无效。

Page 3: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

目录

前言 13

1. 入门 21

获得和安装所需软件 21

启动软件 23

启动 IDE 23

启动应用程序服务器 23

将 Sun Java System Application Server 设置为缺省服务器 30

建立数据库连接 31

启用 JDBC 驱动程序 31

建立 JDBC 资源 32

教程数据库表说明 34

2. 教程简介 37

教程应用程序的功能 37

应用程序方案 38

应用程序的功能规范 38

用户的教程应用程序视图 39

教程应用程序的体系结构 41

应用程序元素 43

3

Page 4: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

EJB 层详细资料 43

创建教程应用程序任务的概述 44

创建 EJB 组件 44

创建教程的 Web 服务 46

安装和使用提供的客户端 47

尾注 48

3. 生成 DiningGuide 应用程序的 EJB 层 49

教程的 EJB 层概述 50

实体 Bean 50

会话 Bean 51

详细资料类 51

步骤摘要 53

使用 EJB 生成器创建实体 Bean 54

创建 Restaurant 和 Customerreview 实体 Bean 54

为 CMP 实体 Bean 创建 Create 方法 62

在实体 Bean 上创建 Finder 方法 66

创建用于测试的 Business 方法 68

创建详细资料类以查看实体 Bean 数据 70

创建详细资料类 70

创建详细资料类属性及其 Accessor 方法 70

创建详细资料类的构造函数 71

在实体 Bean 上创建 Business 方法以获取详细资料类 73

测试实体 Bean 74

为 Restaurant Bean 创建测试客户端 74

为 Sun Java System Application Server 插件提供数据库信息 77

部署并执行 Restaurant Bean 的测试应用程序 79

使用测试客户端测试 Restaurant Bean 80

检查对数据库的增加 83

4 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 5: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

为 Customerreview Bean 创建测试客户端 84

部署并执行 Customerreview Bean 的测试应用程序 86

测试 Customerreview 实体 Bean 86

检查对数据库的增加 88

使用 EJB 生成器创建会话 Bean 88

编写会话 Bean 的 Create 方法的代码 90

创建 Business 方法以获得详细资料数据 92

创建 Business 方法以创建顾客意见记录 96

创建返回 “详细资料类”类型的 Business 方法 97

增加 EJB 引用 99

测试会话 Bean 101

为会话 Bean 创建测试客户端 101

将实体 Bean 引用增加到 EJB 模块中 102

为 Sun Java System Application Server 插件提供数据库信息 102

部署并执行测试应用程序 104

使用测试客户端测试会话 Bean 106

检查对数据库的增加 108

有关创建客户端的注释 109

4. 创建 DiningGuide 应用程序的 Web 服务 111

教程 Web 服务的概述 111

Web 服务 112

运行环境类 112

客户端文件 112

创建教程的 Web 服务 113

创建逻辑 Web 服务 113

生成 Web 服务的运行环境类 115

测试 Web 服务 117

创建测试客户端和测试应用程序 117

目录 5

Page 6: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

将 Web 服务增加到 J2EE 应用程序中 118

部署测试应用程序 119

使用测试应用程序测试 Web 服务 121

使您的 Web 服务可供其他开发人员使用 129

生成 WSDL 文件 129

从 WSDL 文件生成客户端文件 130

5. 为教程应用程序创建客户端 133

使用提供的代码创建客户端 133

运行教程应用程序 134

检查客户端代码 137

显示餐馆数据 137

显示所选餐馆的顾客意见数据 139

创建新的顾客意见记录 141

A. DiningGuide 源文件 145

RestaurantBean.java 源文件 146

RestaurantDetail.java 源文件 149

CustomerreviewBean.java 源文件 154

CustomerreviewDetail.java 源文件 157

DiningGuideManagerBean.java 源文件 160

RestaurantTable.java 源文件 164

CustomerReviewTable.java 源文件 168

B. DiningGuide 数据库脚本 173

PointBase 数据库脚本 174

Oracle 数据库脚本 175

C. 使用 Oracle 数据库创建教程 177

使用 Oracle 数据库设置数据库连接 177

6 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 7: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

启用 oracle Type 4 JDBC 驱动程序 178

将 IDE 连接到 Oracle 服务器 179

创建 JDBC 连接池 180

创建 JDBC 数据源 181

创建 JDBC 持久性管理器 182

创建数据库表 184

使用 Oracle 数据库创建 EJB 组件 185

使用 Oracle 数据库创建 Web 服务 186

索引 187

目录 7

Page 8: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

8 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 9: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

图 2-1 DiningGuide 应用程序体系结构 42

图 3-1 详细资料类的功能 52

9

Page 10: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

10 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 11: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

表 1-1 DiningGuide 数据库表 34

表 1-2 Restaurant 表记录 34

表 1-3 CustomerReview 表记录 35

表 C-1 对第 3 章进行的更改 (与 Oracle 有关) 185

表 C-2 对第 4 章进行的更改 (与 Oracle 有关) 186

11

Page 12: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

12 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 13: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

前言

欢迎使用 《Sun™ Java ™ Studio Enterprise 6 J2EE 应用程序教程》。本教程向您展示如何使用 Java Studio Enterprise 集成开发环境 (IDE) 中的下列功能:

■ EJB™ 2.0 生成器 — 用于创建和开发基于 《Enterprise JavaBeans 规范版本 2.0》的 Enterprise JavaBeans™ 组件。

■ EJB 模块组装 — 用于将 EJB™ 组件组装到 EJB 模块中,您可以将该模块输出到 EJB Java 归档 (JAR) 文件。

■ 测试应用程序工具 — 用于通过将 Sun Java System Application Server 软件作为应用程序服务器来测试企业 bean,无需手动创建客户机。

■ Web 服务功能 — 用于从现有的 EJB 组件生成 SOAP Web 服务,并通过 Web 浏览器生成可视的 JSP™ Pages。

■ 部署到 Sun Java System Application Server— 用于测试教程应用程序。

请参见发行说明,以了解书中有关创建示例的环境列表。发行说明位于下列 Web 页:

http://developers.sun.com/prodtech/javatools/jsenterprise/reference/docs/index.html

屏幕快照将随平台的不同而略有变化。虽然几乎所有过程都使用 Sun Java Studio Enterprise 6 软件界面,但有时您可能也需要在命令行中输入命令。这也会随平台的不同而略有差异。例如:Microsoft Windows 命令可能会如下所示:

UNIX® 命令可能如下所示:

c:>cd MyWorkDir\MyPackage

% cd MyWorkDir/MyPackage

13

Page 14: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

阅读本书须知本教程创建的应用程序符合在 《Java 2 Platform Enterprise Edition (J2EE™) Blueprints》中确定的体系结构。如果要了解如何使用 Sun Java Studio Enterprise 6 的功能来创建、开发和部署 J2EE 兼容应用程序,那么阅读本教程会使您受益匪浅。

开始阅读本教程之前,应熟悉下列主题:

■ Java 编程语言■ Enterprise JavaBeans 概念

■ Java™ Servlet 语法■ 启用了 JDBC™ 的驱动程序语法■ JavaServer Pages™ 语法■ HTML 语法■ 关系数据库概念 (如表和关键字)■ 使用选定数据库的方法■ J2EE 应用程序组装和部署概念

本书要求您对下列资源中描述的 J2EE 概念有所了解:

■ 《Java 2 Platform Enterprise Edition Blueprints》http://java.sun.com/j2ee/blueprints

■ 《Java 2 Platform Enterprise Edition 规范》http://java.sun.com/j2ee/download.html#platformspec

■ 《J2EE 教程》http://java.sun.com/j2ee/tutorial

■ 《Java Servlet 规范版本 2.3》http://java.sun.com/products/servlet/download.html#specs

■ 《JavaServer Pages 规范版本 1.2》http://java.sun.com/products/jsp/download.html#specs

熟悉基于 XML 的 RPC (JAX-RPC) 的 Java API 很有帮助。要获得更多的信息,请访问下面的 Web 页:

http://java.sun.com/xml/jaxrpc

注意 – Sun 不对本文档中提及的第三方 Web 站点的可用性负责,也不为从这些站点和资源获得的任何内容、广告、产品或其它材料提供担保或承担任何责任与义务。对于使用或依靠任何此类站点或资源上 (或通过它们获得)的任何内容、商品或服务而引起或声称引起的任何损害或损失, Sun 概不负责或承担任何责任。

14 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 15: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

本书的结构本手册适于从前往后按顺序阅读。本教程中的每一章都构建于前面章节中所开发的代码的基础之上。

第 1 章 列出 DiningGuide 教程的软件需求,解释如何启动 Java Studio Enterprise IDE 和 Sun Java System Application Server、如何使得 IDE 和应用程序服务器相互识别并同时与 PointBase 数据库通信、如何创建教程数据库表,然后基于这些表在 IDE 中创建数据库结构。

第 2 章 介绍教程应用程序的功能和体系结构。

第 3 章 提供有关创建教程应用程序的 EJB 层以及如何使用 IDE 的测试应用程序工具来测试每个 bean 的分步指导。

第 4 章 介绍如何使用 IDE 来根据教程的 EJB 层生成其 Web 服务,以及如何测试 Web 服务。

第 5 章 解释所提供的 Swing 客户机如何访问根据第 4 章中的 Web 服务模块生成的输出,以及如何运行教程应用程序。

附录 A 提供教程应用程序的完整源文件。

附录 B 提供教程应用程序的数据库脚本。

附录 C 介绍如何适应本教程以使用 Oracle 数据库创建并运行应用程序。

前言 15

Page 16: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

排版惯例

相关文档Java Studio Enterprise 文档包括以 Acrobat Reader (PDF) 格式提供的书籍、发行说明、联机帮助、示例应用程序的自述文件。

联机文档

本部分介绍的文档可从 docs.sun.comSM Web 站点和 Sun Developer Resources (Sun 开发人员资源)门户的文档页面中找到,位置:http://developers.sun.com/devtools/javatools/jsenterprise/reference/docs/index.html。

docs.sun.com Web 站点 (http://docs.sun.com) 使您可以通过 Internet 阅读、打印和购买 Sun Microsystems 的手册。

■ 《Sun Java Studio Enterprise 6 发行说明》 - 部件号码:817-6746-10

介绍 新的发行更改和技术说明。

■ 《Sun Java Studio Enterprise 6 安装指南》 - 部件号码:817-6510-10 (PDF 格式)

介绍如何在每个支持的平台上安装 Sun Java Studio Enterprise 6 集成开发环境 (IDE)和相关服务器,还包括其它相关信息,如系统需求、升级说明、服务器信息、命令行开关、数据库集成,以及有关如何使用更新中心的信息。

字体 含义 示例

AaBbCc123 命令、文件和目录的名称;计算机屏幕输出

编辑您的 .cvspass 文件。

使用 DIR 列出所有文件。

Search is complete.

AaBbCc123 键入的内容,以便与计算机屏幕输出相区别

> login

Password:

AaBbCc123 书名、新词或术语以及要强调的词 请阅读 《用户指南》的第 6 章。

这些称作类选项。

您必须保存您的更改。

AaBbCc123 命令行变量;用实际的名称或值替换 要删除文件,请键入 DEL filename。

16 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 17: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

■ 《Sun Java Studio Enterprise 6 Examples Guide》 - 部件号码:817-6057-10

介绍 Sun Java Studio Enterprise 6 软件的各种代码示例。

■ 《Sun Java Studio Enterprise 6 编程系列》(PDF 格式)

该系列深入介绍有关如何使用 Sun Java Studio Enterprise 6 各项功能以开发标准格式的 J2EE 应用程序的信息。

■ 《构建 Web 组件》 - 部件号码 817-3292-10

描述如何使用 JSP pages、servlet、标记库以及支持的类和文件生成一个作为 J2EE Web 模块的 Web 应用程序。

■ 《构建 J2EE 应用程序》 - 部件号码 817-3290-10

描述如何将 EJB 模块和 Web 模块组装到 J2EE 应用程序中,以及如何部署和运行 J2EE 应用程序。

■ 《构建 Enterprise JavaBeans 组件》 - 部件号码 817-3288-10

描述如何使用 Sun Java Studio Enterprise 6 EJB 生成器向导和 IDE 的其它组件生成 EJB 组件(会话 Bean、消息驱动 bean 和包含容器管理持续性或 Bean 管理持续性的实体 Bean)。

■ 《构建 Web 服务》 - 部件号码 817-3294-10

描述如何使用 Sun Java Studio Enterprise 6 IDE 生成 Web 服务、如何通过 UDDI 注册使 Web 服务可供其它服务使用,以及如何通过本地 Web 服务或 UDDI 注册生成 Web 服务客户机。

■ 《使用 Java 数据库连接》 - 部件号码 817-3296-10

描述如何使用 Sun Java Studio Enterprise 6 IDE 的 JDBC 生产率增强工具,包括如何使用这些工具创建 JDBC 应用程序。

■ Sun Java Studio 的 Web 应用程序框架文档 (PDF 格式)

■ 《Sun Java Studio 的 Web 应用程序框架 IDE 指南》 - 部件号码:817-6514-10

介绍 Sun Java Studio Enterprise 6 IDE 的各个部分,着重介绍用于开发 Web 应用程序框架应用程序的可视工具的使用。

■ 《Sun Java Studio 的 Web 应用程序框架教程》 - 部件号码:817-6516-10

介绍使用 Web 应用程序框架工具生成 Web 应用程序的机制和技术。

■ 《Sun Java Studio 的 Web 应用程序框架开发人员指南》 - 部件号码:817-6518-10

提供创建和使用应用程序组件的步骤 (这些应用程序组件经组装后通过 Web 应用程序框架可用来开发应用程序),并解释如何在大多数 J2EE 容器中部署该应用程序。

■ 《Sun Java Studio 的 Web 应用程序框架概述》 - 部件号码:817-6520-10

介绍 Web 应用程序框架及其概念、工作原理、与其它应用程序框架的区别。

■ 《Sun Java Studio 的 Web 应用程序框架标记库参考》 - 部件号码:817-6512-10概要介绍 Web 应用程序框架标记库并对该库中可用的标记进行综合引用。

前言 17

Page 18: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

■ 《Sun Java Studio 的 Web 应用程序框架组件编写人员指南》 - 部件号码:817-6522-10

介绍 Web 应用程序框架组件体系结构以及设计、创建和分发新组件的过程。

■ 《Sun Java Studio 的 Web 应用程序框架组件参考指南》 - 部件号码: 817-6524-10

介绍 Web 应用程序框架库中可用的组件。

教程、小型教程及示例

Sun Java Studio Enterprise 6 教程、小型教程和示例有助您了解 IDE 的功能。每个示例或教程都提供了代码样例,您可以在开发更多的应用程序时使用或加以修改。所有的示例和教程都以 Sun Java System Application Server 为例解释部署。

■ 可运行的完整示例。针对那些希望快速查看某项功能的作用并希望通过浏览源代码进行了解的用户。您可以在几分钟内安装、部署并执行完整的示例。

您可以在 Java Studio Enterprise 用户目录下的 AboutExamples 目录中获得完整的示例。

■ 小型教程。针对 Sun Java Studio Enterprise 6 软件的某项功能。目标用户是那些对某项特殊功能感兴趣的人员,或者是那些搜索相对较短的示例时有时间限制的人员。某些小型教程在开始时生成应用程序,而其它的小型教程则在提供的源文件上生成应用程序。小型教程的持续时间大概在 1 小时内。

您可以通过访问 Sun Java Studio Enterprise 6 开发人员门户的 “教程和代码库”页获得小型教程,位置:http://developers.sun.com/devtools/javatools/jsenterprise/learning/tutorials/index.html

■ Sun Java Studio Enterprise 6 教程(PDF 格式)演示了如何使用 Sun Java Studio Enterprise 6 的主要功能。这些教程包括:

■ 《Sun Java Studio Enterprise 6 Web 应用程序教程》 - 部件号码:817-6752-10

提供有关生成简单 J2EE Web 应用程序的分步指导。

■ 《Sun Java Studio Enterprise 6 J2EE 应用程序教程》 - 部件号码:817-6754-10

提供有关使用 EJB 组件和 Web 服务技术来生成应用程序的分步指导。

这些文档可通过 docs.sun.com 获得。完整应用程序的文档以及 zip 文件也可以通过访问 Sun Java Studio Enterprise 6 开发人员门户的 “教程和代码库”页面获得,位置:http://developers.sun.com/devtools/javatools/jsenterprise/learning/tutorials/index.html。

18 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 19: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

联机帮助

Java Studio Enterprise IDE 中提供了联机帮助。要打开帮助,请按帮助键(在 Microsoft Windows 和 Linux 环境中按 “F1”键,在 Solaris 环境中按 “Help”键),或选择 “帮助” → “内容”。执行以上任意操作都将显示一个帮助主题列表和一个搜索工具。

使用易读格式的文档

该文档以易读格式提供,以方便残障用户使用辅助技术进行阅读。您还可以按照下表所描述的信息找到文档的易读版本。

Sun 欢迎您提出意见和建议Sun 致力于提高文档质量,并欢迎您提出宝贵的意见和建议。请通过电子邮件将您的意见发送至以下地址:

[email protected]

请在电子邮件的主题行中包含文档的部件号码 (817-6754-10)。

文档类型 易读版本的格式和位置

书籍和教程 HTML 格式,位于 http://docs.sun.com

小型教程 HTML 格式,位于http://developers.sun.com/devtools/javatools/

jsenterprise/learning/tutorials/index.html

集成示例自述文件 HTML 格式,位于 java-studio-install-dir/examples 的子目录中

发行说明 HTML 格式,位于 http://docs.sun.com

前言 19

Page 20: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

20 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 21: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

第 1 章

入门

本章描述在开始学习 Sun Java Studio Enterprise 6 J2EE 应用程序教程之前必须做好哪些准备工作。本章包括以下主题:

■ “获得和安装所需软件”,其后紧跟着■ 第 23 页上的 “启动软件”■ 第 31 页上的 “建立数据库连接”■ 第 34 页上的 “教程数据库表说明”

注意 – 本书中有几个地方引用了 DiningGuide 应用程序文件。这些文件中包括教程应用程序的完整版本、描述如何运行完整应用程序的自述文件,以及创建必需的数据库表所需要的 SQL 脚本文件。这些文件压缩成 zip 文件,您可以从 Java Studio Enterprise 开发人员资源门户 Web 站点的 http://developers.sun.com/devtools/javatools/jsenterprise/learning/tutorials/index.html 页面下载该 zip 文件。

获得和安装所需软件以下各项是创建和运行教程所必需的条目。 ■ Sun Java Studio Enterprise 6 集成开发环境 (IDE)■ Sun Java System Application Server( 以前称为 Sun ONE Application Server)

Java Studio Enterprise 安装程序将安装这两个产品,除非它检测到已经安装了受支持的 Sun Java System Application Server 版本。

您可以从以下位置获得 Java Studio Enterprise 软件:

■ Java Studio Enterprise CD■ Java Studio Enterprise 门户

(http://wwws.sun.com/software/products/jsenterprise/index.html)

21

Page 22: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

■ Java Studio Enterprise 开发人员资源门户 (http://developers.sun.com/prodtech/javatools/jsenterprise/index.html)

■ Java™ 2 Platform Standard Edition (J2SE Platform) 版本 1.4.1_06 或更高版本

如果您的系统上没有安装 J2SE 的该版本 ,则 Java Studio Enterprise 安装程序会安装此版本。

■ PointBase Server 4.2 Restricted Edition 数据库软件

此教程使用 PointBase 数据库。PointBase 随 Java Studio Enterprise 软件一起安装在包含 Sun Java System Application Server 软件的子目录中。如果您的 IDE 和应用程序服务器是分别安装的,则应用程序服务器可能不包括 PointBase 软件。如果应用程序服务器不包括 PointBase 软件,则必须从http://www.pointbase.com/home.shtml下载并安装 PointBase 软件。在《Sun Java Studio Enterprise 6 安装指南》中有关于连接至外部 PointBase 安装的说明。

■ 教程数据库表

教程数据库表包含在您的用户目录中安装的缺省 PointBase 数据库中。这些表将在第 34 页上的 “教程数据库表说明”中进行描述。附录 C 描述如何在 Oracle 数据库中安装教程表。

■ Web 浏览器

您需要使用 Web 浏览器查看教程应用程序页。浏览器可以是 Netscape Communicator™ 或 Microsoft 的 Internet Explorer。

可通过 Java Studio Enterprise 开发人员资源门户的文档页面中的发行说明获知一般系统需求,该页面位于:http://developers.sun.com/devtools/javatools/jsenterprise/

reference/docs/index.html。

22 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 23: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

启动软件本节描述如何在安装 Java Studio Enterprise IDE 和 Sun Java System Application Server 软件之后进行启动。

启动 IDE启动 Java Studio Enterprise IDE 的方法有多种。此处只描述其中的一种方法。要获得更多选项,请参见 《Sun Java Studio Enterprise 6 安装指南》。

启动 IDE:

● 通过运行可执行程序启动 Java Studio Enterprise IDE。■ 在 Microsoft Windows 上,选择 “开始” → “程序” → “Sun Microsystem”

“Java Studio Enterprise 6 2004Q1” → “启动 Java Studio Enterprise”■ 在 Solaris 系统的终端窗口中运行 runide.sh 脚本,如下所示:

java-studio-install-dir 变量表示 IDE 的起始目录,缺省情况下是 /opt/SUNWjstudio。

启动应用程序服务器

Sun Java Enterprise System 安装程序会为 Sun Java System Application Server 用户创建预配置的缺省管理域 。根据服务器的设计 ,该管理域及其相关的服务器属于超级用户。

在 Microsoft Windows 计算机 上,用户通常具备带有管理特权 (即,超级用户)的用户 ID。如果您的用户 ID 具有管理特权,那么就可以使用所有缺省设置来启动应用程序服务器,这些内容在第 24 页上的 “从 IDE 的外部启动应用程序服务器和管理服务器(Microsoft Windows 用户)”或第 25 页上的 “启动缺省域的缺省管理服务器”中有所描述。

$ sh s1studio-install-directory/bin/runide.sh

% sh java-studio-install-dir/bin/runide.sh

第 1 章 入门 23

Page 24: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

在 Solaris 系统上 ,标准用户 ID 通常不具备超级用户管理特权,您的管理员可以在安装 Java Studio Enterprise (其缺省的管理域和服务器实例属于指定的非超级 (标准)用户帐户) 期间进行指定。如果这是您的帐户,那么就可以使用所有缺省设置来启动应用程序服务器,这些内容在第 25 页上的 “启动缺省域的缺省管理服务器”中有所描述。

在所有其它情况下,您的管理员在您可以启动应用程序服务器之前必须首先为您创建非超级用户域。有关创建该非超级用户域的指导说明,请查看 《Sun Java Studio Enterprise 6 安装指南》。一旦创建了该非超级用户域,请使用第 26 页上的 “启动非缺省域的管理服务器” 中描述的步骤在 IDE 中创建应用程序服务器的管理和实例节点。

从 IDE 的外部启动应用程序服务器和管理服务器 (Microsoft Windows 用户)

Microsoft Windows 用户可以通过 “开始”菜单启动管理服务器和应用程序服务器实例。这种方法启动计算机中存在的所有域的服务器。无论 IDE 是否正在运行,您都可以执行该操作。

启动应用程序服务器:

● 选择 “开始” → “程序” → “Sun Microsystems” → “Java Studio Enterprise 6 2004Q1” → “启动服务器” → “应用程序服务器”。

屏幕上会出现一个命令窗口,列出所启动的服务器。当启动了所有管理服务器和所有应用程序服务器实例后,命令窗口消失。在 IDE 中,资源管理器的 “运行环境”标签中“服务器注册”文件夹类似于如下情况:

如果您可以使用该方法启动服务器,请立即转到第 30 页上的 “将 Sun Java System Application Server 设置为缺省服务器”

值显示设置为缺省 Web 服务器和应用程序服务器的 Sun Java System Application Server 的本地安装。

管理服务器实例

应用程序服务器实例

24 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 25: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

启动缺省域的缺省管理服务器

如果您被授权使用缺省域,请根据该部分的说明进行操作。请参见第 23 页上的 “启动应用程序服务器”中的解释说明。

启动缺省管理服务器:

1. 在主 IDE 窗口的 “资源管理器”中,选择 “运行环境”标签。

资源管理器的 “运行环境”窗格显示一个节点,其中包括 “服务器注册”节点。此节点包含所有已安装 Web 服务器和应用程序服务器的子节点,同时还包含一个节点,该节点显示哪些服务器是缺省服务器。

2. 选择 “服务器注册”节点。

如果是第一次启动管理服务器,则会弹出一个查询窗口,询问您是否要启动管理服务器。这是指缺省域的管理服务器。

3. 单击 “确定”。

IDE 启动缺省管理服务器并将 Sun Java System Application Server 配置为 IDE 的缺省应用程序服务器。同时,它还创建一个服务器实例 server1。

4. 展开 “服务器注册”节点、“已安装服务器”节点和 “Sun ONE Application Server 7”节点。

资源管理器中的 “服务器注册”类似如下:

值显示设置为缺省 Web 服务器和应用程序服务器的 Sun Java System Application Server 的本

地安装。

管理服务器实例

应用程序服务器实例

第 1 章 入门 25

Page 26: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

现在,请按第 29 页上的 “从 IDE 启动应用程序服务器实例” 中的说明启动服务器实例。

启动非缺省域的管理服务器

如果您是标准用户并且管理员已经为您创建了域,请根据该部分的说明进行操作。请参见第 23 页上的 “启动应用程序服务器”中的解释说明。

启动管理服务器:

1. 在主 IDE 窗口的 “资源管理器”中,选择 “运行环境”标签。

资源管理器的 “运行环境”窗格显示许多节点,其中包括 “服务器注册”节点。此节点包含所有已安装 Web 服务器和应用程序服务器的子节点,同时还包含一个节点,该节点显示哪些服务器是缺省服务器。

2. 选择 “服务器注册”节点。

如果是第一次启动管理服务器,则会弹出一个查询窗口,询问您是否要启动管理服务器。这是指缺省域的管理服务器。

如果您单击 “确定”,此操作会创建并启动一个您无法使用的管理服务器。

3. 单击“取消”。

这会关闭查询窗口,您可以添加管理服务器。

4. 将您的管理服务器增加到 IDE 中。

a. 展开 “服务器注册”节点和 “已安装服务器”节点。

b. 右键单击 “Sun ONE Application Server 7”节点并选择 “增加管理服务器”。

则会显示 “增加管理服务器”对话框。

26 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 27: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

c. 键入值 (请参见下表),然后单击 “确定”。

请与安装了 IDE 并创建了您的用户管理域的超级用户或管理员联系,获取这些值:

d. 单击 “确定”。

可能会显示下列错误消息:

e. 单击 “确定”关闭该错误消息。

将启动本地管理服务器,并将您的新管理服务器添加到 IDE 中。资源管理器中会生成新的管理服务器节点。例如,在下面的屏幕快照中,新管理服务器的主机是 localhost,端口号是 4850。

管理服务器主机 localhost 或本地计算机名

管理服务器端口 用在 create-domain 命令中的 portnumber

用户名称 用在 create-domain 命令中的 useradmin、 username

用户口令 用在 create-domain 命令中的 userpassword、 user password

域 用在 create-domain 命令中的 userdomain

Could not connect to Admin Server. If Admin Server is local it will be started.

第 1 章 入门 27

Page 28: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

5. 创建应用程序服务器实例。

a. 右键单击新管理服务器节点,然后选择 “创建服务器实例”。

将显示 “输入服务器实例值”对话框。

b. 键入名称和可用端口号。

例如,您可以键入 MyServer 和 4855。

注意 – 在 Solaris 系统上, 1024 以下的端口号为保留值。请使用 1023 以上的端口号。在所有系统上都不要使用缺省应用程序服务器所用的端口号。

c. 单击 “确定”。

此操作启动管理服务器,您可以根据输出窗口和状态栏中的消息验证这一点。 IDE 中将创建新的服务器实例。

新管理服务器实例

28 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 29: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

6. 通过右键单击新服务器实例并选择 “设置为缺省”,设置缺省应用程序服务器和 Web 服务器。

7. 展开 “缺省服务器”节点,验证此操作。

J2EE 应用程序和 Web 层应用程序的缺省服务器会将此新的服务器显示为缺省服务器。

现在按下一部分的说明启动服务器实例。

从 IDE 启动应用程序服务器实例

当您在开发期间进行测试部署应用程序时,只要管理服务器正在运行, IDE 就会自动启动应用程序服务器实例。在这一部分,将手动启动应用程序服务器实例,以便执行本章后面所述的一些操作。

所有用户均按下列步骤启动服务器实例:

1. 右键单击应用程序服务器节点,然后选择 “状态”。

注意 – 如果没有显示此节点,则选择管理服务器实例节点,然后选择 “刷新”。

将显示如图所示的“Sun ONE Application Server 实例状态”对话框,(您的实例标签可能会有所不同)。

新服务器作为缺省服务器

第 1 章 入门 29

Page 30: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

2. 单击 “启动服务器”按钮。

(如果对话框中出现的是 “停止服务器”按钮,则说明服务器已经在运行。)

在 Microsoft Windows 系统中,会出现一个命令窗口,显示进度消息。 当 “服务器实例状态”窗口显示 “状态:正在运行”时,说明已经启动服务器。

3. 单击实例状态对话框上的 “关闭”。

现在,继续转到第 31 页上的 “建立数据库连接”。

将 Sun Java System Application Server 设置为缺省服务器

如果之前已经启动 Sun Java System Application Server,请按以下步骤确认它仍然是缺省服务器,如果不是,请将它设置为缺省服务器:

1. 在 IDE 中,选择 “资源管理器”的 “运行环境”标签。

2. 展开 “服务器注册”节点及其 “缺省服务器”子节点。

如果 “J2EE 应用程序”节点的标签是 server-instance(server-hostname:server-port-number)(如下所示),则 Sun Java System Application Server 为缺省的应用程序服务器。请转到下一部分。否则,继续执行下一步。

3. 在 “已安装服务器”节点下查找您的应用程序服务器实例,右键单击它,然后选择“设置为缺省”。

您的服务器会被设置为 J2EE 和 Web 层应用程序的缺省服务器。

“启动服务器”按钮

值显示设置为缺省应用程序服务器的 Sun Java System Application Server 的本地安装

30 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 31: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

建立数据库连接企业应用程序使用 Java 数据库连接 (JDBC™) API 与数据库交互。必须先在应用程序服务器环境中执行下列必需的 JDBC 相关操作,才能使用 Sun Java System Application Server 部署和执行企业应用程序。这些操作包括:

■ 启用数据库的 JDBC 驱动程序

■ 创建连接池

企业应用程序需要数据库连接池,以便系统中的业务对象可以共享数据库访问。

■ 创建 JDBC 数据源

通过 JDBC 数据源 (也称为 JDBC 资源),您可以使用 getConnection()方法建立与数据库的连接。

■ 创建 JDBC 持久性管理器

持久性管理器是负责管理在容器中安装的实体 bean 的持久性的组件。

在大多数情况下,所有这些操作都已经为您设置完毕,并提供了教程所需的值。如果未自动为您设置这些内容,请根据第 32 页上的 “建立 JDBC 资源”提供的指导说明进行操作。

自动启用 JDBC 驱动程序的异常在下一部分进行描述。

启用 JDBC 驱动程序

PointBase JDBC 驱动程序是随标准安装一起自动安装的,其中 Java Studio Enterprise IDE 和 Sun Java System Application Server 是一起安装的。

注意 – 如果 Java Studio Enterprise IDE 和 Sun Java System Application Server 是分别安装的,那么应用程序服务器的安装可能不包括 PointBase 软件。在这种情况下,请根据《Sun Java Studio Enterprise 6 安装指南》中提供的启用外部 PointBase 安装的指导说明进行操作。

第 1 章 入门 31

Page 32: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

建立 JDBC 资源

JDBC 资源是为缺省域自动设置的。本部分描述在这些资源未被自动设置的情况下,如何进行设置 (在 Microsoft Windows 或 Solaris 系统上)。

注意 – 在开始此过程之前,请确保管理服务器和应用程序服务器都正在运行 (请参考第 23 页上的 “启动软件”)。

为本教程创建 JDBC 连接资源:

1. 在资源管理器的 “运行环境”窗格中,展开 “服务器注册”和 “已安装服务器”节点。

2. 定位您的应用程序服务器实例。

它被标记为 app-server-name (app-server-host:app-server-port),例如 MyServer (localhost:4855)。

3. 右键单击应用程序服务器实例节点,然后选择 “预配置 PointBase JDBC 资源”。

将出现一个计时器图标 (如沙漏)。在进程完成时,光标回复为其常规图标。

4. 展开 JDBC 连接池、 JDBC 数据源和持久性管理器的已注册资源。 您应该在这些资源下看到以下节点:

■ JDBC 连接池:PointbasePool■ JDBC 数据源:jdbc/jdbc-pointbase■ 持久性管理器:jdo/PointbasePM标准用户资源管理器类似如下:

Microsoft Windows 管理员用户的资源管理器类似如下:

32 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 33: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

现在,继续转到教程的数据库表。

第 1 章 入门 33

Page 34: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

教程数据库表说明DiningGuide 教程使用两个数据库表:Restaurant 和 CustomerReview。这两个表是随标准一起安装在 PointBase 缺省 (示例)数据库中自动创建的,其中 Java Studio Enterprise 软件和 Sun Java System Application Server 是一起安装的。

但是,如果没有将 Java Studio Enterprise 软件和 Sun Java System Application Server 一起安装,则必须按照第 31 页上的 “启用 JDBC 驱动程序”中描述的过程进行操作。此操作不仅启用 PointBase JDBC 驱动程序,而且将缺省示例数据库复制到您的用户目录(使您可以使用这些表)。

在本教程中,使用表 1-1 中所示的数据库结构。这些结构是 Java Studio Enterprise 安装程序在 PointBase 数据库中创建的。

Restaurant 表包含表 1-2 中所示的记录。

表 1-1 DiningGuide 数据库表

表名 列 主键 其它

Restaurant 餐馆名称 是

烹调风格

近邻

地址

电话

描述

等级

CustomerReview 餐馆名称 是 与 “顾客名称”一起作为组合主键;引用 Restaurant (餐馆名称)

顾客名称 是

意见

表 1-2 Restaurant 表记录

餐馆名称 烹调风格 近邻 地址 电话 描述 等级

French Lemon

地中海式 Rockridge 1200 College Avenue

510 888 8888

Very nice spot.

5

Bay Fox 地中海式 Piedmont 1200 Piedmont Avenue

510 888 8888

Excellent. 5

34 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 35: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

CustomerReview 表包含表 1-3 中所示的记录。

现在,您就可以启动教程应用程序了。要么继续阅读第 2 章以了解您将生成的应用程序的概况,要么直接转到第 3 章并开始生成它。

表 1-3 CustomerReview 表记录

餐馆名称 顾客名称 意见

French Lemon Fred Nice flowers.

French Lemon Ralph Excellent Service.

第 1 章 入门 35

Page 36: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

36 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 37: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

第 2 章

教程简介

在创建教程示例应用程序的过程中,您将学习如何使用 Java Studio Enterprise 的功能生成简单的 J2EE 应用程序。

本章描述您将生成的应用程序,首先描述其要求,然后提供满足这些要求的体系结构。后一节描述如何使用 Java Studio Enterprise 的功能,即 EJB 生成器、测试应用程序工

具和 “新建 Web 服务”向导,来创建应用程序。

本章包含以下几节:

■ “教程应用程序的功能”(即接下来的主题)■ 第 39 页上的 “用户的教程应用程序视图”■ 第 41 页上的 “教程应用程序的体系结构”■ 第 44 页上的 “创建教程应用程序任务的概述”

教程应用程序的功能教程应用程序 DiningGuide 是一个简单的就餐指南应用程序,使用户能够查看可用餐馆及其特性的列表。用户还可以查看所选餐馆的顾客意见的列表,并向餐馆记录中增加意见。餐馆特性包括餐馆名称、其烹调风格、其近邻情况、地址、电话号码、餐馆的简要描述和等级 (1 - 5)。

用户与应用程序界面的交互操作如下所述:

■ 用户查看餐馆的完整列表■ 用户请求查看特定餐馆的顾客意见的列表■ 用户编写一条意见并将其增加到餐馆的意见列表中

37

Page 38: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

应用程序方案

用户执行列出数据库中的所有餐馆记录的客户端页时,与 DiningGuide 的交互就开始了。当用户退出此应用程序的客户端时,就结束了交互。现在提供了一个简单的 Swing 客户端,以说明用户如何与应用程序的功能进行交互。但是,其它类型的客户端 (如 Web 客户端或另一应用程序)也许能够访问 DiningGuide 应用程序的 business 方法。

下列方案说明应用程序内发生的交互以及应用程序的要求。

1. 用户执行应用程序的 RestaurantTable 类。

应用程序将显示 DiningGuide “餐馆列表”窗口,其中包含所有餐馆的列表 (其名称、烹调风格、位置、电话号码、简短评述和从 1 到 5 的等级)。在该页上有一个标记为 “View Customer Comments”的按钮。

2. 用户选择列表中的一条餐馆记录,然后单击给定餐馆的 “View Customer Comments”按钮。

应用程序将显示 “按餐馆名称的所有顾客意见”窗口,其中包含所选餐馆的顾客所提交的所有意见的列表。

3. 在顾客意见窗口中,用户在 “客户名称”和 “意见”字段中键入文本,然后单击“Submit Customer Review”按钮。

应用程序将顾客的姓名和意见文本增加到 CustomerReview 数据库表中,并重新显示包含增加的新记录的 “按餐馆名称的所有顾客意见”窗口。

4. 用户返回到 “餐馆列表”窗口,选择另一餐馆,然后单击 “View Customer Comments”按钮。

应用程序显示新的 “按餐馆名称的所有顾客意见”窗口,其中包含所选餐馆的所有意见。

应用程序的功能规范

以下项目列出支持应用程序方案的应用程序的用户界面的主要功能。

■ 所有餐馆数据的主视图 (通过显示的列表)

■ 餐馆列表主窗口上的一个按钮,用于检索给定餐馆的所有顾客意见数据

■ 给定餐馆的所有顾客意见数据的主视图

■ 顾客意见列表窗口上用于增加新意见的一个按钮

■ 顾客意见列表窗口上的文本输入字段,用于键入新的顾客名称和新顾客对当前餐馆的意见

■ 顾客意见列表窗口上的一个按钮,用于将已完成的意见数据提交到数据库

38 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 39: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

用户的教程应用程序视图用户的应用程序视图说明如何实现第 37 页上的 “教程应用程序的功能”中所述的方案和功能规范。

1. 在 Java Studio Enterprise 资源管理器中,右键单击 “RestaurantTable”节点,然后选择 “执行”。

IDE 切换到 “运行环境”模式。在执行窗口中将出现 “餐馆”节点。此后,显示“RestaurantTable”窗口,如下所示:

此窗口显示 Restaurant 表 (如第 34 页上的 “教程数据库表说明” 中所述)中的数据。

2. 要查看给定餐馆的顾客意见,请选择该餐馆的名称,然后单击 “View Customer Comments”按钮。

例如,选择 Bay Fox 餐馆。将显示 “CustomerReviewTable”窗口。

在此情况下,没有显示任何记录,因为数据库中没有记录。请参考表 1-3。

第 2 章 教程简介 39

Page 40: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

3. 要增加意见,请键入顾客名称和一些意见文本,然后单击 “Submit Customer Review”按钮。

例如,键入姓名 "New User" 和意见 "I'm speechless"。应用程序重新显示顾客意见窗口,如下所示:

现在显示其它餐馆的意见。

4. 在 “Restaurant List”窗口上,选择 “French Lemon”,然后单击 “View Customer Comments”按钮。

将显示新的顾客意见列表窗口,其中包含对 French Lemon 餐馆的意见。

显示了两条顾客意见记录。请参考表 1-3 以进行确认。

5. 继续增加和查看顾客意见记录。

6. 在完成后,通过关闭任一应用程序窗口来退出应用程序。

7. 要验证新的顾客意见记录是否已写入数据库,请在 IDE 中选择资源管理器的 “运行环境”标签。

40 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 41: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

8. 展开 “数据库”节点,再展开 “PointBase 连接”节点及其下的 “表”节点。

9. 右键单击 CUSTOMERREVIEW 表,然后选择 “查看数据”。

将显示一个命令编辑器窗口,其中包含在步骤 3 中输入的任何新 CustomerReview 记录,例如:

教程应用程序的体系结构教程应用程序的核心是包含两个实体类型企业 bean、两个详细资料类和一个会话 bean 的 EJB 层。实体 bean 代表两个 DiningGuide 数据库表 (Restaurant 和 CustomerReview);两个详细资料类镜像实体 bean 字段并包括每个字段的 getter 和 setter 方法。详细资料类用于减少在检索数据库数据时对实体 bean 的方法调用次数。会话 bean 管理客户端 (通过 Web 服务)和实体 bean 之间的交互。

图 2-1 显示 DiningGuide 应用程序体系结构。

第 2 章 教程简介 41

Page 42: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

图 2-1 DiningGuide 应用程序体系结构

在图 2-1 中,客户端包括一个客户端代理,此代理使用 SOAP 运行环境系统与 Web 服务器上的 SOAP 运行环境系统进行通信。请求是以 SOAP 消息的形式传递的。 Web 服务将 SOAP 消息转换为对 EJB 层会话 bean 的方法的调用。会话 bean 将其响应传回 Web 服务,这些响应由 Web 服务转换为 SOAP 消息提供给客户端代理, 终转换为数据显示或操作。

SOAP 请求是包含对 Web 服务的方法调用和序列化形式的输入数据的 XML 包装器。

42 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 43: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

应用程序元素

图 2-1 所示的元素如下:

■ 一个应用程序服务层 (EJB 层)

在此教程中生成任何其它对象之前,生成并测试 EJB 层。 EJB 层包括:

■ 使用容器管理持久性 (CMP) 的两个实体企业 bean,代表应用程序的两个数据库表

■ 两个详细资料类,容纳返回的数据库记录

■ 一个无态会话企业 bean,管理客户端发出的请求并设置返回给客户端的对象的格式。

■ Web 服务层

■ 一个包含 Servlet 和 JSP 页的 Web 模块,用于执行会话 bean 的方法

这是在为会话 bean 生成测试应用程序时自动创建的。

■ 一个 Web 服务逻辑节点,代表整个 Web 服务并允许修改和配置 Web 服务

■ 一个在部署 Web 服务时生成的客户端代理

■ 一个为客户端描述 Web 服务的 WSDL (Web 服务描述语言)文件

■ 客户端

客户端组件是显示应用程序页面的 Swing 客户端。在第 5 章中,您从提供的客户端页面 (它们实例化在第 4 章的 Web 服务中创建的客户端代理)复制代码。

EJB 层详细资料

DiningGuide 应用程序的 EJB 层包含两个实体类型的企业 bean、两个详细资料类和一个用于管理客户端和实体 bean 之间交互的会话 bean。■ Restaurant CMP EJB 组件

Restaurant bean 是一个使用容器管理持久性 (CMP) 的实体 bean,代表 Restaurant 数据库表中的数据。

■ Customerreview CMP EJB 组件

也是 CMP 类型的实体 bean,Customerreview 实体 bean 代表 CustomerReview 数据库表中的数据。

■ RestaurantDetail 类

此组件具有与 Restaurant 实体 bean 相同的字段,以及每个字段的用于从实体 bean 的远程引用检索此数据的 getter 和 setter 方法。其构造函数实例化代表餐馆数据的对象。然后,可以将此对象的格式设置为 JSP 页、 HTML 页或 Swing 组件以供客户端查看。

■ CustomerreviewDetail 类

第 2 章 教程简介 43

Page 44: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

此组件对 Customerreview 实体 bean 所起的作用与 RestaurantDetail 类对 Restaurant 实体 bean 所起的作用相同。

■ DiningGuideManager 会话 EJB 组件

此组件是一个无态会话 bean,用于管理客户端和实体 bean 之间的交互。

创建教程应用程序任务的概述教程的生成过程分为三章。在第一章 (即本书第 3 章)中,创建 EJB 层并在工作时使用 IDE 的测试应用程序工具测试每个企业 bean。然后,创建会话 bean 以管理通信量。这是手动创建 Web 服务和客户端时的通用模型。

在第二章 (即本书的第 4 章)中,创建 Web 服务并指定要引用 EJB 层的哪些 business 方法。部署 Web 服务 (它生成一个客户端代理),然后测试客户端代理。

在 后一章 (即本书第 5 章)中,将提供的两个 Swing 类安装到应用程序中并执行它们以测试应用程序。

创建 EJB 组件

在第 3 章中,您将学习如何使用 Java Studio Enterprise 的功能来执行下列操作:

■ 使用 EJB 生成器快速生成实体 bean 和会话 bean■ 从数据库结构生成类 (使用 getter 和 setter 方法)

■ 使用测试应用程序工具从企业 bean 汇编 J2EE 应用程序

■ 将 EJB 引用增加到 J2EE 应用程序

■ 将测试应用程序部署到 J2EE 引用实现应用程序服务器

■ 从测试应用程序工具创建的测试客户端页面执行企业 bean 方法。

44 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 45: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

使用 EJB 生成器

“EJB 生成器”向导自动创建组成企业 bean 的各种组件,而不管该 bean 是无态或有态会话 bean 还是具有容器管理持久性 (CMP) 或 bean 管理持久性 (BMP) 的实体 bean。在第 3 章中,创建基于现有数据库表的两个 CMP 实体 bean 和一个无态会话 bean。

在创建实体 bean 时,将学习如何在创建过程中连接到数据库,然后生成实体 bean (其字段表示表的列)。将该 bean 的基本部分生成到这样的 Java Studio Enterprise 资源管理器中,该资源管理器具有已经为起始接口、远程接口、 bean 类和主键类 (如果适用)生成的 Java 代码。您将学习如何通过使用逻辑 bean 节点 (代表整个 bean)正确地编辑和修改 bean。您将学习如何使用 EJB 生成器的 GUI 功能增加 create、 finder 和 business 方法。

创建详细资料类

详细资料类必须具有与实体 bean 相同的字段。创建两个类并为它们增加适当的 bean 属性。在增加每个属性时,激活自动生成该属性的 accessor 方法的选项。这样,您就可以获得应用程序所需的 getter 和 setter 方法。然后,对每个类的构造函数进行编码以实例化属性。 后,将代码增加到两个实体 bean 中的每一个以返回其对应详细资料类的实例。

使用测试应用程序工具

Java Studio Enterprise IDE 包括一种用于测试企业 JavaBean 组件而不必为此目的创建客户端的工具。此工具将 Sun ONE Application Server 7 用作应用程序服务器,并将企业 bean 作为包括一个 Web 模块和若干客户端 JSP 页的 J2EE 应用程序的一部分进行部署。HTML 页与这些 JSP 页进行协调,以便您可以从 Web 浏览器创建该 bean 的实例,然后执行该 bean 的 business 方法。

对于所有三个企业 bean,要分别创建测试应用程序。对于实体 bean,测试应用程序生成包含一个 Web 模块(它包含从 Web 浏览器自动生成以供客户端使用的 JSP 页)和一个用于实体 bean 的 EJB 模块的 J2EE 应用程序。会话 bean 的 EJB 模块也必须包含实体 bean 的 EJB 模块,因为前者调用这些实体 bean 上的方法。使用 IDE 中的命令将实体 bean 引用增加到会话 bean 的 EJB 模块中。在创建测试应用程序时创建的 EJB 模块以后由 Web 服务引用。

在 Web 浏览器中测试会话 bean 时,您可以执行应用程序的所有 business 方法。第 3 章 的结尾处是使用测试客户端设备的准则;如果要手动创建自己的 Web 服务和客户端,应遵循这些准则。

第 2 章 教程简介 45

Page 46: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

创建教程的 Web 服务

在第 4 章中,您将学习如何使用 Java Studio Enterprise 的功能来执行以下操作:

■ 创建逻辑 Web 服务■ 指定 Web 服务要引用哪些会话 business 方法■ 创建 J2EE 应用程序以包含 Web 服务■ 生成 Web 服务的运行环境类和客户端页面■ 生成 Web 服务的客户端代理

创建 Web 服务

Web 服务是一个逻辑实体,代表该 Web 服务中的整个对象组,便于修改和配置该 Web 服务。可以通过在资源管理器中使用 “新建”向导定义 Web 服务的名称和包位置,来创建它。在创建 Web 服务时,该向导会提示您指定希望 Web 服务引用的 business 方法。

通过将 JAX-RPC 运行环境的 URL 指定为 Web 服务的属性,使 Web 服务知道 JAX-RPC 运行环境的位置。然后,生成 Web 服务的运行环境类,这些类是实现 Web 服务的 EJB 组件。

为教程创建测试客户端

创建由前端客户端和后端 J2EE 应用程序组成的测试客户端。然后,增加对会话 bean 的 EJB 模块的引用和对 Web 服务的引用。此操作使 Web 服务的 WAR 和 EJB JAR 文件可用,因此您可以定制这些文件的属性。您定制的其中一个属性是 “Web 上下文”属性。这样,就完成了 DiningGuide 的 J2EE 应用程序,您可以部署它了。

部署 Web 服务和创建测试客户端

在部署包含 Web 服务的 J2EE 应用程序时,IDE 自动生成客户端代理和支持文件。支持文件包括每个被引用方法的 JSP 页、 JSP 错误页和欢迎页。

测试 Web 服务

使用 IDE 命令部署 DiningGuide 应用程序。这将启动应用程序服务器,并显示测试客户端的欢迎页,它在一页上显示所有操作。生成的 JSP 页包含输入字段 (在需要输入参数时)和用于执行操作的 “调用”按钮。使用这些方法来测试 Web 服务如何调用每个会话 bean 的方法。

46 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 47: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

使 Web 服务可供其他开发人员使用

虽然此教程没有描述如何将 Web 服务发布到 UDDI 注册,但是它确实描述了一种使其他开发人员能够将 Web 服务用于测试目的的非正式方法。您将学习如何生成 WSDL 文件,然后通过将它放在服务器上或通过某种其它方式 (如通过电子邮件)分发它使其变为可用。目标开发人员可以从此文件生成客户端代理,以及查找在您的 Web 服务上哪些方法是可用的。然后,他们可以相应地生成客户端,如果您为他们提供已部署 Web 服务的 URL,则他们可以根据您的 Web 服务测试其客户端。

Java Studio Enterprise IDE 还提供了单用户内部 UDDI 注册以用于测试目的。 StockApp 示例说明如何使用此设备发布 Web 服务,该示例可以从 Java Studio Enterprise 开发人员门户的 “教程和代码库”页下载。“教程和代码库”页的网址是:

http://developers.sun.com/devtools/javatools/jsenterprise/

learning/tutorials/index.html。

有关将 Web 服务发布到 UDDI 注册的完整信息,请参见《Java Studio Enterprise 编程系列》中的 《构建 Web 服务》。

安装和使用提供的客户端

演示 DiningGuide 应用程序功能的简单 Swing 客户端的代码在附录 A 中提供。此客户端由每个数据库表的 Swing 类组成。您可以创建两个类,然后用提供的代码替换其缺省代码。然后,只需执行主类即可。

通过检查提供的代码,了解客户端如何访问应用程序的方法。首先,客户端必须实例化客户端代理。这使客户端代理的方法可供客户端使用。 SOAP 运行环境使用这些方法(见图 2-1)来访问应用程序的 EJB 层的方法。

第 2 章 教程简介 47

Page 48: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

尾注根据设计,此教程应用程序是说明 Java Studio Enterprise 主要功能的运行应用程序,同时仍然足够简短以便您在短时间 (可能是一天)内创建它。这对其范围可能产生某些限制,例如,

■ 没有错误处理■ 没有调试过程■ 没有对发布 Web 服务进行描述

虽然在本书中描述的教程应用程序设计为一个您可以快速完成的简单应用程序,但是您可能希望输入整个应用程序、查看源文件或将方法代码复制并粘贴到您创建的方法中。可以从 Java Studio Enterprise 开发人员门户上的 “教程和代码库”页访问 DiningGuide 应用程序,该页的网址是:

http://developers.sun.com/devtools/javatools/jsenterprise/

learning/tutorials/index.html。

48 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 49: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

第 3 章

生成 DiningGuide 应用程序的 EJB 层

本章分步描述如何创建 DiningGuide 教程应用程序的 EJB 层。在此过程中,您将学习如何使用 EJB 生成器创建实体 bean 和会话 bean,以及如何使用 IDE 的测试机制测试 bean。本章包括以下主题:

■ “教程的 EJB 层概述”(即接下来的主题)■ 第 54 页上的 “使用 EJB 生成器创建实体 Bean”■ 第 70 页上的 “创建详细资料类以查看实体 Bean 数据”■ 第 74 页上的 “测试实体 Bean”■ 第 88 页上的 “使用 EJB 生成器创建会话 Bean”■ 第 101 页上的 “测试会话 Bean”■ 第 109 页上的 “有关创建客户端的注释”

到本章结束时,您将能够把 DiningGuide 应用程序的整个 EJB 层作为已部署的测试应用程序运行。

在创建 EJB 层之后,您就可以随意创建自己的 Web 服务和客户端页。或者,您也可以继续第 4 章,学习如何使用 Java Studio Enterprise Web 服务功能创建应用程序的 Web 服务。

49

Page 50: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

教程的 EJB 层概述在本章中,您将创建教程应用程序的核心模块,即它的 EJB 层。创建每个组件后,将使用 IDE 的测试应用程序工具对其进行测试,这会自动创建测试 Web 服务和测试客户端。

创建的 EJB 层将包括:

■ 一个 Restaurant 实体 bean■ 一个 Customerreview 实体 bean■ 一个 DiningGuideManager 会话 bean■ 一个 RestaurantDetail bean■ 一个 CustomerreviewDetail bean

有关 J2EE 体系结构中 EJB 层的作用的完整说明,请参见 《Java Studio Enterprise 编程系列》中的 《构建 Enterprise JavaBeans 组建》。该文档提供所有 bean 元素的完整描述,并解释如何在企业 bean 中支持事务、持久性和安全性。

要检查也使用 EJB 层及从其生成的 Web 服务的应用程序,请参见以下网址上的 Java Studio Enterprise “教程和代码库”页中的 PartSupplier 示例:

http://developers.sun.com/devtools/javatools/jsenterprise/

learning/tutorials/index.html。

实体 Bean实体 bean 为定义概念的一组共享数据提供一致接口。在本教程中,有以下两个概念:餐馆和顾客意见。您创建的 Restaurant 和 Customerreview 实体 bean 代表在第 1 章中创建的数据库表。

实体 bean 可以具有容器管理持久性 (CMP) 或 bean 管理持久性 (BMP)。对于 BMP 实体 bean,开发人员必须提供用于将 bean 的字段映射到数据库表列的代码。对于 CMP 实体 bean, EJB 执行环境管理持久性操作。在此教程中,使用的是 CMP 实体 bean。使用 IDE 的 EJB 生成器向导,连接到数据库并指出要映射哪些列。该向导创建映射到数据库的实体 bean。

EJB 生成器创建 CMP 实体 bean 的框架,包括所需的 home 接口、远程接口和 bean 类。该向导还创建逻辑节点以组织和便于实体 bean 的定制。

手动定义实体 bean 的 create 方法、 finder 方法和 business 方法。在定义这些方法时,IDE 自动将方法传播到相应的 bean 组件。例如,将 create 方法传播到 bean 的 home 接口,并将对应的 ejbCreate 方法传播到 bean 的类。在编辑方法时,也将传播这些更改。

50 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 51: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

对于 finder 方法,您必须定义相应的数据库语句以查找所需对象。 EJB 2.0 体系结构定义了 SQL 独立于数据库的版本 (称为 EJB QL),您将此版本用于您的语句。在部署时,Sun ONE Application Server 插件将 EJB QL 转换为适合于您的数据库的 SQL,并将该 SQL 放在部署描述符中。

会话 Bean实体 bean 代表共享数据,而会话 bean 访问跨概念且不共享的数据。会话 bean 还可以管理完成特定任务所需的步骤。会话 bean 可以是有态的,也可以是无态的。有态会话 bean 在维护客户端的持续会话状态的同时,代表客户端执行任务。无态会话 bean 不维护会话状态,而且不专用于一个客户端。在无态 bean 为客户端完成方法调用之后,该 bean 就可用于为来自另一客户端的请求提供服务。

在 DiningGuide 应用程序中,客户端请求可能包括获得数据库中有关所有餐馆的数据,或者查找给定餐馆的所有顾客意见。提交对给定餐馆的意见是另一个客户端请求。这些请求不是相互联系的,而且不要求维护会话状态。由于这些原因, DiningGuide 教程使用无态会话 bean 管理每个请求所需的不同步骤。

会话 bean 重复生成餐馆和顾客意见记录的集合以满足客户端的请求。通过将每个字段的 getter 和 setter 方法增加到实体 bean 上可以完成此任务,但是在每次会话 bean 必须检索表的行时 , 这个方法都要求为每个字段调用方法。为减少方法调用次数,此教程使用名为详细资料类的特殊 helper 类容纳行数据。

详细资料类

详细资料类是具有对应于实体 bean 的容器管理字段的字段以及每个字段的 getter 和 setter 方法的 Java 类。当会话 bean 查找实体 bean 时,它使用对应的详细资料类创建由实体 bean 返回的每个远程引用的实例。会话 bean 只需调用详细资料类的构造函数即可实例化数据行以进行查看。这样,会话 bean 就能够创建可设置为 HTML 页格式以便客户端进行查看的行实例的集合。将详细资料类实例返回给客户端所使用的网络带宽比返回实体 bean 实例的远程引用所使用的小。

图 3-1 以图形方式显示详细资料类是如何工作的。

第 3 章 生成 DiningGuide 应用程序的 EJB 层 51

Page 52: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

图 3-1 详细资料类的功能

图 3-1 中的已编号项表示以下操作:

1. Web 容器将客户端对所有餐馆数据的请求传递到 DiningGuideManager 会话 bean。

2. 会话 bean 调用 Restaurant 实体 bean 的 findAll 方法以便对 Restaurant 实体 bean 执行查找。

3. findAll 方法获得对实体 bean 的所有可用远程引用。

4. 对于返回的每个远程引用,会话 bean 都调用 Restaurant bean 的 getRestaurantDetail business 方法以获取 RestaurantDetail 类。

5. getRestaurantDetail 方法返回增加到集合中的 RestaurantDetail 对象。

6. 会话 bean 将所有 RestaurantDetail 对象的集合返回到 Web 容器 (它适当地设置数据格式以便客户端进行查看)。

52 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 53: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

步骤摘要

创建 EJB 层需要执行六个步骤:

1. 创建实体 bean

首先,在 IDE 中创建从教程的数据库表映射的数据库结构。接下来使用 EJB 生成器,通过 EJB 生成器向导创建模拟表的 CMP 实体 bean。然后,通过增加 create、finder 和 business 方法并编写其代码为实体 bean 编程。

2. 创建要传递到客户端以便显示的详细资料类。

使用与对应实体 bean 相同的字段创建两个 JavaBeans 类,并包括相同的 accessor 方法。这些类由实体 bean 用作参数、字段和返回值的类型。在网络带宽方面,将这些类返回到客户端的效率比返回实体 bean 实例的远程引用更高。

3. 在实体 bean 上创建 business 方法以获取详细资料类

4. 使用 IDE 的测试应用程序工具测试实体 bean 的方法

从每个实体 bean,您可以自动生成测试客户端;在 Web 浏览器中查看该测试客户端时,您可以创建 bean 的实例,然后执行该实例上的 business 方法。

5. 创建会话 Bean

使用 EJB 生成器创建无态会话 bean。为 bean 的 create 方法编程以便在实体 bean 及其 getter 方法上执行查找以构造详细资料对象的集合 (从每个实体 bean 的详细资料类)。创建一个在数据库中创建顾客意见记录的方法。您也可以创建 SOAP 运行环境所需的两个伪 business 方法。

6. 测试会话 bean 的方法

在测试会话 bean 之前,将对 CMP 实体 bean 的引用增加到 EJB 模块的属性表单中。然后,从会话 bean 生成包括 EJB 模块的测试应用程序。对于此模块,增加来自实体 bean 的测试应用程序的 EJB 模块。然后,使用测试客户端创建会话 bean 的实例,再执行其方法。

注意 – 您必须首先执行了第 1 章中描述的所有设置步骤,才能开始使用教程应用程序。

第 3 章 生成 DiningGuide 应用程序的 EJB 层 53

Page 54: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

使用 EJB 生成器创建实体 Bean创建两个实体 bean (即 Restaurant 和 Customerreview)以代表在第 1 章中创建的两个数据库表。

在 EJB 体系结构的 2.0 版本中,实体 bean 可以具有本地接口、远程接口或同时具有这两种接口。用于确定使用哪种接口的准则取决于调用 bean 的方法的客户端对于该 bean 是远程的还是本地的。在此教程中,创建同时具有远程接口和本地接口的实体 bean,以便为 Web 服务将访问 beans 的方法的方式提供灵活性。两种可能是:会话 bean 访问 bean 的方法 (使用本地接口)或者 Web 服务直接访问方法 (使用远程接口)。

提示 – 要获得使用 EJB 生成器的更多详细信息,请参见有关 EJB 组件的 Java Studio Enterprise 帮助主题。

注意 – 已完成的实体 bean 的源代码在附录 A 中提供。

创建 Restaurant 和 Customerreview 实体 Bean首先,创建一个目录以包含应用程序,然后将该目录安装在 IDE 中。安装一个目录会将其放在 IDE 的类路径中。接下来,在已安装的目录中,从两个数据库表创建数据库结构。 后,为 EJB 层创建包并在其中创建模拟数据库结构的两个实体 bean。

创建教程的目录

创建一个目录以包含教程的文件,然后将该目录安装到 IDE 的文件系统中,如下所述:

1. 在文件系统上的某个位置创建一个目录,并将其命名为 DiningGuide。

注意 – 如果将它创建为另一个目录的子目录,则为此教程创建的某些方法的规范 (包括文件规范)可能变得非常长。这可能导致使用 Microsoft Windows 2000(带编号小于 3 的 Service Pack)的平台出现执行问题。为避免这一问题,请在磁盘或卷的顶层创建此目录 (例如 c:\DiningGuide)。

2. 安装 DiningGuide 目录。

在资源管理器中安装对象,会将该对象放在 IDE 的类路径中。

54 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 55: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

a. 在 Java Studio Enterprise IDE 中,选择 “文件” → “安装文件系统”。

将显示 “新建向导”。

b. 选择 “本地目录”,然后单击 “下一步”。

将显示 “新建向导”的 “选择目录”页。

c. 使用“查找范围”文件查找器查找 DiningGuide 目录,选择它,然后单击“完成”。

新目录 (例如 c:\DiningGuide)已安装在资源管理器中。

为教程的表创建数据库结构

现在,创建模拟 Restaurant 和 Customerreview 数据库表的数据库结构。IDE 从数据库读取表定义并创建结构。

1. 通过选择 “工具” → “PointBase 网络服务器” → “启动服务器”,启动 PointBase 服务器。

如果 “启动服务器”命令呈浅色,则说明服务器已经运行。

2. 打开到 PointBase 示例数据库的连接。

a. 选择资源管理器的 “运行环境”标签。

b. 展开 “数据库”节点。

■ 如果有一个标记为 “jdbc:pointbase:server://localhost:9092/sample “PBPUBLIC on PBPUBLIC”的方形图标且它是完整的,请跳到步骤 3。

■ 如果有一个如上所述的方形图标但它已破裂,请右键单击它,然后选择 “连接”。

在打开连接时,破裂的方形图标将重新显示为完整的方形。

注意 – 如果没有方形图标,则说明您的 IDE 和应用程序服务器是分别安装的,而且在 IDE 中尚未启用 PointBase JDBC 驱动程序;请参考 《Sun Java Studio Enterprise 6 安装指南》以获取有关将外部 PointBase 数据库连接到 IDE 的指示。

3. 开始创建结构。

a. 右键单击资源管理器中的 “DiningGuide”节点,然后选择 “新建” → “所有模板”。

将出现 “新建向导”,此时显示的是该向导的 “选择模板”页。

b. 展开 “数据库”节点,选择 “数据库结构”,然后单击 “下一步”。

将显示 “新建向导”的 “新对象名称”页。

4. 在 “名称”字段中键入 dgSchema,然后单击 “下一步”。

将显示向导的 “数据库连接”页。

第 3 章 生成 DiningGuide 应用程序的 EJB 层 55

Page 56: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

5. 指定结构的源数据库。

a. 启用 “现有的连接”选项。

b. 从列表中选择 “jdbc:pointbase:server://localhost:9092/sample [PBPUBLIC on PBPUBLIC]”。

c. 单击 “下一步”。

将显示 “表和视图”页。

6. 选择要在结构中模拟的表。

a. 选择可用表列表中的 “CUSTOMERREVIEW”表,然后单击 “增加”按钮。

b. 选择列表中的 “RESTAURANT”表,然后单击 “增加”按钮。

CUSTOMERREVIEW 和 RESTAURANT 表将出现在选定的表和视图的列表中。

c. 单击 “完成”。

新的数据库结构将出现在资源管理器中的 DiningGuide 目录下。如果展开其所有子节点,则它看起来类似如下:

Restaurant 结构

Customerreview 结构

56 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 57: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

为 EJB 层创建 Java 包在已安装的 “DiningGuide”节点内创建一个 Java 包以容纳 EJB 层 (它是应用程序的数据)。

1. 右键单击 “DiningGuide”节点,然后选择 “新建” → “Java 包”。

2. 将新包命名为 Data,然后单击 “完成”。

新建的 Data 包将出现在 DiningGuide 目录下。

创建 Restaurant 实体 Bean创建模拟 Restaurant 表的实体 bean,如下所述:

1. 开始创建 Restaurant 实体 bean。

a. 右键单击新建的 “Data”包,然后选择 “新建” → “所有模板”。

b. 在 “模板” 向导中,展开 “J2EE”节点,选择 “CMP 实体 EJB”,然后单击 “下一步”。

将显示 “新建向导”的 “CMP 实体 Bean 名称和属性” 页 (由 EJB 生成器模块使用)。如果单击向导任一页上的 “帮助”按钮,则可以获得与创建 CMP 实体 bean 的上下文有关的帮助。

c. 将新的 CMP 实体 bean 命名为 Restaurant,然后选择以下选项:

“新建向导”看起来类似如下。

选项种类 要选择的选项

实体和字段的源 来自数据库结构对象的表

组件接口 远程和本地接口

第 3 章 生成 DiningGuide 应用程序的 EJB 层 57

Page 58: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

d. 单击 “下一步”。

这将显示 “来自数据库结构对象的表”页。

2. 指定 “RESTAURANT”结构。

a. 展开 “DiningGuide”节点以及 “dgSchema”节点下的节点,然后选择“RESTAURANT”表。

该页看起来类似如下:

58 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 59: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

b. 单击 “下一步”进入到 “CMP 字段”页。

3. 定制希望定义 CMP bean 的任何字段。

在向导创建 Restaurant 实体 bean 时,您将看到并排显示的 Restaurant 数据库表的列和将这些列映射到的对应 Java 字段。对于此教程,您希望更改 “rating”字段的类型。

a. 选择 “rating”字段,然后单击 “编辑”按钮。

将显示 “编辑持久性字段”对话框。

b. 删除 “类型”字段中的现有文本,然后键入 int。对话框看起来类似如下:

第 3 章 生成 DiningGuide 应用程序的 EJB 层 59

Page 60: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

c. 单击 “确定”关闭该对话框。

“rating” Java 字段的类型被更改为 int。

d. 单击 “下一步”。

将显示 “CMP 实体 Bean 类文件”页,该页列出将创建的 Restaurant bean 的各部分。请注意, EJB 生成器向导已经自动将新的实体 bean 命名为与数据库表同名。

4. 通过单击 “完成”,完成 bean 的创建。

这样,就创建了新的 Restaurant 实体 bean 及其所有部分,并将其显示在 “资源管理器”窗口中。

其中的五个部分是接口,一个部分是 bean 类。第六个部分是将企业 bean 的所有元素组合在一起并便于使用它们的逻辑节点。

逻辑节点

本地接口

Bean 类

本地 home 接口远程接口

远程 home 接口

60 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 61: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

创建 Customerreview 实体 Bean使用以下步骤,像创建 Restaurant bean 那样创建 Customerreview 实体 bean:

1. 开始创建 Customerreview 实体 bean。

a. 右键单击新建的 “Data”包,然后选择 “新建” → “CMP 实体 EJB”。

请注意,此项出现在上下文菜单中。每当从 “新建”菜单中选择一个项时,都会创建此快捷方式以便于您使用。

b. 命名新的 CMP bean Customerreview,然后选择以下选项:

c. 单击 “下一步”。

这将显示 “来自数据库结构对象的表”页。

2. 指定 “CUSTOMERREVIEW”结构。

a. 展开 “DiningGuide”节点及 “dgSchema”节点下的所有节点。

b. 选择 “CUSTOMERREVIEW”表。

c. 单击 “下一步”。

3. 完成 bean 的创建。

a. 单击 “CMP 字段”页上的 “下一步”。

b. 单击最后一页 (即 “CMP 实体 Bean 类文件”页)上的 “完成”。

Customerreview 实体 bean 已显示在资源管理器的 Data 包中。请注意,还有一个名为 CustomerreviewKey 的主键类。当实体 bean 具有复合主键时,会自动创建此类。(请参见第 1 章中的表 1-1 以确认此表中的复合主键。)

选项种类 要选择的选项

实体和字段的源 来自数据库方案对象的表

组件接口 远程和本地接口

第 3 章 生成 DiningGuide 应用程序的 EJB 层 61

Page 62: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

为 CMP 实体 Bean 创建 Create 方法

为两个实体 bean 创建 create 方法,增加参数和代码以初始化 bean 实例的字段。

创建 Restaurant Bean 的 Create 方法

为 Restaurant 实体 bean 创建 create 方法,如下所述:

1. 在资源管理器中,右键单击 “Restaurant(EJB)”逻辑节点 (bean 图标 )。

2. 从上下文菜单中选择 “增加 Create 方法”。

将显示 “增加 Create 方法”对话框。

3. 为 Restaurant 数据库的每一列都增加方法参数。

a. 单击 “参数”部分中的 “增加”按钮。

将显示 “输入方法参数”对话框。

b. 在 “字段名称”中键入 restaurantname。

c. 选择 “类型”中的 java.lang.String。

逻辑节点

本地接口

Bean 类

主键类

本地 home 接口

远程 home 接口

远程接口

62 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 63: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

d. 单击 “确定”(或按 “Enter”键)以创建参数并关闭对话框。

e. 同样地,创建其它参数:

注意 – 在使用测试应用程序工具测试 bean 时,创建这些参数的顺序变得很重要。按上面给出的顺序创建它们。

保留缺省创建的两个异常,并确保将方法同时增加到 Home 接口和本地 Home 接口。

4. 单击 “确定”。

IDE 传播 RestaurantHome 接口下的 create 方法、LocalRestaurantHome 接口下的另一个 create 方法和 Restaurant bean 类 (RestaurantBean) 下的 ejbCreate 方法。相关 ejbPostCreate 方法也被增加到 bean 类中。

5. 展开 “Restaurant(EJB)”逻辑节点和 “Create Methods”文件夹,然后双击 create 方法。

将显示源编辑器,而且光标位于 bean 的 ejbCreate 方法上。

注意 – 如果右键单击 create 方法节点并选择 “帮助”,则可以获得有关 create 方法的联机帮助信息。

字段名称 类型

cuisine java.lang.String

neighborhood java.lang.String

address java.lang.String.

phone java.lang.String

description java.lang.String

rating int

第 3 章 生成 DiningGuide 应用程序的 EJB 层 63

Page 64: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

6. 将以下代码 (仅粗体文本)增加到 ejbCreate 方法体中,以初始化 bean 实例的字段:

提示 – 在将代码复制并粘贴到源编辑器中之后,按“Control” + “Shift” + “F”正确地重新设置其格式。如果要从 PDF 文件进行复制,则如代码注释指示的那样,联接因自动换行而中断的行。

在 Restaurant 实体 bean 的 create 方法被调用时,它会根据此 bean 的容器管理字段在数据库中创建新记录。

7. 选择 “Restaurant(EJB)”逻辑节点,然后按 “F9”键编译 bean。Restaurant 实体 bean 将被编译,且不出现错误。

创建 Customerreview Bean 的 Create 方法

为 Customerreview 实体 bean 创建 create 方法,如下所述:

1. 右键单击 “Customerreview(EJB)”逻辑节点 (bean 图标 ),然后选择 “增加 Create 方法”。

public String ejbCreate(java.lang.String restaurantname, java.lang.String cuisine, java.lang.String neighborhood, java.lang.String address, java.lang.String phone, java.lang.String description, int rating) throws javax.ejb.CreateException {

if (restaurantname == null) {// Join the following two lines in the Source Editor

throw new javax.ejb.CreateException("The restaurant name is required.");

}setRestaurantname(restaurantname);setCuisine(cuisine);setNeighborhood(neighborhood);setAddress(address);setPhone(phone);setDescription(description);setRating(rating);

return null;}

64 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 65: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

2. 使用 “增加”按钮创建三个参数 (为 CustomerReview 表的每个列创建一个参数):

注意 – 如步骤 a 中那样,按给定的顺序创建这些参数。

缺省情况下,保留创建的两个异常,并确保将方法同时增加到 Home 接口和本地 Home 接口。

3. 单击 “确定”。

4. 打开 “Customerreview(EJB)”逻辑节点和 “Create 方法”文件夹,然后双击 create 方法。

将打开源编辑器,而且光标位于 bean 的 ejbCreate 方法上。

5. 将以下 (粗体)代码增加到 ejbCreate 方法体中,以初始化 bean 实例的字段:

提示 – 在将代码复制并粘贴到源编辑器中之后,按“Control” + “Shift” + “F”正确地重新设置其格式。如果要从 PDF 文件进行复制,则如代码注释指示的那样,联接因自动换行而中断的行。

在 ejbCreate 方法被调用时,它会根据此 bean 的容器管理字段在数据库中创建新记录。

字段名称 类型

restaurantname java.lang.String

customername java.lang.String

review java.lang.String

public CustomerreviewKey ejbCreate(java.lang.String restaurantname, java.lang.String customername, java.lang.String review) throws javax.ejb.CreateException {

if ((restaurantname == null) || (customername == null)) {// Join the following two lines in the Source Editor

throw new javax.ejb.CreateException("Both the restaurant name and customer name are required.");

}setRestaurantname(restaurantname);setCustomername(customername);setReview(review);

return null;}

第 3 章 生成 DiningGuide 应用程序的 EJB 层 65

Page 66: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

6. 选择 “Customerreview(EJB)”逻辑节点,然后按 “F9”键编译 bean。将编译 Customerreview 实体 bean,且不出现错误。

现在,在这两个实体 bean 上创建将定位上下文中每个 bean 的所有实例或选定实例的 finder 方法。

在实体 Bean 上创建 Finder 方法

在 Restaurant bean 上创建 findAll 方法,以定位所有的餐馆数据。另外,在 Customerreview bean 上创建 findByRestaurantName,以定位给定餐馆的意见数据。

每个 finder 方法 (findByPrimaryKey 除外)都必须与部署描述符中的查询元素关联。在为这两个实体 bean 创建 finder 方法时,请使用在 EJB 2.0 规范中指定的数据库无关语言(即 EJB QL)指定 SQL 语句。在部署时,应用程序服务器插件将 EJB QL 转换为目标数据库的 SQL。

创建 Restaurant Bean 的 findAll 方法

创建 Restaurant bean 的 findAll 方法:

1. 右键单击 “Restaurant(EJB)”逻辑节点,然后选择 “增加 Finder 方法”。

将显示 “增加新的 Finder 方法”对话框。

2. 在 “名称”字段中的 “find”字符串之后键入 All。

3. 选择 “返回类型”中的 java.util.Collection。

4. 接受两个缺省异常。

5. 定义 EJB QL 语句,如下所述:

6. 确保将方法同时增加到 Home 接口和本地 Home 接口中。

7. 单击 “确定”。

在 Restaurant bean 的本地接口和本地 Home 接口中即会创建新的 findAll 方法。

EJB QL 语句 文本

Select Object(o)

From Restaurant o

66 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 67: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

注意 – 如果右键单击 “Finder 方法”节点并选择 “帮助”,则可以获得有关 finder 方法的联机帮助信息。

8. 选择 “Restaurant(EJB)”逻辑节点,然后按 “F9”键编译 bean。Restaurant 实体 bean 将编译,且不出现错误。

创建 Customerreview Bean 的 findByRestaurantName 方法

创建 Customerreview bean 的 findByRestaurantName 方法:

1. 右键单击 “Customerreview(EJB)”逻辑节点,然后选择 “增加 Finder 方法”。

将显示 “增加新的 Finder 方法”对话框。

2. 在 “名称”字段中的 “find”字符串之后键入 ByRestaurantName。

3. 选择 “返回类型”中的 java.util.Collection。

4. 单击参数的 “增加”按钮。

将显示 “输入新参数”对话框。

5. 键入参数名称 restaurantname。

6. 选择参数类型 java.lang.String。

7. 单击 “确定”。

8. 接受两个缺省异常。

9. 定义 EJB QL 语句,如下所述:

(在 Where 子句中所使用的数字取决于 finder 方法中参数的位置。在这种情况下,只有一个参数,因此数字是 “1”)。

10. 确保将方法同时增加到 Home 接口和本地 Home 接口中。

11. 单击 “确定”。

即会在 Customerreview bean 的本地接口和本地 Home 接口中创建新的 findByRestaurantName 方法。

EJB QL 语句 文本

Select Object(o)

From Customerreview o

Where o.restaurantname = ?1

第 3 章 生成 DiningGuide 应用程序的 EJB 层 67

Page 68: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

12. 选择 “Customerreview(EJB)”逻辑节点,然后按 “F9”键编译 bean。Customerreview 实体 bean 将编译,且不出现错误。

创建用于测试的 Business 方法

为每个实体 bean 创建 business 方法,它返回实体 bean 参数中一个参数的值。通过 business 方法,您可以在以后测试 bean。对于 Restaurant,创建 getRating 方法;对于 Customerreview,创建 getReview 方法。

创建 Restaurant Bean 的 getRating 方法

创建 Restaurant bean 的 getRating business 方法:

1. 检查 Restaurant 实体 bean 的 business 方法。

a. 展开 “Restaurant(EJB)”逻辑节点,然后展开其 “Business 方法”节点。

此实体 bean 还没有 business 方法。

b. 展开 Restaurant bean 的类 (RestaurantBean),然后展开其 “方法”节点。

bean 上的每个字段都具有 accessor 方法,其中包括 getRating 方法。

容器使用这些方法与数据源进行同步。要在开发中使用其中的任一方法,必须将这些方法创建为 business 方法。

2. 创建 getRating business 方法。

a. 右键单击 “Restaurant(EJB)”逻辑节点,然后选择 “增加 Business 方法”。

将显示 “增加新的 Business 方法”对话框。

b. 在 “名称”字段中键入 getRating。

c. 从 “返回类型”字段的列表中选择 int。

d. 接受缺省异常 (RemoteException) 以及将同时在远程接口和本地 Home 接口中创建方法的指定。

e. 单击 “确定”。

3. 再次检查 Restaurant 实体 bean 的 business 方法。

在逻辑节点的 “Business 方法”文件夹下, getRating 方法现在作为 business 方法是可以访问的。当 getRating 方法被使用时,它返回选定餐馆记录的 “rating”列中的值。

4. 通过右键单击 “Restaurant(EJB)”逻辑节点并从上下文菜单中选择 “验证 EJB”来验证 bean。Restaurant 实体 bean 将编译,且不出现错误。现在,为 Customerreview bean 创建类似方法。

68 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 69: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

创建 Customerreview Bean 的 getReview 方法

创建 Customerreview bean 的 getReview business 方法:

1. 右键单击 “Customerreview(EJB)”逻辑节点,然后选择 “增加 Business 方法”。

将显示 “增加新的 Business 方法”对话框。

2. 在 “名称”字段中键入 getReview。

3. 在 “返回类型”字段中选择 java.lang.String。接受缺省异常 (RemoteException) 以及接受将同时在远程接口和本地 Home 接口中创建方法的指派。

4. 单击 “确定”。

现在 getReview 方法作为 business 方法是可以访问的。当 getReview 方法被调用时,它返回选定餐馆记录的 “意见”列中的值。

5. 右键单击 “Customerreview(EJB)”逻辑节点,然后从上下文菜单中选择 “验证 EJB”。

Customerreview 实体 bean 将编译,且不出现错误。

6. 检查资源管理器中的图标不再指示 bean 未经编译。

第 3 章 生成 DiningGuide 应用程序的 EJB 层 69

Page 70: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

创建详细资料类以查看实体 Bean 数据如第 51 页上的 “详细资料类”中所讨论的,此教程将详细资料类用作容纳行数据以便进行查看以及减少对实体 bean 的调用次数的机制。这些类必须具有与对应的实体 bean 相同的字段、每个字段的 access 方法和设置每个字段的构造函数。

注意 – 已完成的详细资料类的源代码在附录 A 中提供。

创建详细资料类

首先,创建 RestaurantDetail 类和 CustomerreviewDetail 类:

1. 在资源管理器中,右键单击 “Data”包,然后选择 “新建” → “所有模板”。

将显示 “新建”向导。

2. 在该向导的 “选择模板”页中,展开 “Java Beans”节点并选择 “Java Bean”。

3. 单击 “下一步”。

将显示该向导的 “新对象名称”页。

4. 在 “名称”字段中键入 RestaurantDetail,然后单击 “完成”。

新建的 bean 将显示在资源管理器中。

5. 右键单击 “Data”包节点,然后选择 “新建” → “Java Bean”。

请注意, IDE 已经创建了 Java Bean 模板的快捷方式。

6. 在 “名称”字段中键入 CustomerreviewDetail,然后单击 “完成”。

创建详细资料类属性及其 Accessor 方法

现在,复制详细资料类中实体 bean 的 CMP 字段。通过将这些字段作为 bean 属性进行增加,可以做到这一点。(如果查看实体 bean 的 bean 类的 “Bean 模式”节点,您将看到 CMP 字段存储为 bean 属性。)在增加字段的同时,您可以为每个字段自动创建 accessor 方法。

创建详细资料类属性和方法:

1. 展开 “RestaurantDetail”节点和类 “RestaurantDetail”节点。

70 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 71: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

2. 右键单击 “Bean 模式”节点,然后选择 “增加” → “属性”。

将显示 “新建属性模式”对话框。

3. 在 “名称”字段中键入 restaurantname。

4. 从 “类型”中选择 String。

5. 选择 “生成字段”选项。

6. 选择 “生成 Return 语句”选项。

7. 选择 “生成 Set 语句”选项。

8. 单击 “确定”。

9. 重复步骤 2 至步骤 8 以创建下面的其它属性:

cuisine (String)neighborhood (String)address (String)phone (String)description (String)rating (int)

10. 展开 RestaurantDetail bean 的 “方法”节点。

请注意,已经为每个字段生成了 accessor 方法。

11. 展开 “CustomerreviewDetail”节点和类 “CustomerreviewDetail”节点。

12. 重复步骤 2 至步骤 8 在 “Bean 属性”节点中创建以下属性:

restaurantname (String)customername (String)review (String)

创建详细资料类的构造函数

创建实例化类字段的详细资料类的构造函数:

1. 展开 RestaurantDetail bean,右键单击类 “RestaurantDetail”节点,然后选择 “增加” → “构造函数”。

将显示 “编辑新构造函数”对话框。

2. 增加以下方法参数,然后单击 “确定”:

java.lang.String restaurantnamejava.lang.String cuisinejava.lang.String neighborhoodjava.lang.String address

第 3 章 生成 DiningGuide 应用程序的 EJB 层 71

Page 72: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

java.lang.String phonejava.lang.String descriptionint rating

3. 将以下粗体代码增加到此 RestaurantDetail 构造函数体中以初始化字段:

提示 – 请记住,可以通过按“Control” + “Shift” + “F”重新格式化粘贴到源编辑器中的代码。

4. 同样地,将构造函数增加到带有以下参数的 CustomerreviewDetail 类:

java.lang.String restaurantnamejava.lang.String customernamejava.lang.String review

5. 将以下粗体代码增加到此 CustomerreviewDetail 构造函数体中以初始化字段:

6. 右键单击 “Data”包,然后选择 “全部编译”。

该包将编译,且不出现错误。

现在,在实体 bean 上创建 get 方法以检索详细资料类的实例。

public RestaurantDetail(java.lang.String restaurantname, java.lang.String cuisine, java.lang.String neighborhood, java.lang.String address, java.lang.String phone, java.lang.String description, java.lang.Integer rating){

System.out.println("Creating new RestaurantDetail");setRestaurantname(restaurantname);setCuisine(cuisine);setNeighborhood(neighborhood);setAddress(address);setPhone(phone);setDescription(description);setRating(rating);

}

public CustomerreviewDetail(java.lang.String restaurantname, java.lang.String customername, java.lang.String review){

System.out.println("Creating new CustomerreviewDetail");setRestaurantname(restaurantname);setCustomername(customername);setReview(review);

}

72 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 73: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

在实体 Bean 上创建 Business 方法以获取详细资料类

在返回其对应详细资料类的每个实体 bean 上创建一个方法。

创建这些方法:

1. 在资源管理器中,右键单击“Restaurant (EJB)”逻辑节点,然后选择“增加 Business 方法”。

将显示 “增加新的 Business 方法”对话框。

2. 在 “名称”字段中键入 getRestaurantDetail。

3. 对于返回类型,使用 “浏览”按钮选择 RestaurantDetail 类。

提示 – 确保选择该类 ( ),而不是 bean 的节点。

Data.RestaurantDetail 将显示在 “返回类型”字段中。

4. 确保启用了选项 “远程和本地接口”。

5. 接受所有其它缺省值,然后单击 “确定”以创建方法。

6. 在逻辑 bean 的 “Business 方法”节点下查找新方法,然后双击它以将其显示在源编辑器中。

7. 将以下粗体代码增加到方法体中:

8. 选择 “Restaurant (EJB)”逻辑节点,然后按 “F9”键编译代码。

9. 在资源管理器中,右键单击 “Customerreview (EJB)”逻辑节点,然后选择 “增加 Business 方法”。

10. 在 “名称”字段中键入 getCustomerreviewDetail。

11. 对于返回类型,使用 “浏览”按钮选择 CustomerreviewDetail 类图标。

12. 确保启用了选项 “远程和本地接口”。

13. 接受所有其它缺省值,然后单击 “确定”以创建方法。

public Data.RestaurantDetail getRestaurantDetail() {return (new RestaurantDetail(getRestaurantname(),

getCuisine(), getNeighborhood(), getAddress(), getPhone(), getDescription(), getRating()));}

第 3 章 生成 DiningGuide 应用程序的 EJB 层 73

Page 74: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

14. 在源编辑器中打开方法,然后增加以下粗体代码:

15. 右键单击 “Data”包,然后选择 “全部编译”。

整个包将编译,且不出现错误。

您已经完成了教程应用程序的实体 bean 及其详细资料类帮助器的创建。接下来的任务是测试 bean。

测试实体 Bean使用 Java Studio Enterprise IDE,您可以创建测试客户端以执行实体 bean 上的方法。测试客户端使用 JavaServer Pages 技术,通过该技术您可以创建 bean 的实例并在 Web 浏览器中执行 bean 的 create、 finder 和 business 方法。

使用此测试客户端执行 Restaurant bean 的 create 和 getRating 方法。

为 Restaurant Bean 创建测试客户端

在创建测试客户端时, IDE 生成一个 EJB 模块、一个 J2EE 应用程序模块和许多支持元素。

为 Restaurant 实体 bean 创建测试客户端:

1. 右键单击 “Restaurant(EJB)”逻辑节点,然后选择 “创建新的 EJB 测试应用程序”。

将显示 “EJB 测试应用程序”向导。

2. 接受所有缺省值。

该向导的窗口看起来类似如下:

public Data.CustomerreviewDetail getCustomerreviewDetail() {return (new CustomerreviewDetail(getRestaurantname(),

getCustomername(), getReview()));}

74 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 75: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

3. 单击 “确定”。

此时,会暂时出现一个进度监视器,当进程完成时将关闭该监视器。屏幕上会显示另一个窗口,通知您创建的 Web 模块在 “项目”标签中也是可见的。该窗口也将自动关闭。如果它没有关闭,请单击 “确定”关闭窗口。

4. 在资源管理器中查看结果测试对象。

IDE 已经创建了一个名为 Restaurant_EJBModule 的 EJB 模块、一个名为 Restaurant_WebModule 的 Web 模块 (它也是单独安装的)和一个名为 Restaurant_TestApp 的 J2EE 应用程序。 Web 模块包含许多支持测试客户端的 JSP 页。J2EE 应用程序包括对 EJB 模块和 Web 模块的引用。

第 3 章 生成 DiningGuide 应用程序的 EJB 层 75

Page 76: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

由 IDE 创建的 J2EE 应用程序包含对 Web 模块和 EJB 模块的引用。通过展开 Restaurant_TestApp,您可以看到这些对象:

Web 模块

JSP 页

EJB 模块

J2EE 应用程序

Web 模块(已安装)

76 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 77: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

为 Sun Java System Application Server 插件提供数据库信息

为了使测试客户端找到数据库并登录到它,您必须将有关数据库的信息增加到 EJB 模块的应用程序服务器属性中。

增加所需的信息:

1. 在资源管理器中展开 EJB 模块 (Restaurant_EJBModule),然后选择该模块下的“Restaurant”节点 (对 Restaurant bean 的引用)以显示其属性。

如果尚未显示 “属性”窗口,请选择 “查看” → “属性”。

2. 选择 “属性”窗口的 “Sun ONE AS”标签。

3. 确认如表所示设置了以下属性:

如果显示这些值,则继续执行步骤 5。

4. 如果没有显示这些值,则重新映射 Restaurant 引用,如下所述:

a. 选择 “已映射的字段”值的值字段,然后单击省略号按钮。

将显示 “映射到数据库”向导。

b. 单击 “下一步”以查看 “选择表”页。

c. 从 “主表”字段的下拉列表中选择 “RESTAURANT”。

如果 RESTAURANT 不在列表中,请使用 “浏览”按钮在 dgSchema 结构中查找该表。

d. 单击 “下一步”以查看 “字段映射”页。

e. 如果字段没有被映射,请单击 “自动映射”按钮。

将出现每个字段的映射值,如图所示:

属性 值

已映射的字段 已映射的 7 个容器管理字段

已映射的主表 RESTAURANT

已映射的结构 dgSchema

第 3 章 生成 DiningGuide 应用程序的 EJB 层 77

Page 78: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

f. 单击 “完成”。

现在,值应该像步骤 3 中那样显示。

5. 选择 EJB 模块 (Restaurant_EJBModule) 以显示其属性。

6. 选择 “属性”窗口的 “Sun ONE AS”标签。

7. 在 “CMP 资源”属性的值字段中单击以显示省略号按钮。

8. 单击省略号按钮以显示 “CMP 资源”属性编辑器。

9. 在 “Jndi 名称”字段中键入 jdo/PointbasePM。这是在第 32 页上的 “建立 JDBC 资源”中描述的 JDBC 持久性管理器的 JNDI 名称。

10. 在 “名称”和 “口令”字段中,键入数据库的用户名称和口令。

对于 PointBase 示例数据库,用户名称和口令都是 PBPUBLIC。编辑器看起来类似如下:

78 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 79: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

11. 单击 “确定”以接受这些值并关闭属性编辑器。

您已经完成了将测试应用程序配置为使用您的数据库的操作,现在您可以部署测试应用程序。

部署并执行 Restaurant Bean 的测试应用程序

注意 – 在部署测试应用程序和访问数据库的任何其它 J2EE 应用程序之前,确保 PointBase 服务器正在运行。此外,请确保 Sun Java System Application Server 正在运行而且是 IDE 的缺省应用程序服务器。要获得有关信息,请参见第 30 页上的 “将 Sun Java System Application Server 设置为缺省服务器”。

部署 Restaurant 测试应用程序:

● 右键单击“Restaurant_TestApp” J2EE 应用程序节点,然后从上下文菜单中选择“执行”。

“进度监视器”窗口将显示部署过程的进度。输出窗口上服务器实例的日志文件标签将显示进度消息。如果看到成功消息,则说明应用程序已成功部署。

IDE 启动缺省 Web 浏览器并显示测试应用程序的主 URL:http://server-host:server-port-number/Restaurant_TestApp/dispatch.jsp

您的浏览器显示的测试客户端如下所示:

第 3 章 生成 DiningGuide 应用程序的 EJB 层 79

Page 80: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

注意 – 如果看不到浏览器,请查看 IDE 窗口的背后。通过检查输出窗口上服务器实例的日志文件标签,您可以验证是否已部署应用程序。如果看到成功消息,则说明应用程序已成功部署。

使用测试客户端测试 Restaurant Bean在显示的测试客户端的 Web 页上,使用 Restaurant bean 的 home 接口的 create 方法创建 bean 的实例。然后,测试该实例上的 business 方法 (在这种情况下为 getRating)。

测试 Restaurant bean:

1. 通过调用 create 方法,创建 Restaurant bean 的实例。

create 方法位于标题“调用 Data.RestaurantHome 上的方法”下。在该方法下有七个字段。这些字段没有命名,但是您可以按它们的顺序(与您创建它们的顺序相同)推断出它们的名称(请参见第 62 页上的“为 CMP 实体 Bean 创建 Create 方法”下的步骤 a)。

注意 – 在资源管理器中双击 Restaurant.create 方法,将其显示在源编辑器中;字段的顺序显示在方法的定义中。

提示 – 如果希望按另一种顺序显示参数,请右键单击资源管理器中的“Restaurant.create”方法节点,然后选择 “定制”。在 “定制器”对话框中,通过选择并单击 “上移”和 “下移”按钮重新排列参数。然后,通过右键单击资源管理器中测试应用程序的节点并选择 “部署”重新部署测试应用程序。

在测试会话期间创建的对象的列表。

显示上一次方法调用的结果的区域。

可以输入参数和调用方法的区域。

正在测试的实例的列表,它以正在测试的 bean 的 home 接口

开头。

80 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 81: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

在字段中键入任何所需数据,例如 (您的字段顺序可能不同):

2. 单击 create 方法旁边的 “Invoke”按钮。

已部署的测试应用程序将创建的记录增加到测试数据库中。新的 Restaurant 实例按其 restaurantname 值在左上部列出,新的数据对象在右上部列出,如图所示。

结果显示在 “结果”区域中。

第 3 章 生成 DiningGuide 应用程序的 EJB 层 81

Page 82: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

3. 通过单击 Restaurant bean 旁边的 “Invoke”按钮,测试其 findAll 方法。

结果区域应该看起来类似如下:

请注意,已返回了三个项。这说明已将您在步骤 2 中创建的新数据库记录增加到在第 1章中创建的两个数据库记录中。

4. 通过键入 Bay Fox 并单击 findByPrimaryKey 方法旁边的 “Invoke”按钮,测试该方法。

结果区域显示已经返回了 Bay Fox 记录。

现在,测试实体 bean 的 business 方法。

5. 选择在实例列表左上部的 Data.RestaurantHome 下列出的 Joe's House of Fish 的实例。

现在, getRating 方法已在 “调用方法”区域下列出。

6. 单击 getRating 方法旁边的 “Invoke”按钮。

此操作的结果在 “结果”区域中列出,并且应该看起来类似如下:

82 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 83: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

这说明您已经在数据库中创建了一个新记录,并使用 getRating 方法检索了它的其中一个字段的值。

通过选择已创建的对象并调用其方法,继续进行测试。例如,如果选择其中一个 Data.RestaurantDetail 对象,则可以调用其 getter 方法查看其数据,或者调用其 setter 方法向数据库中写入新数据。

7. 在完成测试时,可以退出浏览器,根据需要将浏览器指向另一个 URL 或者不执行任何操作

检查对数据库的增加

验证 Restaurant_TestApp 应用程序是否已将数据插入到数据库中:

1. 在 IDE 中,选择资源管理器的 “运行环境”标签。

2. 展开 “数据库”节点、“PointBase”连接节点和 “表”节点。

将显示示例数据库中每个表的节点。

3. 右键单击 “RESTAURANT”表,然后选择 “查看数据”。

将显示一个命令编辑器窗口,该窗口显示您在第 80 页上的 “使用测试客户端测试 Restaurant Bean”下的步骤 1 中输入的 Restaurant 新记录,如图所示。

第 3 章 生成 DiningGuide 应用程序的 EJB 层 83

Page 84: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

现在,您可以创建 Customerreview Bean 的测试客户机了。

注意 – 您不必停止应用程序服务器的进程 (它在执行窗口中列出)。每当重新部署时,服务器都会卸下应用程序,然后重新部署它。在退出 IDE 时,将显示一个对话框,提示您终止应用程序服务器的实例进程。但是,您可以随时手动终止它,方法是右键单击执行窗口中的 “server1(hostname:host-port)”节点,然后选择 “终止进程”。

为 Customerreview Bean 创建测试客户端

为 Customerreview 实体 bean 创建测试客户端,方法是重复第 74 页上的“为 Restaurant Bean 创建测试客户端”中的所有步骤,但使用适合于 Customerreview bean 的值。

创建测试客户端应用程序的摘要:

1. 选择 “Customerreview(EJB)”逻辑 bean,然后选择 “创建新的 EJB 测试应用程序”。

2. 接受所有缺省值,然后单击 “确定”。

使用适合于 Customerreview bean 的值,增加插件的数据库信息 (类似于第 77 页上的“为 Sun Java System Application Server 插件提供数据库信息”中的描述)。

将数据库信息增加到插件中的摘要:

84 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 85: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

1. 展开 EJB 模块 (Customerreview_EJBModule),选择该模块下的 “Customerreview”节点,并显示其属性。

2. 选择 “属性”窗口的 “Sun ONE AS”标签。

3. 确认相应属性的以下三个值:

如果显示这些值,则继续执行步骤 5。

4. 如果没有显示这些值,则重新映射 Customerreview bean,如下所述:

a. 将 “已映射的结构”设置为 Data/dgSchema。

b. 将 “已映射的主表”设置为 CUSTOMERREVIEW。

c. 单击 “已映射的字段”属性的值字段中的省略号按钮。

d. 在向导中,单击 “下一步”以查看 “选择表”页。

e. 从 “主表”字段的下拉列表中选择 CUSTOMERREVIEW。

f. 单击 “下一步”以查看 “字段映射”页。

g. 如果字段没有映射,请单击 “自动映射”按钮。

h. 单击 “完成”。

5. 显示 EJB 模块 (Customerreview_EJBModule) 属性。

6. 选择属性窗口的 “Sun ONE AS”标签。

7. 单击 “CMP 资源”属性的值字段中的省略号按钮。

8. 在 “CMP 资源”属性编辑器的 “Jndi 名称”字段中键入 jdo/PointbasePM。

9. 在 “名称”和 “口令”字段中,键入数据库的用户名和口令。

对于 PointBase 示例数据库,用户名和口令都是 PBPUBLIC。

10. 单击 “确定”以接受这些值并关闭属性编辑器。

属性 值

已映射的字段 已映射的 3 个容器管理字段

已映射的主表 CUSTOMERREVIEW

已映射的结构 dgSchema

第 3 章 生成 DiningGuide 应用程序的 EJB 层 85

Page 86: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

部署并执行 Customerreview Bean 的测试应用程序

注意 – 确保在部署测试应用程序或者访问数据库的任何其它 J2EE 应用程序之前 PointBase 服务器正在运行。此外,请确保 Sun Java System Application Server 正在运行而且它是 IDE 的缺省应用程序服务器。要获得有关信息,请参见第 30 页上的“将 Sun Java System Application Server 设置为缺省服务器”。

部署 Customerreview 测试应用程序:

● 右键单击 “Customerreview_TestApp J2EE”应用程序节点,然后从上下文菜单中选择“执行”。

“进度监视器”窗口将显示部署过程的进度。输出窗口上服务器实例的日志文件标签显示进度消息。如果看到成功消息,则说明应用程序已成功部署。

IDE 启动缺省 Web 浏览器并显示测试应用程序的主 URL:http://serve-host:server-port-number/Customerreview_TestApp/dispatch.jsp

注意 – 如果看不到浏览器,请查看 IDE 窗口的背后。您可以通过检查输出窗口上服务器实例的日志文件标签,验证是否已部署应用程序。如果看到成功消息,则说明应用程序已成功部署。

测试 Customerreview 实体 Bean在测试客户端的 Web 页上,使用 Customerreview bean 的 home 接口的 create 方法创建 bean 的实例。然后,在该实例上测试 business 方法 (在这种情况下为 getCustomerreview)。

测试会话 Customerreview bean:

1. 通过调用 create 方法创建 Customerreview bean 的实例。

create 方法位于标题 “调用 Data.CustomerreviewHome 上的方法”之下。在该方法下有三个字段。

2. 在三个字段中键入值。

在字段中键入任何所需数据,例如 (您的字段顺序可能不同):

86 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 87: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

3. 单击 create 方法旁边的 “Invoke”按钮。

已部署的测试应用程序将您创建的记录增加到测试数据库中。新的 Restaurant 实例按其 restaurantname 值在左上部列出,新的数据对象在右上部列出,如图所示。

4. 在 findByRestaurantName 方法的字段中,键入 French Lemon,然后单击 “Invoke”按钮。

结果看起来类似如下 (显示返回的 French Lemon 记录):

5. 在 “导航”单元格 (左上部)中,选择 CustomerreviewKey 实例。

6. 查找实例的 getReview 方法,然后单击其 “Invoke”按钮。

结果显示在步骤 2 和步骤 3 中创建的实例的顾客意见,例如:

第 3 章 生成 DiningGuide 应用程序的 EJB 层 87

Page 88: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

通过选择创建的对象并调用其方法,继续进行测试。

7. 在完成测试时,可以退出浏览器,根据需要将浏览器指向另一个 URL 或者不执行任何操作。

检查对数据库的增加

如在第 83 页上的 “检查对数据库的增加”中测试 Restaurant_TestApp 那样,验证 Customerreview_TestApp 应用程序是否在数据库中插入了数据:

1. 在 IDE 中,选择资源管理器的 “运行环境”标签。

2. 展开 “数据库”节点、“PointBase”连接节点和 “表”节点。

3. 右键单击 CUSTOMERREVIEW 表,然后选择 “查看数据”。

您的新意见记录会显示在命令编辑器中。

使用 EJB 生成器创建会话 Bean创建一个无态会话 bean 以管理客户端 (您将在第 4 章中创建的 Web 服务)和实体 bean 之间的会话。

注意 – 已完成的会话 bean 的源代码在附录 A 中提供。

在 EJB 体系结构的 2.0 版本中,会话 bean 可以具有本地接口、远程接口或者同时具有这两种接口。在此教程中,会话 bean 的方法将由测试应用程序(它对于会话 bean 是本地的)、 Web 服务 (也是本地的)或客户端 (远程)调用。因此,可以创建同时具有本地接口和远程接口的会话 bean。

1. 在 Java Studio Enterprise 资源管理器中,右键单击 “Data”包,然后选择 “新建”→ “所有模板”。

将显示 “新建”向导,此时显示的是该向导的 “选择模板”页。

2. 展开 “J2EE”节点,然后选择 “会话 EJB”。

88 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 89: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

3. 单击 “下一步”。

将显示 “会话 Bean 名称和属性”页。

i. 在 “名称”字段中键入 DiningGuideManager,然后选择以下选项:

4. 单击 “下一步”。

将显示向导的 “会话 Bean 类文件”页,该页列出将为此会话 bean 创建的所有组件。

请注意,所有组件的名称都基于 DiningGuideManager。

5. 单击 “完成”。

新的 DiningGuideManager 会话 bean 即会显示在资源管理器中。

现在,创建会话 bean 的方法。

选项种类 要选择的选项

状态 无态

事务类型 容器管理

组件接口 远程和本地接口

DiningGuideManager 会话 bean

第 3 章 生成 DiningGuide 应用程序的 EJB 层 89

Page 90: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

编写会话 Bean 的 Create 方法的代码

create 方法是在创建 DiningGuideManager 会话 bean 时创建的。现在,您将修改它。

无态会话 bean 的 Create 方法没有参数,因为会话 bean 不维护需要初始化的进行中状态。 DiningGuideManager 会话 bean 的 create 方法必须首先创建初始上下文,然后使用它获得所需的远程引用。

1. 在逻辑 bean 的 Create 文件夹中定位 DiningGuideManager 的 create 方法,然后双击它以便在源编辑器中显示它。

2. 从对 RestaurantHome 接口远程引用的 JNDI 查找开始编写方法的代码。

提示 – 请记住,您可以通过按 “Control” + “Shift” + “F”,重新设置复制到源编辑器中的代码的格式。还要记住删除代码注释所指出的换行符。

public void ejbCreate(){// Join the following two lines in the Source Editor

System.out.println("Entering DiningGuideManagerEJB.ejbCreate()");

Context c = null;Object result = null;

if (this.myRestaurantHome == null) {try {

c = new InitialContext();result =

c.lookup("java:comp/env/ejb/Restaurant");myRestaurantHome =

(RestaurantHome)javax.rmi.PortableRemoteObject.narrow (result, RestaurantHome.class);

}catch (Exception e) {System.out.println("Error:"+

e); }}

90 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 91: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

3. 在前面的代码下,为 CustomerreviewHome 接口增加类似的 JNDI 查找。

4. 现在,为 javax.naming 包增加 import 语句。

在文件顶部增加 import 语句。您必须输入 javax.naming,因为它包含您刚使用的 lookup 方法。

5. 声明 myRestaurantHome 和 myCustomerreviewHome 字段。

将这两个声明增加到 import 语句之后的 DiningGuideManagerEJB 会话 bean 定义中。

6. 选择 “DiningGuideManager(EJB)”逻辑节点,然后按 “F9”键编译 bean。

接下来,创建 DiningGuideManager 的 business 方法。

Context crc = null;Object crresult = null;

if (this.myCustomerreviewHome == null) {try {

crc = new InitialContext();result =

crc.lookup("java:comp/env/ejb/Customerreview");myCustomerreviewHome =

(CustomerreviewHome)javax.rmi.PortableRemoteObject.narrow(result, CustomerreviewHome.class);

}catch (Exception e) {System.out.println("Error:"+

e); }}

import javax.naming.*;

public class DiningGuideManagerBean implements javax.ejb.SessionBean {

private javax.ejb.SessionContext Context;private RestaurantHome myRestaurantHome;private CustomerreviewHome myCustomerreviewHome;

第 3 章 生成 DiningGuide 应用程序的 EJB 层 91

Page 92: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

创建 Business 方法以获得详细资料数据

DiningGuideManager bean 需要一个这样的方法:它在收到客户端发出的要查看餐馆列表的请求时检索所有餐馆数据。它还需要一个方法,该方法在客户端请求顾客意见列表时检索特定餐馆的意见数据。创建 getAllRestaurants 和 getCustomerreviewsByRestaurant 方法以满足这些要求。

创建 getAllRestaurants 方法

创建 getAllRestaurants business 方法:

1. 右键单击 “DiningGuideManager”逻辑节点,然后选择 “增加 Business 方法”。

将显示 “增加新的 Business 方法”对话框。

2. 在 “名称”字段中键入 getAllRestaurants。

3. 在 “返回类型”字段中键入 java.util.Vector。

4. 确保启用了 “远程和本地接口”选项。 此方法应该同时增加到远程接口和本地接口。

5. 接受所有其它缺省值,然后单击 “确定”。

将在 DiningGuideManager 会话 bean 的 business 方法中创建方法 shell。

92 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 93: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

6. 在源编辑器中打开方法,并增加以下代码 (仅限粗体):

注意 – 请记住,删除代码注释所指出的换行符。

此代码为上下文中 Restaurant bean 的每个远程引用获取 RestaurantDetail 的实例,将它增加到名为 restaurantList 的向量中,并返回此向量。

7. 选择 “DiningGuideManager(EJB)”逻辑节点,然后按 “F9”键编译 bean。

现在,创建类似方法以获得顾客意见的列表。

public java.util.Vector getAllRestaurants() {// Join the following two lines in the Source Editor

System.out.println("Entering DiningGuideManagerEJB.getAllRestaurants()");

java.util.Vector restaurantList = new java.util.Vector();try {

java.util.Collection rl = myRestaurantHome.findAll();

if (rl == null) { restaurantList = null; }else {

RestaurantDetail rd;java.util.Iterator rli = rl.iterator();while ( rli.hasNext() ) {

rd =((Restaurant)rli.next()).getRestaurantDetail();

System.out.println(rd.getRestaurantname());System.out.println(rd.getRating());restaurantList.addElement(rd);

}}

} catch (Exception e) {

// Join the following two lines in the Source EditorSystem.out.println("Error in

DiningGuideManagerEJB.getAllRestaurants():" + e);}

// Join the following two lines in the Source EditorSystem.out.println("Leaving

DiningGuideManagerEJB.getAllRestaurants()");return restaurantList;

}

第 3 章 生成 DiningGuide 应用程序的 EJB 层 93

Page 94: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

创建 getCustomerreviewsByRestaurant 方法

创建 getCustomerreviewsByRestaurant 方法:

1. 右键单击 “DiningGuideManager”逻辑节点,然后选择 “增加 Business 方法”。

将显示 “增加新的 Business 方法”对话框。

2. 在 “名称”字段中键入 getCustomerreviewsByRestaurant。

3. 在 “返回类型”字段中键入 java.util.Vector。

4. 单击 “增加”按钮以增加具有以下值的参数:

5. 单击 “确定”以关闭对话框并创建方法参数。

6. 确保启用了 “远程和本地接口”选项。

7. 接受所有其它缺省值,然后再次单击 “确定”创建 business 方法。

即会在 DiningGuideManager 会话 bean 中创建该方法。

参数名称 类型

restaurantname java.lang.String

94 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 95: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

8. 在源编辑器中查找该方法并增加以下粗体代码:

注意 – 请记住删除代码注释所指出的换行符。

与 getAllRestaurants 代码类似,此方法为上下文中 Customerreview bean 的每个远程引用检索 CustomerreviewDetail 的实例,将它增加到名为 reviewList 的向量中,然后返回此向量。

9. 选择 “DiningGuideManager(EJB)”逻辑节点,然后按 “F9”键编译 bean。

public java.util.Vector getCustomerreviewsByRestaurant(java.lang.String

restaurantname) {// Join the following two lines in the Source Editor

System.out.println("Entering DiningGuideManagerEJB.getCustomerreviewsByRestaurant()");

java.util.Vector reviewList = new java.util.Vector();try {

java.util.Collection rl = myCustomerreviewHome.findByRestaurantName(restaurantname);

if (rl == null) { reviewList = null; }else {

CustomerreviewDetail crd;java.util.Iterator rli = rl.iterator();while ( rli.hasNext() ) {

crd =((Customerreview)rli.next()).getCustomerreviewDetail();

System.out.println(crd.getRestaurantname());

System.out.println(crd.getCustomername());System.out.println(crd.getReview());reviewList.addElement(crd);

}}

} catch (Exception e) {

// Join the following two lines in the Source EditorSystem.out.println("Error in

DiningGuideManagerEJB.getCustomerreviewsByRestaurant():" + e);}

// Join the following two lines in the Source EditorSystem.out.println("Leaving

DiningGuideManagerEJB.getCustomerreviewsByRestaurant()");return reviewList;

}

第 3 章 生成 DiningGuide 应用程序的 EJB 层 95

Page 96: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

创建 Business 方法以创建顾客意见记录

现在,创建一个调用 Customerreview 实体 bean 的 create 方法的 business 方法以便在数据库中创建新记录。

创建 createCustomerreview 方法:

1. 右键单击 “DiningGuideManager”逻辑节点,然后选择 “增加 Business 方法”。

将显示 “增加新的 Business 方法”对话框。

2. 在 “名称”字段中键入 createCustomerreview。

3. 在 “返回类型”字段中键入 void。

4. 使用 “增加”按钮增加具有以下值的三个参数:

5. 单击 “确定”关闭 “增加参数”对话框。

6. 确保启用了 “远程和本地接口”选项。

7. 再次单击 “确定”以创建 business 方法。

即会在 DiningGuideManager 会话 bean 中创建该方法。

参数名称 类型

restaurantname java.lang.String

customername java.lang.String

review java.lang.String

96 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 97: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

8. 在源编辑器中查找该方法,并增加以下粗体代码:

注意 – 确保删去注释所指出的三个换行符。

9. 再次选择 “DiningGuideManager(EJB)”逻辑节点,然后按 “F9”键编译 bean。

创建返回 “详细资料类”类型的 Business 方法

您将在第 4 章中创建的 Web 服务是 SOAP RPC Web 服务的 JAX-RPC 实现。 SOAP(简单对象访问协议)是使 Web 服务可以使用 HTTP 和 XML 彼此进行通信的抽象信息传送技术。 SOAP 运行环境必须知道 Web 服务所调用的任何方法采用的所有 Java 类型,以便将它们正确地映射到 XML 中。由于教程的 Web 服务将调用会话 bean 方法,因此它需要知道这些方法所使用的每种类型。

SOAP 运行环境所无法知道的一种类型是组成集合的对象的类型。您刚创建的方法(getAllRestaurants 和 getCustomerreviewsByRestaurant)都返回详细资料类的集合。您必须通过为每个详细资料类创建返回该类的方法,使 SOAP 运行环境知道这些类。您将创建的方法是 getRestaurantDetail 和 getCustomerreviewDetail 方法。

您在实体 bean 上创建了同名的方法 (请参见第 73 页上的 “在实体 Bean 上创建 Business 方法以获取详细资料类”),但是现在您创建的方法是空的,其目的仅仅是为 SOAP 运行环境提供所需的返回类型。

要获得 Java Studio Enterprise Web 服务和 SOAP 运行环境的更多信息,请参见 《Sun Java Studio Enterprise 6 编程系列》中的 《构建 Web 服务》。

public void createCustomerreview(java.lang.String restaurantname, java.lang.String customername, java.lang.String review) {// Join the following two lines in the Source Editor

System.out.println("Entering DiningGuideManagerEJB.createCustomerreview()");

try {Customerreview customerrev =

myCustomerreviewHome.create(restaurantname, customername, review);

} catch (Exception e) {// Join the following two lines in the Source Editor

System.out.println("Error in DiningGuideManagerEJB.createCustomerreview():" + e);

}// Join the following two lines in the Source Editor

System.out.println("Leaving DiningGuideManagerEJB.createCustomerreview()");}

第 3 章 生成 DiningGuide 应用程序的 EJB 层 97

Page 98: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

创建 getRestaurantDetail 方法

创建 getRestaurantDetail 方法:

1. 右键单击 “DiningGuideManager”逻辑节点,然后选择 “增加 Business 方法”。

将显示 “增加新的 Business 方法”对话框。

2. 在 “名称”字段中键入 getRestaurantDetail。

3. 对于返回类型,使用 “浏览”按钮选择 RestaurantDetail 类。

确保选择的是类 ( ),而不是 bean 的节点。 Data.RestaurantDetail 将显示在“返回类型”字段中。

4. 确保启用了 “远程和本地接口”选项。

5. 接受所有其它缺省值,然后单击 “确定”以创建 business 方法并关闭对话框。

即会在 DiningGuideManager 会话 bean 中创建该方法。

6. 在源编辑器中查找该方法,然后增加以下粗体代码:

创建 getCustomerreviewDetail 方法

创建 getCustomerreviewDetail 方法:

1. 右键单击 “DiningGuideManager”逻辑节点,然后选择 “增加 Business 方法”。

将显示 “增加新的 Business 方法”对话框。

2. 在 “名称”字段中键入 getCustomerreviewDetail。

3. 对于返回类型,使用 “浏览”按钮选择 CustomerreviewDetail 类。

Data.CustomerreviewDetail 将显示在 “返回类型”字段中。

4. 确保启用了 “远程和本地接口”选项。

5. 单击 “确定”以创建 business 方法并关闭对话框。

即会在 DiningGuideManager 会话 bean 中创建该方法。

public Data.RestaurantDetail getRestaurantDetail() {return null;

}

98 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 99: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

6. 在源编辑器中查找该方法,然后增加以下粗体代码:

7. 右键单击 “DiningGuideManager(EJB)”,然后选择 “验证 EJB”。

DiningGuideManager 会话将验证,且不出现错误。

增加 EJB 引用

在部署会话 bean 时,它的属性必须包含对它所调用的任何实体 bean 方法的引用。现在,将这些引用增加到会话 bean 中;将 bean 组装到 EJB 模块之后,您无法增加它们。

1. 在资源管理器中,选择 “DiningGuideManager(EJB)”逻辑节点。

2. 将显示 bean 的属性表单。

如果还看不见 “属性”窗口,请选择 “查看” → “属性”。

3. 选择 “属性”窗口的 “引用”标签。

4. 单击 “EJB 引用”字段,然后单击省略号 (…) 按钮。

将显示 “EJB 引用”属性编辑器。

5. 单击 “增加”按钮。

将显示 “增加 EJB 引用”属性编辑器。

6. 在 “引用名称”字段中键入 ejb/Restaurant。

7. 对于 “引用的 EJB 名称”字段,单击 “浏览”按钮。

将显示 “选择 EJB”浏览器。

8. 选择 “DiningGuide/Data”节点下的 Restaurant (EJB) bean,然后单击 “确定”。

请注意,“Home”和 “远程”接口字段是自动填充的。

9. 将 “类型”字段设置为 Entity。“增加 EJB 引用”属性编辑器看起来类似如下:

public Data.CustomerreviewDetail getCustomerreviewDetail() {return null;

}

第 3 章 生成 DiningGuide 应用程序的 EJB 层 99

Page 100: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

10. 选择 “Sun ONE 应用服务器”标签。

11. 在 “JNDI 名称”字段中键入 ejb/Restaurant,然后单击 “确定”。

这是在创建 Restaurant bean 时分配给它的缺省 JNDI 名称。

12. 同样地,增加对 Customerreview 实体 bean 的引用,以便属性具有以下值:

“EJB 引用”对话框看起来类似如下:

标签 属性 值

标准 引用名称 ejb/Customerreview

引用的 EJB 名称 Customerreview

类型 Entity

起始接口 Data.CustomerreviewHome

远程接口 Data.Customerreview

Sun ONE App Server JNDI 名称 ejb/Customerreview

100 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 101: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

13. 单击 “确定”关闭 “属性编辑器”窗口。

现在,您已经完成了教程应用程序的 EJB 层,可以测试它了。与测试实体 bean 时一样, IDE 的测试应用程序工具创建可以由浏览器中的客户端读取的 Web 层和 JSP 页。

测试会话 Bean使用 IDE 的测试应用程序工具测试 DiningGuideManager 会话 bean。这将测试整个 EJB 层,因为会话 bean 的方法提供对该层所有组件上的方法的访问。

为会话 Bean 创建测试客户端

从 DiningGuideManager bean 创建测试应用程序。然后,将这两个实体 bean 增加到 EJB 模块中。

为会话 bean 创建测试客户端:

1. 右键单击 “DiningGuideManager”逻辑节点,然后选择 “创建新的 EJB 测试应用程序”。

将显示 “EJB 测试应用程序”向导。

2. 接受所有缺省值,然后单击 “确定”。

此时,会暂时出现一个进度监视器,当进程完成时将关闭该监视器。屏幕上会显示另一个窗口,通知您创建的 Web 模块在 “项目”标签中也是可见的。该窗口也应该自动关闭。如果它没有关闭,请单击 “确定”关闭窗口。

3. 在资源管理器中查看结果测试对象。

IDE 已经创建了以下对象:

■ 一个 EJB 模块 (DiningGuideManager_EJBModule)■ 一个 Web 模块 (DiningGuideManager_WebModule)

第 3 章 生成 DiningGuide 应用程序的 EJB 层 101

Page 102: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

■ 一个 J2EE 应用程序 (DiningGuideManager_TestApp)EJB 模块和 Web 模块作为子节点出现在 Data 包下,还作为模块包含在 J2EE 应用程序中。此外,还单独安装了 Web 模块。

将实体 Bean 引用增加到 EJB 模块中EJB 模块仅包含 DiningGuideManager bean,因此您必须将两个实体 bean 增加到该模块中。

1. 右键单击 “DiningGuideManager_EJBModule”,然后选择 “增加 EJB”。

将显示 “将 EJB 增加到 EJB 模块”浏览器。

2. 展开 “DiningGuide”文件系统和 “Data”包。

3. 通过在按住 “Control”键的同时单击来同时选择 Restaurant 和 Customerreview 逻辑 bean。

4. 单击 “确定”。

IDE 将对两个实体 bean 的引用增加到 EJB 模块以及其在测试应用程序中的引用。DiningGuideManager_EJBModule 应该看起来类似如下:

5. 选择 “文件” → “全部保存”。

为 Sun Java System Application Server 插件提供数据库信息

您必须将数据库信息增加到 EJB 模块的 Sun Java System Application Server 属性中。已经使用第 77 页上的 “为 Sun Java System Application Server 插件提供数据库信息”中的实体 bean 测试客户端执行了此任务。

增加所需的信息:

1. 在资源管理器中展开 EJB 模块 (DiningGuideManager_EJBModule),然后选择该模块下的 “Restaurant”节点 (对 Restaurant bean 的引用)以显示其属性。

如果尚未显示 “属性”窗口,则选择 “查看” → “属性”。

102 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 103: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

2. 选择 “属性”窗口的 “Sun ONE AS”标签。

注意 – 如果在 “属性”窗口上没有 “Sun ONE AS”标签,则在 “服务器注册”中没有 Sun Java System Application Server 的实例。请参见第 30 页上的 “将 Sun Java System Application Server 设置为缺省服务器”以更正此问题。

3. 确认相应属性的以下三个值:

如果显示这些值,则继续执行步骤 5。

4. 如果未显示这些值,则重新映射 Restaurant bean,如下所述:

a. 将 “已映射的结构”属性设置为 Data/dgSchema。

b. 将 “已映射的主表”属性设置为 Restaurant。

c. 在 “已映射的字段”的值字段中单击,然后单击省略号按钮。

将显示 “映射到数据库”向导。

d. 单击 “下一步”查看 “选择表”页。

e. 从 “主表”字段的下拉列表中选择 RESTAURANT。如果 RESTAURANT 不在列表中,则使用 “浏览”按钮查找具有 dgSchema 结构的表。

f. 单击 “下一步”查看 “字段映射”页。

g. 如果字段没有映射,请单击 “自动映射”按钮。

将出现每个字段的映射值。

h. 单击 “完成”。

现在,值应该像步骤 3 中那样显示。

5. 对于 Customerreview 引用,重复步骤 1 至步骤 4 (如有必要)。

6. 选择 EJB 模块 (DiningGuideManager_EJBModule) 以显示其属性。

7. 选择 “属性”窗口的 “Sun ONE AS”标签。

属性 值

已映射的字段 已映射的 7 个容器管理字段

已映射的主表 RESTAURANT

已映射的结构 dgSchema

第 3 章 生成 DiningGuide 应用程序的 EJB 层 103

Page 104: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

8. 在 “CMP 资源”属性的值字段中单击,然后单击省略号按钮。

将显示 “CMP 资源”属性编辑器。

9. 在 “Jndi 名称”字段中键入 jdo/PointbasePM。这是您在第 32 页上的 “建立 JDBC 资源”中定义的 JDBC 持久性管理器的 JNDI 名称。

10. 在 “名称”和 “口令”字段中,键入数据库的用户名和口令。

对于 PointBase 示例数据库,用户名和口令都是 PBPUBLIC。编辑器看起来类似如下:

11. 单击 “确定”接受值并关闭属性编辑器。

您已经完成了将测试应用程序配置为使用您的数据库的操作,现在可以部署测试应用程序了。

12. 使用 “文件” → “全部保存”保存您所做的工作。

部署并执行测试应用程序

您必须首先卸下实体 bean 的两个测试应用程序 (如果仍然部署了它们),才能部署会话 bean 的测试应用程序。这是因为它们使用的对 Restaurant 和 Customerreview bean 的 JNDI 查找与 DiningGuideManager_TestApp 应用程序使用的相同。如果未能卸下这些应用程序,尽管将部署 DiningGuideManager 测试应用程序,但是将不装入它。

注意 – 在继续进行此部分之前,确保您的应用程序服务器实例正在运行,而且设置为缺省的应用程序服务器。

卸下实体 Bean 的测试应用程序

卸下以前部署的任何应用程序。

1. 单击资源管理器的 “运行环境”标签以显示 “运行环境”页。

104 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 105: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

2. 展开 “已安装服务器”下 Sun Java System Application Server 节点下的“servername(hostname:host-number)”实例节点。

例如, server1(localhost:80) 是缺省服务器实例。或者,您的实例可能具有其它标签,如 MyServer(localhost:82)。

3. 确保应用程序服务器正在运行。

a. 右键单击应用程序服务器节点,然后选择 “状态”。

将显示 “应用程序服务器实例状态”对话框。如果 “状态”为 “正在运行”,请继续执行步骤 4。

b. 单击 “启动服务器”按钮。

将出现一个显示进度消息的命令窗口。如果此窗口显示字符串“Application onReady complete”,则说明已启动服务器。

c. 单击实例状态对话框上的 “关闭”。

虽然可以在必要时将命令窗口 小化,但是不要关闭它。

4. 展开 “部署的应用程序”节点。

将显示两个实体 bean 测试应用程序。

如果未显示任何内容,请右键单击 “部署的应用程序”节点,然后选择 “刷新列表”。

部署的应用程序

第 3 章 生成 DiningGuide 应用程序的 EJB 层 105

Page 106: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

5. 右键单击其中的一个应用程序,然后选择 “卸下”。

该应用程序即被卸下。

6. 重复步骤 5 以卸下其它应用程序。

部署 DiningGuideManager 测试应用程序

注意 – 在部署测试应用程序或任何其它访问数据库的 J2EE 应用程序之前,确保 PointBase 服务器正在运行。

部署 DiningGuideManager 测试应用程序:

1. 单击资源管理器的 “文件系统”标签以显示 “文件系统”页。

2. 右键单击 “DiningGuideManager_TestApp” J2EE 应用程序节点,然后从上下文菜单中选择 “执行”。

“进度监视器”窗口将显示部署过程的进度。输出窗口上服务器实例的日志文件标签将显示进度消息。如果看到成功消息,则说明应用程序已成功部署。

IDE 启动缺省 Web 浏览器,并显示测试应用程序的主 URL。如果您的应用程序服务器是在本地安装的,则主 URL 类似于 http://localhost/DiningGuideManager_TestApp/;如果应用程序服务器是远程安装的,则主 URL 将是不同的。

使用测试客户端测试会话 Bean在测试客户端的 Web 页上,通过执行 create 方法创建 DiningGuideManager 会话 bean 的实例;然后,测试该实例上的 business 方法 (getRating)。

测试 DiningGuideManager bean:

1. 通过调用 DiningGuideManagerHome 的 create 方法,创建 DiningGuideManager 会话 bean 的实例。

Data.DiningGuideManager[x] 实例将出现在实例列表中。现在,您可以测试 bean 的 getter 方法。

2. 选择新的 Data.DiningGuideManager[x] 实例。

这将使 getAllRestaurants 和 getCustomerreviewsByRestaurant 方法变为可用。

3. 在 createCustomerreview 的各字段中,键入所需的任何数据。

例如:

106 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 107: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

4. 单击 createCustomerreview 方法旁边的 “Invoke”按钮。

已部署的测试应用程序将您创建的记录增加到数据库中。新的参数值在 “存储的对象”部分 (右上部)中列出,结果显示在 “结果”区域中:

5. 单击 getAllRestaurants 方法上的 “Invoke”按钮。

如果在数据库中创建了 Joe's House of Fish (在第 80 页上的 “使用测试客户端测试 Restaurant Bean”中),则大小为 3 的向量将出现在已创建的对象列表 (右上部)中,方法调用的结果应该看起来如图所示 (实际数字可能是不同的)。如果没有创建此记录,则您的结果可能是不同的。

6. 单击 getCustomerreviewDetail 方法上的 “Invoke”按钮。

结果显示在 “结果”部分中。

第 3 章 生成 DiningGuide 应用程序的 EJB 层 107

Page 108: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

7. 在 getCustomerreviewsByRestaurant 方法的字段中键入 Joe’s House of Fish,然后单击 “Invoke”按钮。

应该不返回 CustomerreviewDetail 记录,因为数据库中没有顾客意见。现在,请尝试 French Lemon 记录。

8. 在同一字段中键入 French Lemon,然后调用方法。

应该返回两条 CustomerreviewDetail 记录:

9. 单击 getRestaurantDetail 方法上的 “Invoke”按钮。

结果将显示在 “结果”部分中。

10. 在完成测试时,通过将 Web 浏览器指向另一个 URL 或者通过退出浏览器 (或不执行任何操作)停止测试客户端。

注意 – 您不必停止应用程序服务器的进程 (它在执行窗口中列出)。每当重新部署时,服务器都会卸下应用程序,然后重新部署。在退出 IDE 时,将显示一个对话框,提示您终止应用程序服务器的实例进程。但是,您可以随时手动终止它,方法是右键单击执行窗口中的 “server1(hostname:host-port)”节点并选择 “终止进程”。

检查对数据库的增加

要验证 DiningGuideManager_TestApp 应用程序是否已将数据插入数据库,请重复在第 83 页上的 “检查对数据库的增加”和第 88 页上的 “检查对数据库的增加”中描述的过程。

现在,可以创建 Web 服务了。

108 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 109: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

有关创建客户端的注释恭喜!您已经成功地完成了 DiningGuide 应用程序的 EJB 层。您可以继续学习第 4 章以使用 Java Studio Enterprise IDE 的 Web 服务模块为应用程序创建 Web 服务,然后继续学习第 5 章为您的客户端安装提供的 Swing 类。

但是,您可能希望创建自己的 Web 服务和客户端,在这种情况下,Java Studio Enterprise 测试应用程序可以提供一些准则。

访问会话 bean (如 DiningGuideManager bean)的 Web 服务必须包括 servlet 和 JSP 页(这些页具有用于获得 EJB 层中实体 bean 的 Home 接口和 Home 对象的 lookup 方法)。测试应用程序工具创建的 Web 模块提供所需代码的示例。

Lookup 方法示例可在 Web 模块下的 EjbInvoker 类中找到。具体说来,在 WEB-INF/Classes/com/sun/forte4j/j2ee/ejbtest/webtest 目录下查找此类。

例如,以下方法是 lookup 代码的良好示例:

■ EjbInvoker.getHomeObject■ EjbInvoker.getHomeInterface■ EjbInvoker.resolveEjb

Lookup 方法示例

第 3 章 生成 DiningGuide 应用程序的 EJB 层 109

Page 110: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

110 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 111: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

第 4 章

创建 DiningGuide 应用程序的 Web 服务

本章描述如何使用 Java Studio Enterprise IDE 创建 DiningGuide 应用程序的 Web 服务。本章包括以下主题:

■ “教程 Web 服务的概述”(即接下来的主题)■ 第 113 页上的 “创建教程的 Web 服务”■ 第 117 页上的 “测试 Web 服务”■ 第 129 页上的 “使您的 Web 服务可供其他开发人员使用”

有关 Java Studio Enterprise Web 服务功能的完整讨论,请参见 《Sun Java Studio Enterprise 6 编程系列》中的 《构建 Web 服务》。此书可以从 Java Studio Enterprise 门户的 Documentation (文档)页下载,该页的网址是 http://developers.sun.com/prodtech/javatools/jsenterprise/

reference/docs/index.html。有关特定功能的信息,请参见 Java Studio Enterprise 联机帮助。

教程 Web 服务的概述在本章中,您将创建 DiningGuide 应用程序的 Web 服务。作为此过程的一部分,您将显式创建许多组件并生成一些其它组件。

您将显式创建:

■ 一个逻辑 Web 服务,即 DGWebService Web 服务

■ 一个 J2EE 应用程序,它既引用会话 bean 的 EJB 模块也引用 Web 服务

您将生成:

■ 运行环境类,它们是实现 Web 服务的 EJB 组件■ 一个测试客户端■ 测试客户端文件

111

Page 112: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

Web 服务

有关 Web 服务以及如何创建它们和为它们编程的更完整信息,请参见 《构建 Web 服务》。有关特定的 Web 服务主题和过程,另请参见 Java Studio Enterprise 联机帮助。

在此教程中,您可以通过在 Web 服务中创建对希望客户端能够访问的方法的引用,从而开发 Web 服务的功能。

运行环境类

在创建 Web 服务及其方法引用之后,将生成其运行环境类。您不会直接对运行环境类进行处理,但是您将看到它们在包含 Web 服务的包中生成。

客户端文件

在创建客户端并生成其文件时,会创建支持客户端页。您将使用这些客户端页测试 Web 服务。您也可以将它们用作开发功能完整的被引用的方法的起点或指南。这些客户端文件包括每个引用方法的 JSP 页、显示 Web 服务错误的 JSP 页以及组织该方法 JSP 页以便在 Web 浏览器中显示的 HTML 欢迎页。

欢迎页包含一个 HTML 窗体,该窗体具有为被引用的方法而生成的每个 JSP 页。如果方法需要参数,则 HTML 窗体包含相应的输入字段。如有必要,通过为每个参数输入数据测试方法,并按方法的 “调用”按钮。然后,将发生以下操作:

1. JSP 页将请求传递到 SOAP 客户端文件。

2. SOAP 客户端文件将请求传递到应用程序服务器上的 JAX-RPC 运行环境系统。

SOAP 请求是一个 XML 包装器,包含对 Web 服务的方法调用和以序列化形式的输入数据。

3. 应用程序服务器上的 JAX-RPC 运行环境系统将 SOAP 请求变换为对 DiningGuide Web 服务引用的相应方法的方法调用。

4. 将方法调用传递到 EJB 层中相应的 business 方法。

5. 处理后的响应沿传递链传回 SOAP 客户端文件。

6. SOAP 客户端文件将响应传递到 JSP 页,该页在 Web 页上显示响应。

112 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 113: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

创建教程的 Web 服务创建教程的 Web 服务需要执行以下两个步骤:

1. 为应用程序创建逻辑 Web 服务。

使用 IDE 的 “Web 服务”向导创建逻辑 Web 服务和指定要引用的方法。这些方法是为 DiningGuideManager 会话 bean 创建的五个 business 方法。

2. 生成 Web 服务运行环境类。

此任务生成用于测试和实现 Web 服务的支持 EJB 组件。

创建逻辑 Web 服务

使用 “新建 Web 服务”向导创建逻辑 Web 服务。该向导允许您选择体系结构:多层或以 Web 为中心。 DiningGuide 应用程序的 Web 服务调用 EJB 层组件上的方法,因此选择多层体系结构。

该向导还提示您选择 Web 服务将调用的方法,以便它可以生成对这些方法的引用。选择 EJB 层的会话 bean 的五个 business 方法。

创建教程的逻辑 Web 服务:

1. 在资源管理器中,右键单击已安装的 DiningGuide 文件系统,然后选择“新建” → “Java 包”。

将显示 “新建包”对话框。

2. 键入包的名称 WebService,然后单击 “完成”。

在 DiningGuide 目录下,将出现新建的 WebService 包。

3. 右键单击 WebService 包,然后选择 “新建” → “所有模板”。

将显示 “新建向导”,该向导显示 “选择模板”页。

4. 展开 “Web 服务”节点,选择 “Web 服务”,然后单击 “下一步”。

“新建向导”显示 “Web 服务”页。

5. 在 “名称”字段中键入 DGWebService,选择以下选项:

选项种类 要选择的选项

创建自 Java 方法

体系结构 多层

第 4 章 创建 DiningGuide 应用程序的 Web 服务 113

Page 114: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

6. 单击 “下一步”。

将显示 “新建向导”的 “选择方法”页。

7. 展开 “Data”、“DiningGuideManager(EJB)”和 “Business 方法”节点。

8. 通过在按住 “Shift”键并同时单击来选择 DiningGuideManager 的所有 business 方法:

“方法”页看起来类似如下:

9. 单击 “完成”。

新建的 DGWebService Web 服务 (带有蓝色球形的图标 )出现在资源管理器中的 WebService 包下。如果展开此节点,则资源管理器看起来类似如下:

114 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 115: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

生成 Web 服务的运行环境类

在将 Web 服务汇编为 J2EE 应用程序并部署它以供测试之前,您必须生成 Web 服务的运行环境类。当体系结构为多层时, IDE 生成许多类以实现 Web 服务,其中的三个类用于生成的 EJB 组件。

注意 – 确保您的管理服务器正在运行,而且将您的应用程序服务器设置为缺省服务器。

生成 Web 服务的运行环境类:

1. 右键单击 “DGWebService”节点,然后选择 “生成 Web 服务文件”。

在操作完成时,“已完成”字样将出现在 IDE 的输出窗口中。在资源管理器中将出现运行环境类 (它们是用于实现 SOAP RPC Web 服务的 EJB 组件):

新建 Web 服务

包括的方法

第 4 章 创建 DiningGuide 应用程序的 Web 服务 115

Page 116: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

2. 显示 “DGWebService”节点的属性。

可以在资源管理器下的 “属性”窗口中查看它们,也可以右键单击该节点,然后从上下文菜单中选择 “属性”查看它们。

3. 验证 SOAP RPC URL 属性的值是否反映您的应用程序服务器的主机名和端口号。

例如,对于主机名为 “tech5”、端口号为 “4855”的应用程序服务器, URL 应该如下所示:

http://tech5:4855/DGWebService/DGWebService

Web 服务组件

116 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 117: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

测试 Web 服务测试 Web 服务需要执行以下任务:

1. 创建包括以下对象的测试客户端:

■ 测试客户端■ 引用 EJB 模块和 Web 服务的 J2EE 应用程序

2. 部署测试应用程序。

3. 使用测试应用程序来测试 Web 服务。

Web 服务测试应用程序为 Web 服务中的每个 XML 操作生成一个 JSP 页以及组织这些 JSP 页以便在浏览器中查看的欢迎页。在执行测试客户端时,将从欢迎页执行 XML 操作。

创建测试客户端和测试应用程序

要测试 Web 服务,请创建测试客户端和 J2EE 应用程序。将 EJB 模块和 Web 服务模块增加到 J2EE 应用程序中。

提示 – 在创建测试客户端时,将其设置为 Web 服务的缺省测试客户端。然后,在部署 J2EE 应用程序时,也部署测试客户端。

为 Web 服务创建和部署客户端应用程序:

1. 在资源管理器中,右键单击 “DGWebService”节点 ( ),然后选择 “创建新的 Web 服务测试客户端”。

将显示 “创建新的 Web 服务测试客户端”对话框。

缺省情况下,“将其设为 Web 服务的缺省测试客户端”选项处于选中状态。

第 4 章 创建 DiningGuide 应用程序的 Web 服务 117

Page 118: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

2. 接受所有缺省值,然后单击 “确定”。

一个新的客户端节点出现在资源管理器 ( ) 中。现在,为 Web 服务创建新的 J2EE 应用程序。

3. 右键单击 “WebService”包,然后选择 “新建” → “所有模板”。

4. 在 “新建”向导中,展开 “J2EE”节点,选择 “应用程序”,然后单击 “下一步”。

5. 在 “名称”字段中键入 DGApp,然后单击 “完成”。

新建的 J2EE 应用程序节点 ( ) 出现在 WebService 软件包下。

将 Web 服务增加到 J2EE 应用程序中

现在,将 Web 服务增加到应用程序中:

1. 右键单击 “DGApp”节点,然后选择 “增加模块”。

将出现 “将模块增加到应用程序”对话框。

2. 在该对话框中,展开 “DiningGuide”文件系统以及 “Data”包和 “WebService”包。

3. 通过在按住 “Control”键并同时单击来选择 “DiningGuideManager_EJBModule”和“DGWebService”节点。

对话框看起来类似如下:

118 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 119: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

4. 单击 “确定”以接受选择并关闭对话框。

5. 在资源管理器中,展开 DGApp J2EE 应用程序。

DGWebService 的 WAR 和 EJB JAR 文件以及 DiningGuideManager_EJBModule 都已增加到应用程序中:

部署测试应用程序

您必须首先卸下已部署的任何测试应用程序,才能部署会话 bean 的测试应用程序 (其原因与第 104 页上的 “部署并执行测试应用程序”中给出的相同)。(因为它们使用的对 Restaurant 和 Customerreview bean 的 JNDI 查找与 Web 服务测试应用程序将使用的相同。)

有关卸下应用程序的过程,请参见第 104 页上的 “卸下实体 Bean 的测试应用程序”。

第 4 章 创建 DiningGuide 应用程序的 Web 服务 119

Page 120: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

注意 – 确保在部署测试应用程序或访问数据库的任何其它 J2EE 应用程序之前 PointBase 服务器正在运行。此外,请确保您的 Sun Java System Application Server 实例正在运行并且该应用程序服务器是 IDE 的缺省应用程序服务器。要获得信息,请参见第 30 页上的 “将 Sun Java System Application Server 设置为缺省服务器”。

部署 DGApp 应用程序:

1. 卸下任何已部署的 DiningGuide 测试应用程序。

如有必要,对于此过程请参考第 104 页上的 “卸下实体 Bean 的测试应用程序”。确保您还重新启动了应用程序服务器。

2. 在资源管理器中,右键单击 “DGApp”节点 ( ),然后选择 “部署”。

进度监视器窗口显示部署过程正在进行。

3. 验证是否已部署应用程序。

“进度监视器”窗口显示部署过程的进度。输出窗口上服务器实例的 “日志文件”标签显示进度消息。在看到成功消息时,说明已经成功部署了应用程序。

资源管理器的 “执行视图”窗口显示 servername(server-hostname:server-port-number) 节点。

4. 展开 “WebService”包下的 “DGWebServiceClient$Documents”节点。

已经创建了以下支持项:

■ 每个方法的使用标记库设置显示格式的 JSP 页■ 每个方法的用于显示返回的 SOAP 消息的 JSP 页■ 组成欢迎页的一组 JSP 页。■ JSP 错误页

要获得有关这些页的更多信息,请参见 《构建 Web 服务》。

资源管理器看起来类似如下:

120 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 121: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

在 “DGWebServiceClient”节点下的 “生成的文档”节点下也引用这些文件。

使用测试应用程序测试 Web 服务

有关如何在客户端和 Web 服务之间传递 SOAP 请求和响应的详细说明,请参见《构建 Web 服务》(可以从 Java Studio Enterprise 门户的文档页下载,该页的网址是 http://developers.sun.com/prodtech/javatools/jsenterprise/

reference/docs/index.html)。

注意 – 确保管理服务器和 PointBase 服务器正在运行。确保您的应用程序服务器是缺省的应用程序服务器。

生成的客户端页

第 4 章 创建 DiningGuide 应用程序的 Web 服务 121

Page 122: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

测试 Web 服务:

1. 在资源管理器中,右键单击 “DGWebServiceClient”节点 ( ),然后选择 “部署”。

部署 DGWebServiceClient。在资源管理器的 “运行环境”窗格中您的应用程序服务器实例的 “部署的 Web 模块”节点下,可以看到此节点。

2. 右键单击同一节点,然后选择 “执行”。

IDE 将部署测试客户端,启动缺省的 Web 浏览器,并显示客户端生成的欢迎页 (DGWebServiceClient_SOAP.html):

通过此页,您可以测试操作是否像期望的那样工作。

3. 通过在文本字段中键入 French Lemon 并单击 “调用”按钮,测试 getCustomerreviewsByRestaurant 方法。

122 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 123: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

将创建一个 SOAP 消息并发送到应用程序服务器。DGApp Web 服务将 SOAP 消息转换为 DiningGuideManager.getCustomerreviewsByRestaurant 方法的方法调用。此方法将一个集合返回给生成的 JSP 页 getCustomerreviewsByRestaurant_TAGLIB.jsp,该页在带格式的表中显示返回的数据,如图所示。

该数据包括为 French Lemon 餐馆输入的所有记录。通过启动 Pointbase 控制台并运行以下 SQL 语句验证此数据:

select * from CustomerReview;

结果显示您输入了哪些 CustomerReview 记录。

第 4 章 创建 DiningGuide 应用程序的 Web 服务 123

Page 124: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

4. 要查看 SOAP 消息,请单击 “查看 SOAP 请求 / 响应”链接。

这将返回的数据显示为 XML 包装的 SOAP 消息。

5. 使用浏览器上的 “后退”按钮返回到欢迎页。

6. 通过在 “餐馆名称”字段中键入 French Lemon并在其它两个字段中键入任何所需内容,测试 createCustomerreview 操作。

例如:

124 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 125: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

7. 单击 “调用”按钮。

此方法采用复合 Java 对象作为输入参数。生成的 JSP 页 createCustomerreview_SOAP.jsp 将提示进行三项输入。然后,将这些输入转换为 Customerreview 对象并作为 SOAP 消息进行传递。将此消息发送到应用程序服务器,在应用程序服务器中将它转换回 Java 方法调用并发送到 DiningGuideManagerEJB 组件。结果显示在浏览器中:

第 4 章 创建 DiningGuide 应用程序的 Web 服务 125

Page 126: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

8. 单击 “查看 SOAP 请求 / 响应”链接。

SOAP 请求和响应看起来类似如下。

126 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 127: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

9. 使用浏览器上的 “后退”按钮返回到欢迎页。

10. 测试 getAllRestaurants 操作,方法是单击其在欢迎页上的 “调用”按钮。

此方法不需要输入参数。它返回餐馆数据的集合 (getAllRestaurants_SOAP.jsp 页将此集合显示为 XML):

第 4 章 创建 DiningGuide 应用程序的 Web 服务 127

Page 128: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

请注意,测试 Restaurant 实体 bean (请参见第 80 页上的 “使用测试客户端测试 Restaurant Bean”)时输入的餐馆记录是该页上的 后一条记录。

您已经成功地为 DiningGuide 教程创建了 Web 服务。在第 5 章中,您将使用提供的 Swing 客户端运行 DiningGuide 应用程序。

128 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 129: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

使您的 Web 服务可供其他开发人员使用您已经学习了测试 Web 服务的便利方法 (如果您是 Web 服务开发人员)。但是,您组织中的其它开发组 (尤其是客户端开发人员)也需要根据您的 Web 服务测试其工作。您可以轻松地为他们提供您的 Web 服务的 WSDL 文件。通过此文件,他们可以生成客户端文件 (通过该客户端文件,可以生成应用程序的客户端)。然后,如果您为他们提供已部署的 Web 服务(并确保 Web 服务正在运行),则他们可根据您的 Web 服务测试客户端。

要使 Web 服务可供其他开发人员使用,需要执行以下任务:

1. Web 服务开发人员:

■ 从 Web 服务生成 WSDL 文件■ 使 WSDL 文件可供目标用户使用■ 为目标用户提供已部署的 Web 服务的 URL

2. 目标用户:

■ 将 WSDL 文件增加到资源管理器中的已安装文件系统■ 从该 WSDL 创建 Web 服务客户端■ 生成客户端文件■ 根据客户端文件生成客户端■ 将 Web 服务 URL 指定为客户端的 SOAP RPC URL 属性

生成客户端文件就会生成开发应用程序的实际客户端所需的 JSP 页。

生成 WSDL 文件

共享对应用程序的 Web 服务的访问的第一步是生成 Web 服务的 WSDL 文件。此步骤由 Web 服务的开发人员执行。

生成 Web 服务的 WSDL 文件:

1. 在资源管理器中,右键单击 “DGWebService”节点 ( ),然后选择 “生成 WSDL”。

即会在 “WebService”包下创建一个名为 DGWebService 的 WSDL 文件 (带有绿色球形的节点 )。

您可以在操作系统的文件系统上的 DiningGuide/WebService 目录中找到此文件(其名称为 DGWebService.wsdl)。

2. 使此文件可供其它开发组使用。

您可以将此文件附加到电子邮件或将它张贴在 Web 站点上。

第 4 章 创建 DiningGuide 应用程序的 Web 服务 129

Page 130: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

从 WSDL 文件生成客户端文件

共享对应用程序的 Web 服务的访问的第二步是从 WSDL 文件生成所有 Web 服务支持文件。此步骤是由客户端的开发人员执行的。

从 WSDL 文件生成 Web 服务文件和客户端文件:

1. 在操作系统的文件系统上,创建一个目录并将 DGWebService.wsdl 文件放在该目录中。

例如,创建 c:\wsdlHolder 目录并将文件粘贴在该目录中。

2. 在 Java Studio Enterprise 资源管理器中,安装此目录。

3. 右键单击新目录,然后选择 “新建” → “Java 包”。

4. 在 “名称”字段中键入 MyClientPackage,然后单击 “完成”。

MyClientPackage 即会显示在已安装的目录中。

5. 在资源管理器中,右键单击 “MyClientPackage”,然后选择 “新建” → “所有模板”。

6. 在 “新建”向导中,展开 “Web 服务”节点,选择 “Web 服务客户端”,然后单击“下一步”。

将显示 “Web 服务客户端”页。

7. 在 “名称”字段中键入 NewClient。

8. 确保包是 MyClientPackage 包。

9. 对于 “源”,选择 “本地 WSDL 文件”选项,然后单击 “下一步”。

将显示 “新建”向导的 “选择本地 WSDL 文件”页。

10. 展开在步骤 1 中创建的目录,选择 DGWebService WSDL 文件,然后单击 “完成”。

一个新的客户端节点 ( ) 出现在资源管理器中。

11. 右键单击 “NewClient”客户端节点,然后选择 “生成客户端文件”。

在资源管理器中将生成一个 “生成的文档”节点。展开 “生成的文档”节点将显示客户端所需的 JSP 页和欢迎页,如图所示:

130 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 131: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

现在,您可以使用客户端测试 Web 服务了(如第 121 页上的“使用测试应用程序测试 Web 服务” 中所述)。

在完成您的应用程序时,您可能要将 Web 服务发布到 UDDI 注册,以使其可供您的 接近语言环境之外的开发人员使用。 Java Studio Enterprise 提供单用户内部 UDDI 注册以测试此过程,StockApp 示例(可以从 Java Studio Enterprise 门户的“教程和代码库”)页下载,该页的网址是:

http://developers.sun.com/devtools/javatools/jsenterprise/

learning/tutorials/index.html。说明如何使用此功能。有关发布到外部 UDDI 注册的信息,请参见《构建 Web 服务》。

生成的支持文件

第 4 章 创建 DiningGuide 应用程序的 Web 服务 131

Page 132: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

132 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 133: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

第 5 章

为教程应用程序创建客户端

本章描述如何使用提供的 Swing 客户端 (它与在第 4 章中创建的 Web 服务进行通信)运行 DiningGuide 应用程序。

提供的客户端包含两个 Swing 类:RestaurantTable 和 CustomerReviewTable。将这两个类增加到 WebService 包中,然后执行 RestaurantTable 类以运行应用程序。

此客户端非常简单,提供它的目的只是为了说明如何访问为 Web 服务生成的客户端的方法。

本章包括以下主题:

■ “使用提供的代码创建客户端”(即接下来的主题)■ 在第 134 页上的 “运行教程应用程序”■ 在第 137 页上的 “检查客户端代码”

使用提供的代码创建客户端客户端类是在 DiningGuide.zip 文件 (可以从 开发人员资源门户下载)中以 Java 类文件的形式提供的。

将所提供的两个 Java 客户端类复制到 DiningGuide 应用程序中:

1. 在 IDE 的 DiningGuide 文件夹中创建 Client 包。

a. 右键单击 DiningGuide 文件夹,然后选择 “新建” → “Java 包”。

b. 在 “新建”向导的 “名称”字段中键入 Client,然后单击 “完成”。

2. 从 开发人员资源门户解压缩 DiningGuide.zip 文件。

a. 从 开发人员资源门户下载 DiningGuide.zip 文件。

http://developers.sun.com/devtools/javatools/jsenterprise/learning/tutorials/index.html

133

Page 134: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

b. 将文件解压缩到本地目录,例如 /MyZipFiles 目录。

3. 使用文件系统命令将这两个客户端文件从 DiningGuide 源文件复制到 Client 包,如下所述:

■ 在 Microsoft Windows 系统上,复制这两个文件并将其粘贴到新建的 Client 文件夹中。

■ 在 Solaris 或 Linux 环境中,键入类似如下的命令:

4. 在 IDE 的资源管理器中,展开 DiningGuide/Client 包并验证它是否包含这两个新类。

注意 – 当您在 IDE 的窗体编辑器中创建 Swing 客户端时, IDE 生成一个 .form 文件和一个 .java 文件。通过 .form 文件,您可以在窗体编辑器中编辑 GUI 组件。但是,由于尚未为 RestaurantTable 和 CustomerReviewTable 类提供 .form 文件,因此您将无法在窗体编辑器中修改 GUI 组件。

运行教程应用程序通过执行 RestaurantTable 类运行 DiningGuide 应用程序,如下所述:

1. 重新启动 IDE。

2. 通过选择“工具” → “PointBase 网络服务器” → “启动服务器”,启动 PointBase 服务器。

3. 如果需要,启动 Sun Java System Application Server。

a. 在 “资源管理器”的 “运行环境”窗格中,展开 “已安装服务器”下的节点,直到看见您的服务器实例节点。

b. 右键单击服务器实例节点,然后选择 “状态”。

c. 如果状态显示为 “停止”,请单击 “启动服务器”按钮。

4. 重新部署 DGApp 应用程序。

DGApp 应用程序位于 “资源管理器”的 “文件系统”窗格下,在 DiningGuide/WebService 的下方。

$ cp /MyZipFiles/DiningGuide/Client/*.java /DiningGuide/Client

$ cp /MyZipFiles/DiningGuide/Client/*.java /DiningGuide/Client

134 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 135: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

5. 展开客户机节点,右键单击 “RestaurantTable”节点,然后选择 “执行”。

IDE 编译两个客户机文件,然后将切换到 “运行环境”模式。“Restaurant”节点出现在执行窗口中。此后将显示 “RestaurantTable”窗口,如下所示:

6. 选择表中的任一餐馆并单击 “View Customer Comments”按钮。

例如,选择 French Lemon 餐馆。将显示 CustomerReviewTable 窗口。如果数据库中存在此餐馆的任何意见,则显示它们 (如图所示)。否则,将显示一个空表。

7. 在 “Customer Name”字段和 “Review”字段中键入某些文本,然后单击 “Submit Customer Review”按钮。

例如:

第 5 章 为教程应用程序创建客户端 135

Page 136: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

记录意见输入到数据库中,并显示在同一 “CustomerReviewTable”窗口中,如图所示:

8. 试用这些功能,如在第 39 页上的 “用户的教程应用程序视图”中所述。

9. 通过关闭任一窗口退出应用程序。

在退出应用程序之后,执行窗口显示 Sun Java System Application Server 进程仍在运行。您不必停止应用程序服务器。如果重新部署教程的任一 J2EE 应用程序或重新运行测试客户端 (但不是此 Swing 客户端),则会自动地重新启动服务器。

在退出 IDE 时,将显示一个对话框,提示您终止仍在运行的任何进程 (包括应用程序服务器或 Web 服务器)。选择每个正在运行的进程,然后单击 “结束任务”按钮。您也可以在 IDE 运行的同时随时手动终止任何进程,方法是在执行窗口中右键单击进程的节点并选择 “终止进程”。

136 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 137: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

检查客户端代码已经在 DiningGuide 应用程序中安装的两个客户端类由在窗体编辑器中创建的 Swing 组件和操作以及在源编辑器中创建的几个方法组成。增加到源编辑器中的方法包括实例化客户端以便其方法变为可用于客户端的关键任务。

为帮助您了解 Swing 客户端是如何与 Web 服务交互的,接下来的几节讲述客户端的主要操作,即:

■ 在第 137 页上的 “显示餐馆数据”■ 在第 139 页上的 “显示所选餐馆的顾客意见数据”■ 在第 141 页上的 “创建新的顾客意见记录”

显示餐馆数据

显示餐馆数据是由 RestaurantTable 类的方法 (这些方法实例化客户端并调用其 getAllRestaurants 方法)实现的,如下所述:

1. RestaurantTable.getAllRestaurants 方法实例化客户端,调用客户端的 getAllRestaurants 方法以获取餐馆数据,并以向量形式返回获取的餐馆数据。

private Vector getAllRestaurants() {Vector restList = new Vector();try {

WebService.DGWebServiceClientGenClient.DGWebService service1 = new

WebService.DGWebServiceClientGenClient.DGWebService_Impl();

WebService.DGWebServiceClientGenClient.DGWebServiceServantInterface port =service1.getDGWebServiceServantInterfacePort();

restList = (java.util.Vector)port.getAllRestaurants();}catch (Exception ex) {

System.err.println("Caught an exception." );ex.printStackTrace();

}return restList;

}

第 5 章 为教程应用程序创建客户端 137

Page 138: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

2. RestaurantTable 构造函数将返回的餐馆数据放在 restaurantList 变量中并调用 RestaurantTable.putDataToTable。

3. RestaurantTable.putDataToTable 方法迭代通过向量并填充表。

4. RestaurantTable.Main 方法将表显示为 Swing jTable 组件。

public RestaurantTable() {initComponents();restaurantList=getAllRestaurants();putDataToTable();

}

private void putDataToTable() {Iterator j=restaurantList.iterator();while (j.hasNext()) {

RestaurantDetail ci = (RestaurantDetail)j.next();String strRating = null;String[] str ={ci.getRestaurantname(),

ci.getCuisine(), ci.getNeighborhood(), ci.getAddress(), ci.getPhone(), ci.getDescription(), strRating.valueOf(ci.getRating()),

};TableModel.addRow(str);

}}

public static void main(String args[]) {new RestaurantTable().show();

}

138 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 139: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

显示所选餐馆的顾客意见数据

当 RestaurantTable 的按钮组件的操作实例化 CustomerReviewTable 时,将开始显示顾客意见数据。 CustomerReviewTable 的方法通过客户端的方法获取顾客意见数据并填充表。然后, RestaurantTable 的按钮组件的操作显示顾客意见数据,如下所述:

1. 当按一下 RestaurantTable 的按钮检索顾客意见数据时,RestaurantTable.jButton1ActionPerformed 方法实例化新的 CustomerReviewTable 对象,调用其 putDataToTable 方法,并将所选列的数据传递给它。

2. CustomerReviewTable.putDataToTable 方法调用 CustomerReviewTable.getCustomerReviewByName 方法,将所选餐馆名称传递给它,将返回的向量赋予 customerList 变量。

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt){

int r =jTable1.getSelectedRow();int c = jTable1.getSelectedColumnCount();String i =(String)TableModel.getValueAt(r,0);CustomerReviewTable crt = new CustomerReviewTable();crt.putDataToTable(i);crt.show();System.out.println(i);

}

public void putDataToTable(java.lang.String restaurantname) {RestaurantName = restaurantname;java.util.Vector customerList =

getCustomerReviewByName(restaurantname);Iterator j=customerList.iterator();while (j.hasNext()) {

CustomerreviewDetail ci = (CustomerreviewDetail)j.next();

String[] str = {ci.getCustomername(),ci.getReview()};TableModel.addRow(str);

}}

第 5 章 为教程应用程序创建客户端 139

Page 140: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

3. CustomerReviewTable.getCustomerReviewByName 方法实例化客户端 (如有必要)并调用其 getCustomerreviewsByRestaurant 方法,将所选餐馆的名称传递给它。

4. 将意见数据向上传递给 CustomerReviewTable.putDataToTable 方法,该方法迭代通过意见数据并填充表。

private Vector getCustomerReviewByName(java.lang.String restaurantname) {Vector custList = new Vector();try {

WebService.DGWebServiceClientGenClient.DGWebService service2 = new

WebService.DGWebServiceClientGenClient.DGWebService_Impl();

WebService.DGWebServiceClientGenClient.DGWebServiceServantInterface port = service2.getDGWebServiceServantInterfacePort();

custList =(java.util.Vector)port.getCustomerreviewsByRestaurant(restaurantname);}

catch (Exception ex) {System.err.println("Caught an exception." );ex.printStackTrace();

}return custList;

}

public void putDataToTable(java.lang.String restaurantname) {RestaurantName = restaurantname;java.util.Vector customerList =

getCustomerReviewByName(restaurantname);Iterator j=customerList.iterator();while (j.hasNext()) {

CustomerreviewDetail ci = (CustomerreviewDetail)j.next();

String[] str = {ci.getCustomername(),ci.getReview()};TableModel.addRow(str);

}}

140 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 141: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

5. 然后, RestaurantTable.jButton1ActionPerformed 方法显示数据。

创建新的顾客意见记录

当用户在 “顾客意见”窗口上键入名称和意见,然后单击 “Submit Customer Review”按钮时, CustomerReviewTable 的 jButton1ActionPerformed 方法将通过客户端的方法在数据库中创建意见记录,然后刷新 “顾客意见”窗口,如下所述:

1. 当按一下 CustomerReviewTable 的按钮提交顾客意见记录时,CustomerReviewTable.jButton1ActionPerformed 方法实例化新客户端 (如有必要)并调用其 createCustomerreview 方法,将餐馆名称、顾客名称和意见数据传递给它。

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt){

int r =jTable1.getSelectedRow();int c = jTable1.getSelectedColumnCount();String i =(String)TableModel.getValueAt(r,0);CustomerReviewTable crt = new CustomerReviewTable();crt.putDataToTable(i);crt.show();System.out.println(i);

}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {try {

WebService.DGWebServiceClientGenClient.DGWebService service1 = new

WebService.DGWebServiceClientGenClient.DGWebService_Impl();

WebService.DGWebServiceClientGenClient.DGWebServiceServantInterface port = service1.getDGWebServiceServantInterfacePort();

port.createCustomerreview(RestaurantName,customerNameField.getText(),reviewField.getText());

}catch (Exception ex) {

System.err.println("Caught an exception." );ex.printStackTrace();

}refreshView();

}

第 5 章 为教程应用程序创建客户端 141

Page 142: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

2. 此同一方法 (jButton1ActionPerformed) 调用 CustomerReviewTable.refreshView 方法。

3. CustomerReviewTable.refreshView 方法调用 putDataToTable 方法,将餐馆名称传递给它。

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {try {

WebService.DGWebServiceClientGenClient.DGWebService service1 = new

WebService.DGWebServiceClientGenClient.DGWebService_Impl();

WebService.DGWebServiceClientGenClient.DGWebServiceServantInterface port = service1.getDGWebServiceServantInterfacePort();

port.createCustomerreview(RestaurantName,customerNameField.getText(),reviewField.getText());

}catch (Exception ex) {

System.err.println("Caught an exception." );ex.printStackTrace();

}refreshView();

}

void refreshView() {try{

while(TableModel.getRowCount()>0) {TableModel.removeRow(0);

}putDataToTable(RestaurantName);repaint();

}catch (Exception ex) {

ex.printStackTrace();}

}

142 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 143: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

4. CustomerReviewTable.putDataToTable 方法填充表。

5. 然后, CustomerReviewTable.refreshView 方法重画窗口,显示新数据。

public void putDataToTable(java.lang.String restaurantname) {RestaurantName = restaurantname;java.util.Vector customerList =

getCustomerReviewByName(restaurantname);Iterator j=customerList.iterator();while (j.hasNext()) {

CustomerreviewDetail ci = (CustomerreviewDetail)j.next();

String[] str = {ci.getCustomername(),ci.getReview()};TableModel.addRow(str);

}}

void refreshView() {try{

while(TableModel.getRowCount()>0) {TableModel.removeRow(0);

}putDataToTable(RestaurantName);repaint();

}catch (Exception ex) {

ex.printStackTrace();}

}

第 5 章 为教程应用程序创建客户端 143

Page 144: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

144 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 145: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

附录 A

DiningGuide 源文件

本附录显示下列 DiningGuide 组件的代码:

■ EJB 层组件:

■ 第 146 页上的 “RestaurantBean.java 源文件”■ 第 149 页上的 “RestaurantDetail.java 源文件”■ 第 154 页上的 “CustomerreviewBean.java 源文件”■ 第 157 页上的 “CustomerreviewDetail.java 源文件”■ 第 160 页上的 “DiningGuideManagerBean.java 源文件”

■ 客户端组件:

■ 第 164 页上的 “RestaurantTable.java 源文件”■ 第 168 页上的 “CustomerReviewTable.java 源文件”

本代码也作为源文件在 DiningGuide 应用程序压缩文件内提供,您可以从位于 Java Studio Enterprise 开发人员资源门户的 “教程和代码库”页面下载该文件:

http://developers.sun.com/devtools/javatools/jsenterprise/learning/tutorials/index.html

提示 – 如果使用这些文件将代码剪切并粘贴到 Java Studio Enterprise 源编辑器中,所有格式都将丢失。要在源编辑器中自动重新设置代码的格式,请在粘贴代码后按住“Control”-“Shift”“F”。

注意 – 带软回车符的行将作为单独的行从 PDF 中复制出来,从而导致编译器将某些类型的语句解释为无意义。本代码中的这些行前面带注释 “在源编辑器中连接下列两行”。此外,源编辑器还会将这些行标记为代码错误,以便可以很容易地找到并更正这些行。

建议 Solaris 和 Linux 用户不要复制这些行,因为源编辑器不会读取行末尾的回车符。要查看源文件,应解压缩 DiningGuide 源压缩文件,然后在 IDE 中安装解压缩后的目录。

145

Page 146: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

RestaurantBean.java 源文件package Data;

import javax.ejb.*;

public abstract class RestaurantBean implements javax.ejb.EntityBean {

private javax.ejb.EntityContext context;

/**

* @see javax.ejb.EntityBean#setEntityContext(javax.ejb.EntityContext)

*/

public void setEntityContext(javax.ejb.EntityContext aContext) {

context=aContext;

}

/**

* @see javax.ejb.EntityBean#ejbActivate()

*/

public void ejbActivate() {

}

/**

* @see javax.ejb.EntityBean#ejbPassivate()

*/

public void ejbPassivate() {

}

/**

* @see javax.ejb.EntityBean#ejbRemove()

*/

public void ejbRemove() {

}

146 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 147: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

/**

* @see javax.ejb.EntityBean#unsetEntityContext()

*/

public void unsetEntityContext() {

context=null;

}

/**

* @see javax.ejb.EntityBean#ejbLoad()

*/

public void ejbLoad() {

}

/**

* @see javax.ejb.EntityBean#ejbStore()

*/

public void ejbStore() {

}

public abstract java.lang.String getRestaurantname();

public abstract void setRestaurantname(java.lang.String restaurantname);

public abstract java.lang.String getCuisine();

public abstract void setCuisine(java.lang.String cuisine);

public abstract java.lang.String getNeighborhood();

public abstract void setNeighborhood(java.lang.String neighborhood);

public abstract java.lang.String getAddress();

public abstract void setAddress(java.lang.String address);

public abstract java.lang.String getPhone();

public abstract void setPhone(java.lang.String phone);

public abstract java.lang.String getDescription();

public abstract void setDescription(java.lang.String description);

public abstract int getRating();

public abstract void setRating(int rating);

附录 A DiningGuide 源文件 147

Page 148: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

public java.lang.String ejbCreate(java.lang.String restaurantname, java.lang.String cuisine, java.lang.String neighborhood, java.lang.String address, java.lang.String phone, java.lang.String description, int rating) throws javax.ejb.CreateException {

if (restaurantname == null) {

// Join the following two lines in the Source Editor

throw new javax.ejb.CreateException("The restaurant name is required.");

}

setRestaurantname(restaurantname);

setCuisine(cuisine);

setNeighborhood(neighborhood);

setAddress(address);

setPhone(phone);

setDescription(description);

setRating(rating);

return null;

}

public void ejbPostCreate(java.lang.String restaurantname, java.lang.String cuisine, java.lang.String neighborhood, java.lang.String address, java.lang.String phone, java.lang.String description, int rating) throws javax.ejb.CreateException {

}

public Data.RestaurantDetail getRestaurantDetail() {

return (new RestaurantDetail(getRestaurantname(),

getCuisine(), getNeighborhood(), getAddress(), getPhone(),

getDescription(), getRating()));

}

}

148 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 149: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

RestaurantDetail.java 源文件/*

* RestaurantDetail.java

*

* Created on March 27, 2003, 3:35 PM

*/

package Data;

import java.beans.*;

public class RestaurantDetail extends Object implements java.io.Serializable {

private static final String PROP_SAMPLE_PROPERTY = "SampleProperty";

private String sampleProperty;

private PropertyChangeSupport propertySupport;

/** Holds value of property restaurantname. */

private String restaurantname;

/** Holds value of property cuisine. */

private String cuisine;

/** Holds value of property neighborhood. */

private String neighborhood;

/** Holds value of property address. */

private String address;

/** Holds value of property phone. */

private String phone;

/** Holds value of property description. */

private String description;

/** Holds value of property rating. */

附录 A DiningGuide 源文件 149

Page 150: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

private int rating;

/** Creates new RestaurantDetail */

public RestaurantDetail() {

propertySupport = new PropertyChangeSupport( this );

}

public RestaurantDetail(java.lang.String restaurantname, java.lang.String cuisine, java.lang.String neighborhood, java.lang.String address, java.lang.String phone, java.lang.String description, int rating) {

System.out.println("Creating new RestaurantDetail");

setRestaurantname(restaurantname);

setCuisine(cuisine);

setNeighborhood(neighborhood);

setAddress(address);

setPhone(phone);

setDescription(description);

setRating(rating);

}

public String getSampleProperty() {

return sampleProperty;

}

public void setSampleProperty(String value) {

String oldValue = sampleProperty;

sampleProperty = value;

propertySupport.firePropertyChange(PROP_SAMPLE_PROPERTY, oldValue, sampleProperty);

}

public void addPropertyChangeListener(PropertyChangeListener listener) {

propertySupport.addPropertyChangeListener(listener);

}

public void removePropertyChangeListener(PropertyChangeListener listener) {

propertySupport.removePropertyChangeListener(listener);

}

/** Getter for property restaurantname.

* @return Value of property restaurantname.

150 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 151: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

*

*/

public String getRestaurantname() {

return this.restaurantname;

}

/** Setter for property restaurantname.

* @param restaurantname New value of property restaurantname.

*

*/

public void setRestaurantname(String restaurantname) {

this.restaurantname = restaurantname;

}

/** Getter for property cuisine.

* @return Value of property cuisine.

*

*/

public String getCuisine() {

return this.cuisine;

}

/** Setter for property cuisine.

* @param cuisine New value of property cuisine.

*

*/

public void setCuisine(String cuisine) {

this.cuisine = cuisine;

}

/** Getter for property neighborhood.

* @return Value of property neighborhood.

*

*/

public String getNeighborhood() {

return this.neighborhood;

}

/** Setter for property neighborhood.

* @param neighborhood New value of property neighborhood.

*

附录 A DiningGuide 源文件 151

Page 152: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

*/

public void setNeighborhood(String neighborhood) {

this.neighborhood = neighborhood;

}

/** Getter for property address.

* @return Value of property address.

*

*/

public String getAddress() {

return this.address;

}

/** Setter for property address.

* @param address New value of property address.

*

*/

public void setAddress(String address) {

this.address = address;

}

/** Getter for property phone.

* @return Value of property phone.

*

*/

public String getPhone() {

return this.phone;

}

/** Setter for property phone.

* @param phone New value of property phone.

*

*/

public void setPhone(String phone) {

this.phone = phone;

}

/** Getter for property description.

* @return Value of property description.

*

*/

152 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 153: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

public String getDescription() {

return this.description;

}

/** Setter for property description.

* @param description New value of property description.

*

*/

public void setDescription(String description) {

this.description = description;

}

/** Getter for property rating.

* @return Value of property rating.

*

*/

public int getRating() {

return this.rating;

}

/** Setter for property rating.

* @param rating New value of property rating.

*

*/

public void setRating(int rating) {

this.rating = rating;

}

}

附录 A DiningGuide 源文件 153

Page 154: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

CustomerreviewBean.java 源文件package Data;

import javax.ejb.*;

public abstract class CustomerreviewBean implements javax.ejb.EntityBean {

private javax.ejb.EntityContext context;

/**

* @see javax.ejb.EntityBean#setEntityContext(javax.ejb.EntityContext)

*/

public void setEntityContext(javax.ejb.EntityContext aContext) {

context=aContext;

}

/**

* @see javax.ejb.EntityBean#ejbActivate()

*/

public void ejbActivate() {

}

/**

* @see javax.ejb.EntityBean#ejbPassivate()

*/

public void ejbPassivate() {

}

/**

* @see javax.ejb.EntityBean#ejbRemove()

*/

public void ejbRemove() {

}

154 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 155: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

/**

* @see javax.ejb.EntityBean#unsetEntityContext()

*/

public void unsetEntityContext() {

context=null;

}

/**

* @see javax.ejb.EntityBean#ejbLoad()

*/

public void ejbLoad() {

}

/**

* @see javax.ejb.EntityBean#ejbStore()

*/

public void ejbStore() {

}

public abstract java.lang.String getRestaurantname();

public abstract void setRestaurantname(java.lang.String restaurantname);

public abstract java.lang.String getCustomername();

public abstract void setCustomername(java.lang.String customername);

public abstract java.lang.String getReview();

public abstract void setReview(java.lang.String review);

public Data.CustomerreviewKey ejbCreate(java.lang.String restaurantname, java.lang.String customername, java.lang.String review) throws javax.ejb.CreateException {

if ((restaurantname == null) || (customername == null)) {

// Join the following two lines in the Source Editor

throw new javax.ejb.CreateException("Both the restaurant name and customer name are required.");

}

setRestaurantname(restaurantname);

setCustomername(customername);

setReview(review);

return null;

附录 A DiningGuide 源文件 155

Page 156: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

}

public void ejbPostCreate(java.lang.String restaurantname, java.lang.String customername, java.lang.String review) throws javax.ejb.CreateException {

}

public Data.CustomerreviewDetail getCustomerreviewDetail() {

return (new CustomerreviewDetail(getRestaurantname(),

getCustomername(), getReview()));

}

}

156 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 157: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

CustomerreviewDetail.java 源文件 * CustomerreviewDetail.java

*

* Created on March 27, 2003, 3:35 PM

*/

package Data;

import java.beans.*;

public class CustomerreviewDetail extends Object implements java.io.Serializable {

private static final String PROP_SAMPLE_PROPERTY = "SampleProperty";

private String sampleProperty;

private PropertyChangeSupport propertySupport;

/** Holds value of property restaurantname. */

private String restaurantname;

/** Holds value of property customername. */

private String customername;

/** Holds value of property review. */

private String review;

/** Creates new CustomerreviewDetail */

public CustomerreviewDetail() {

propertySupport = new PropertyChangeSupport( this );

}

public CustomerreviewDetail(java.lang.String restaurantname, java.lang.String customername, java.lang.String review) {

System.out.println("Creating new CustomerreviewDetail");

setRestaurantname(restaurantname);

setCustomername(customername);

附录 A DiningGuide 源文件 157

Page 158: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

setReview(review);

}

public String getSampleProperty() {

return sampleProperty;

}

public void setSampleProperty(String value) {

String oldValue = sampleProperty;

sampleProperty = value;

propertySupport.firePropertyChange(PROP_SAMPLE_PROPERTY, oldValue, sampleProperty);

}

public void addPropertyChangeListener(PropertyChangeListener listener) {

propertySupport.addPropertyChangeListener(listener);

}

public void removePropertyChangeListener(PropertyChangeListener listener) {

propertySupport.removePropertyChangeListener(listener);

}

/** Getter for property restaurantname.

* @return Value of property restaurantname.

*

*/

public String getRestaurantname() {

return this.restaurantname;

}

/** Setter for property restaurantname.

* @param restaurantname New value of property restaurantname.

*

*/

public void setRestaurantname(String restaurantname) {

this.restaurantname = restaurantname;

}

/** Getter for property customername.

* @return Value of property customername.

*

158 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 159: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

*/

public String getCustomername() {

return this.customername;

}

/** Setter for property customername.

* @param customername New value of property customername.

*

*/

public void setCustomername(String customername) {

this.customername = customername;

}

/** Getter for property review.

* @return Value of property review.

*

*/

public String getReview() {

return this.review;

}

/** Setter for property review.

* @param review New value of property review.

*

*/

public void setReview(String review) {

this.review = review;

}

}

附录 A DiningGuide 源文件 159

Page 160: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

DiningGuideManagerBean.java 源文件package Data;

import javax.ejb.*;

import javax.naming.*;

public class DiningGuideManagerBean implements javax.ejb.SessionBean {

private javax.ejb.SessionContext context;

private RestaurantHome myRestaurantHome;

private CustomerreviewHome myCustomerreviewHome;

/**

* @see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)

*/

public void setSessionContext(javax.ejb.SessionContext aContext) {

context=aContext;

}

/**

* @see javax.ejb.SessionBean#ejbActivate()

*/

public void ejbActivate() {

}

/**

* @see javax.ejb.SessionBean#ejbPassivate()

*/

public void ejbPassivate() {

}

/**

* @see javax.ejb.SessionBean#ejbRemove()

*/

public void ejbRemove() {

}

160 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 161: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

/**

* See section 7.10.3 of the EJB 2.0 specification

*/

public void ejbCreate() {

System.out.println("Entering DiningGuideManagerEJB.ejbCreate()");

Context c = null;

Object result = null;

if (this.myRestaurantHome == null) {

try {

c = new InitialContext();

result = c.lookup("java:comp/env/ejb/Restaurant");

myRestaurantHome = (RestaurantHome)javax.rmi.PortableRemoteObject.narrow(result, RestaurantHome.class);

}

catch (Exception e) {System.out.println("Error: "+

e); }

}

Context crc = null;

Object crresult = null;

if (this.myCustomerreviewHome == null) {

try {

crc = new InitialContext();

result = crc.lookup("java:comp/env/ejb/Customerreview");

myCustomerreviewHome = (CustomerreviewHome)javax.rmi.PortableRemoteObject.narrow(result, CustomerreviewHome.class);

}

catch (Exception e) {System.out.println("Error: "+

e); }

}

}

public java.util.Vector getAllRestaurants() {

System.out.println("Entering DiningGuideManagerEJB.getAllRestaurants()");

java.util.Vector restaurantList = new java.util.Vector();

try {

java.util.Collection rl = myRestaurantHome.findAll();

if (rl == null) { restaurantList = null; }

附录 A DiningGuide 源文件 161

Page 162: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

else {

RestaurantDetail rd;

java.util.Iterator rli = rl.iterator();

while ( rli.hasNext() ) {

rd = ((Restaurant)rli.next()).getRestaurantDetail();

System.out.println(rd.getRestaurantname());

System.out.println(rd.getRating());

restaurantList.addElement(rd);

}

}

}

catch (Exception e) {

// Join the following two lines in the Source Editor

System.out.println("Error in DiningGuideManagerEJB.getAllRestaurants():" + e);

}

// Join the following two lines in the Source Editor

System.out.println("Leaving DiningGuideManagerEJB.getAllRestaurants()");

return restaurantList;

}

public java.util.Vector getCustomerreviewsByRestaurant(java.lang.String restaurantname) {

System.out.println("Entering DiningGuideManagerEJB.getCustomerreviewsByRestaurant()");

java.util.Vector reviewList = new java.util.Vector();

try {

java.util.Collection rl = myCustomerreviewHome.findByRestaurantName(restaurantname);

if (rl == null) { reviewList = null; }

else {

CustomerreviewDetail crd;

java.util.Iterator rli = rl.iterator();

while ( rli.hasNext() ) {

crd = ((Customerreview)rli.next()).getCustomerreviewDetail();

System.out.println(crd.getRestaurantname());

System.out.println(crd.getCustomername());

System.out.println(crd.getReview());

reviewList.addElement(crd);

}

}

}

162 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 163: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

catch (Exception e) {

// Join the following two lines in the Source Editor

System.out.println("Error in DiningGuideManagerEJB.getCustomerreviewsByRestaurant():" + e);

}

// Join the following two lines in the Source Editor

System.out.println("Leaving DiningGuideManagerEJB.getCustomerreviewsByRestaurant()");

return reviewList;

}

public void createCustomerreview(java.lang.String restaurantname, java.lang.String customername, java.lang.String review) {

System.out.println("Entering DiningGuideManagerEJB.createCustomerreview()");

try {

Customerreview customerrev = myCustomerreviewHome.create(restaurantname, customername,

review);

} catch (Exception e) {

// Join the following two lines in the Source Editor

System.out.println("Error in DiningGuideManagerEJB.createCustomerreview():" + e);

}

// Join the following two lines in the Source Editor

System.out.println("Leaving DiningGuideManagerEJB.createCustomerreview()");

}

public Data.RestaurantDetail getRestaurantDetail() {

return null;

}

public Data.CustomerreviewDetail getCustomerreviewDetail() {

return null;

}

}

附录 A DiningGuide 源文件 163

Page 164: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

RestaurantTable.java 源文件/*

* RestaurantTable.java

*

* Created on March 12, 2003, 4:29 PM

*/

package Client;

import javax.swing.table.*;

import java.util.*;

import WebService.DGWebServiceClientGenClient.*;

/**

*

* @author administrator

*/

public class RestaurantTable extends javax.swing.JFrame {

/** Creates new form RestaurantTable */

public RestaurantTable() {

initComponents();

restaurantList=getAllRestaurants();

putDataToTable();

}

/** This method is called from within the constructor to

* initialize the form.

* WARNING:Do NOT modify this code.The content of this method is

* always regenerated by the Form Editor.

*/

private void initComponents() {//GEN-BEGIN:initComponents

jButton1 = new javax.swing.JButton();

jScrollPane1 = new javax.swing.JScrollPane();

jTable1 = new javax.swing.JTable();

jLabel1 = new javax.swing.JLabel();

getContentPane().setLayout(new

org.netbeans.lib.awtextra.AbsoluteLayout());

addWindowListener(new java.awt.event.WindowAdapter() {

public void windowClosing(java.awt.event.WindowEvent evt) {

exitForm(evt);

}

164 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 165: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

});

jButton1.setText("View Customer Comments");

jButton1.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent evt) {

jButton1ActionPerformed(evt);

}

});

getContentPane().add(jButton1, new

org.netbeans.lib.awtextra.AbsoluteConstraints(200, 240, -1, -1));

TableModel = (new javax.swing.table.DefaultTableModel(

new Object [][] {

},

new String [] {

"RESTAURANT NAME", "CUISINE", "NEIGHBORHOOD", "ADDRESS", "PHONE",

"DESCRIPTION", "RATING"

}

) {

Class[] types = new Class [] {

java.lang.String.class, java.lang.String.class,

java.lang.String.class,

java.lang.String.class,java.lang.String.class,java.lang.String.class,java.lang

.String.class

};

public Class getColumnClass(int columnIndex) {

return types [columnIndex];

}

});

jTable1.setModel(TableModel);

jScrollPane1.setViewportView(jTable1);

getContentPane().add(jScrollPane1, new

org.netbeans.lib.awtextra.AbsoluteConstraints(0, 60, 600, 100));

jLabel1.setText("Restaurant Listing");

getContentPane().add(jLabel1, new

org.netbeans.lib.awtextra.AbsoluteConstraints(230, 20, 110, 30));

pack();

}//GEN-END:initComponents

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed

int r =jTable1.getSelectedRow();

int c = jTable1.getSelectedColumnCount();

附录 A DiningGuide 源文件 165

Page 166: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

String i =(String)TableModel.getValueAt(r,0);

CustomerReviewTable crt = new CustomerReviewTable();

crt.putDataToTable(i);

crt.show();

System.out.println(i);

}//GEN-LAST:event_jButton1ActionPerformed

/** Exit the Application */

private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm

System.exit(0);

}//GEN-LAST:event_exitForm

private void putDataToTable() {

Iterator j=restaurantList.iterator();

while (j.hasNext()) {

RestaurantDetail ci = (RestaurantDetail)j.next();

String strRating = null;

String[] str =

{ci.getRestaurantname(),ci.getCuisine(),ci.getNeighborhood(),ci.getAddress(),

ci.getPhone(),ci.getDescription(),

strRating.valueOf(ci.getRating()),

};

TableModel.addRow(str);

}

}

private Vector getAllRestaurants() {

Vector restList = new Vector();

try {

WebService.DGWebServiceClientGenClient.DGWebService service1 = new

WebService.DGWebServiceClientGenClient.DGWebService_Impl();

WebService.DGWebServiceClientGenClient.DGWebServiceServantInterface port

=

service1.getDGWebServiceServantInterfacePort();

restList = (java.util.Vector)port.getAllRestaurants();

}

catch (Exception ex) {

System.err.println("Caught an exception." );

ex.printStackTrace();

}

return restList;

}

166 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 167: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

private Vector getCustomerreviewByRestaurant(java.lang.String

restaurantname) {

Vector reviewList = new Vector();

try {

WebService.DGWebServiceClientGenClient.DGWebService service2 = new

WebService.DGWebServiceClientGenClient.DGWebService_Impl();

WebService.DGWebServiceClientGenClient.DGWebServiceServantInterface port

=

service2.getDGWebServiceServantInterfacePort();

reviewList =

(java.util.Vector)port.getCustomerreviewsByRestaurant(restaurantname);

}

catch (Exception ex) {

System.err.println("Caught an exception." );

ex.printStackTrace();

}

return reviewList;

}

/**

* @param args the command line arguments

*/

public static void main(String args[]) {

new RestaurantTable().show();

}

// Variables declaration - do not modify//GEN-BEGIN:variables

private javax.swing.JButton jButton1;

private javax.swing.JScrollPane jScrollPane1;

private javax.swing.JTable jTable1;

private javax.swing.JLabel jLabel1;

// End of variables declaration//GEN-END:variables

private DefaultTableModel TableModel;

private java.util.Vector restaurantList = null;

}

附录 A DiningGuide 源文件 167

Page 168: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

CustomerReviewTable.java 源文件/*

* CustomerReviewTable.java

*

* Created on March 12, 2003, 4:29 PM

*/

package Client;

import javax.swing.table.*;

import java.util.*;

import WebService.DGWebServiceClientGenClient.*;

/**

*

** @author administrator

*/

public class CustomerReviewTable extends javax.swing.JFrame {

/** Creates new form CustomerReviewTable */

public CustomerReviewTable() {

initComponents();

}

/** This method is called from within the constructor to

* initialize the form.

* WARNING:Do NOT modify this code.The content of this method is

* always regenerated by the Form Editor.

*/

private void initComponents() {//GEN-BEGIN:initComponents

jScrollPane1 = new javax.swing.JScrollPane();

jTable1 = new javax.swing.JTable();

jButton1 = new javax.swing.JButton();

customerNameLabel = new javax.swing.JLabel();

customerNameField = new javax.swing.JTextField();

reviewLabel = new javax.swing.JLabel();

reviewField = new javax.swing.JTextField();

jLabel1 = new javax.swing.JLabel();

getContentPane().setLayout(new

org.netbeans.lib.awtextra.AbsoluteLayout());

addWindowListener(new java.awt.event.WindowAdapter() {

public void windowClosing(java.awt.event.WindowEvent evt) {

168 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 169: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

exitForm(evt);

}

});

TableModel = (new javax.swing.table.DefaultTableModel(

new Object [][] {

},

new String [] {

"CUSTOMER NAME", "REVIEW"

}

) {

Class[] types = new Class [] {

java.lang.String.class,java.lang.String.class

};

public Class getColumnClass(int columnIndex) {

return types [columnIndex];

}

});

jTable1.setModel(TableModel);

jScrollPane1.setViewportView(jTable1);

getContentPane().add(jScrollPane1, new

org.netbeans.lib.awtextra.AbsoluteConstraints(0, 60, 400, 100));

jButton1.setText("Submit Customer Review");

jButton1.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent evt) {

jButton1ActionPerformed(evt);

}

});

getContentPane().add(jButton1, new

org.netbeans.lib.awtextra.AbsoluteConstraints(100, 250, 190, -1));

customerNameLabel.setText("Customer Name");

getContentPane().add(customerNameLabel, new

org.netbeans.lib.awtextra.AbsoluteConstraints(40, 170, -1, -1));

getContentPane().add(customerNameField, new

org.netbeans.lib.awtextra.AbsoluteConstraints(153, 170, 170, -1));

reviewLabel.setText("Review");

getContentPane().add(reviewLabel, new

org.netbeans.lib.awtextra.AbsoluteConstraints(40, 200, 80, -1));

getContentPane().add(reviewField, new

org.netbeans.lib.awtextra.AbsoluteConstraints(153, 200, 170, 20));

jLabel1.setText("All Customer Review By Restaurant Name");

getContentPane().add(jLabel1, new

附录 A DiningGuide 源文件 169

Page 170: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

org.netbeans.lib.awtextra.AbsoluteConstraints(80, 10, 240, -1));

pack();

}//GEN-END:initComponents

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GENFIRST:event_jButton1ActionPerformed

try {

WebService.DGWebServiceClientGenClient.DGWebService service1 = new

WebService.DGWebServiceClientGenClient.DGWebService_Impl();

WebService.DGWebServiceClientGenClient.DGWebServiceServantInterface

port =

service1.getDGWebServiceServantInterfacePort();

port.createCustomerreview(RestaurantName,

customerNameField.getText(),reviewField.getText());

}

catch (Exception ex) {

System.err.println("Caught an exception." );

ex.printStackTrace();

}

refreshView();

}//GEN-LAST:event_jButton1ActionPerformed

void refreshView() {

try {

while(TableModel.getRowCount()>0) {

TableModel.removeRow(0);

}

putDataToTable(RestaurantName);

repaint();

}

catch (Exception ex) {

ex.printStackTrace();

}

}

/** Exit the Application */

private void exitForm(java.awt.event.WindowEvent evt) {//GENFIRST:event_exitForm

System.exit(0);

}//GEN-LAST:event_exitForm

public void putDataToTable(java.lang.String restaurantname) {

RestaurantName = restaurantname;

java.util.Vector customerList =getCustomerReviewByName(restaurantname);

Iterator j=customerList.iterator();

170 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 171: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

while (j.hasNext()) {

CustomerreviewDetail ci = (CustomerreviewDetail)j.next();

String[] str = {ci.getCustomername(),ci.getReview()

};

TableModel.addRow(str);

}

}

private Vector getCustomerReviewByName(java.lang.String restaurantname) {

Vector custList = new Vector();

try {

WebService.DGWebServiceClientGenClient.DGWebService service2 = new

WebService.DGWebServiceClientGenClient.DGWebService_Impl();

WebService.DGWebServiceClientGenClient.DGWebServiceServantInterface

port =

service2.getDGWebServiceServantInterfacePort();

custList =

(java.util.Vector)port.getCustomerreviewsByRestaurant(restaurantname);

}

catch (Exception ex) {

System.err.println("Caught an exception." );

ex.printStackTrace();

}

return custList;

}

/**

* @param args the command line arguments

*/

public static void main(String args[]) {

new CustomerReviewTable().show();

}

// Variables declaration - do not modify//GEN-BEGIN:variables

private javax.swing.JLabel reviewLabel;

private javax.swing.JButton jButton1;

private javax.swing.JScrollPane jScrollPane1;

private javax.swing.JTextField customerNameField;

private javax.swing.JTable jTable1;

private javax.swing.JLabel customerNameLabel;

private javax.swing.JLabel jLabel1;

private javax.swing.JTextField reviewField;

// End of variables declaration//GEN-END:variables

附录 A DiningGuide 源文件 171

Page 172: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

private DefaultTableModel TableModel;

private java.lang.String RestaurantName = null;

//private java.util.Vector restaurantList = null;

}

172 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 173: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

附录 B

DiningGuide 数据库脚本

本附录显示 DiningGuide 教程的下列数据库脚本:

■ 第 174 页上的 “PointBase 数据库脚本”■ 第 175 页上的 “Oracle 数据库脚本”

该代码也可以作为 DiningGuide 应用程序压缩文件中的 SQL 脚本文件。您可以从 Java Studio Enterprise 开发人员资源门户的 “教程和代码库”页面下载,网址为:http://developers.sun.com/devtools/javatools/jsenterprise/learning/tutorials/index.html

173

Page 174: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

PointBase 数据库脚本drop table CustomerReview;

drop table Restaurant;

create table Restaurant(

restaurantName varchar(80),

cuisine varchar(25),

neighborhood varchar(25),

address varchar(30),

phone varchar(12),

description varchar(200),

rating tinyint,

constraint pk_Restaurant primary key(restaurantName));

create table CustomerReview(

restaurantName varchar(80) not null references Restaurant(restaurantName),

customerName varchar(25),

review varchar(200),

constraint pk_CustomerReview primary key(CustomerName, restaurantName));

insert into Restaurant (restaurantName, cuisine, neighborhood, address, phone, description, rating) values ('French Lemon','Mediterranean','Rockridge','1200 College Avenue','510 888 8888','Very nice spot.',5);

insert into Restaurant (restaurantName, cuisine, neighborhood, address, phone, description, rating) values ('Bay Fox','Mediterranean','Piedmont','1200 Piedmont Avenue','510 888 8888','Excellent.',5);

insert into CustomerReview (restaurantName, customerName, review) values ('French Lemon','Fred','Nice flowers.');

insert into CustomerReview (restaurantName, customerName, review) values ('French Lemon','Ralph','Excellent service.');

174 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 175: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

Oracle 数据库脚本

drop table CustomerReview;drop table Restaurant;

create table Restaurant(restaurantName varchar(80),cuisine varchar(25),neighborhood varchar(25),address varchar(30),phone varchar(12),description varchar(200),rating number(1,0),

constraint pk_Restaurant primary key(restaurantName));grant all on Restaurant to public;

create table CustomerReview(restaurantName varchar(80) not null references

Restaurant(restaurantName),customerName varchar(25),review varchar(200),

constraint pk_CustomerReview primary key(CustomerName, restaurantName));grant all on CustomerReview to public;

insert into Restaurant (restaurantName, cuisine, neighborhood, address, phone, description, rating) values ('French Lemon','Mediterranean','Rockridge','1200 College Avenue','510 888 8888','Very nice spot.',5);insert into Restaurant (restaurantName, cuisine, neighborhood, address, phone, description, rating) values ('Bay Fox','Mediterranean','Piedmont','1200 Piedmont Avenue','510 888 8888','Excellent.',5);

insert into CustomerReview (restaurantName, customerName, review) values ('French Lemon','Fred','Nice flowers.');insert into CustomerReview (restaurantName, customerName, review) values ('French Lemon','Ralph','Excellent service.');

commit;

附录 B DiningGuide 数据库脚本 175

Page 176: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

176 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 177: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

附录 C

使用 Oracle 数据库创建教程

本附录描述使用 Oracle 数据库创建和运行 DiningGuide 教程所必须执行的步骤。其中包括下列主题:

■ “使用 Oracle 数据库设置数据库连接”(即接下来的主题)■ 第 183 页上的 “创建数据库表”■ 第 184 页上的 “使用 Oracle 数据库创建 EJB 组件”■ 第 185 页上的 “使用 Oracle 数据库创建 Web 服务”

注意 – 本书中有几个地方引用了 DiningGuide 应用程序文件。这些文件中包括教程应用程序的完整版本、描述如何运行完整应用程序的自述文件,以及创建必需的数据库表所需要的 SQL 脚本文件。这些文件压缩成 zip 文件,您可以从 Java Studio Enterprise 开发人员资源门户下载该 zip 文件,网址为: http://developers.sun.com/devtools/javatools/jsenterprise/

learning/tutorials/index.html。

使用 Oracle 数据库设置数据库连接通过在应用程序服务器环境中执行与 JDBC 相关的必要操作,将 Sun Java System Application Server 配置为连接到 Oracle 数据库。其中包括:

■ 启用数据库的 JDBC 驱动程序■ 创建连接池■ 创建 JDBC 数据源■ 创建 JDBC 持久性管理器

177

Page 178: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

启用 oracle Type 4 JDBC 驱动程序

启用 JDBC 驱动程序意味着将驱动程序库放入 Sun Java Enterprise System 和 Sun Java System Application Server 类路径中。要完成此项操作,您需要 oracle Type 4 JDBC 驱动程序库 (classes12.zip 文件)。可以从 Oracle 门户 Web 站点下载该驱动程序。启用 IDE 之前,应将 JDBC Type 4 驱动程序复制到 Java Studio Enterprise 的程序文件中。

启用 Oracle Type 4 JDBC 驱动程序:

1. 将 Oracle Type 4 驱动程序库复制到 java-studio-install-dir/lib/ext 目录中。

例如,将 classes12.zip 文件复制到 c:\Sun\jstudio\Ent6_04Q1\lib\ext 中。 Solaris 用户将具有不同的目标目录。

注意 – 您必须具有超级用户或管理员特权才能对 Sun Java Enterprise System 起始目录进行写操作。

2. 重新启动 IDE。

3. 在资源管理器的 “运行环境”窗格中,选择您的应用程序服务器实例。

其标记为 app-server-name (app-server-host:app-server-port)。例如,缺省服务器为 server1 (localhost:8080),而标准用户的服务器为 MyServer (localhost:4855)。

4. 显示应用程序服务器实例的属性。

属性窗口通常位于资源管理器窗口的下面。选择节点时便会在窗口中显示属性。如果窗口未出现,请右键单击服务器实例节点,然后选择 “属性”。

5. 打开 “类路径后缀”属性的属性编辑器。

单击该属性的值字段,然后单击出现的省略号按钮。将显示 “类路径后 ”编辑器窗口。

6. 单击 “增加 JAR/ZIP”按钮。

使用 “增加 JAR 文件”文件查找器来定位 classes12.zip 文件。

7. 选择 classes12.zip 文件然后单击 “确定”。

8. 单击 “确定”关闭属性编辑器窗口。

178 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 179: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

将 IDE 连接到 Oracle 服务器

要创建 JDBC 连接资源或教程的 EJB 层,必须将 IDE 连接到 Oracle 数据库。可以在创建这些组件之前或创建过程中进行连接。下面讲述的是如何提前连接到数据库:

1. 确保 Oracle 服务器正在运行。

2. 在资源管理器的 “运行环境”窗格中,展开 “数据库”节点及其 “驱动程序”子节点。

将显示一个标记为 “Oracle thin”的节点。

如果该节点具有红色的删除线,则说明您未正确地启用 Oracle JDBC 驱动程序。请按照 第 178 页上的 “启用 oracle Type 4 JDBC 驱动程序” 中的过程执行操作。

3. 右键单击该节点,然后选择 “连接方法”。

将显示 “新建数据库连接”对话框。

4. 确保在名称字段中选定了 “Oracle thin”。

5. 在 “数据库 URL”、“用户名”和 “口令”中填入属性值。

例如,对于本地安装的 Oracle 数据库 (SID 为 “extut”、“用户名”为缺省 Oracle 登录 “scott”、“口令” 为 “tiger”)而言,下列值是正确的:(1521 为标准 Oracle 端口号。)

6. 启用 “在此会话期间记住口令”选项。

“新建数据库连接”对话框应如下所示:

名称 值

URL jdbc:oracle:thin:@localhost:1521:extut

用户名 scott

口令 tiger

附录 C 使用 Oracle 数据库创建教程 179

Page 180: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

7. 单击 “确定”。

8. 关闭 “驱动程序” 节点。

将显示新的 Oracle thin 驱动程序节点,其标记为 jdbc:oracle:thin:@hostname:1521:sid [Username on Password]。

9. 展开该节点及其 “表”子节点。

将显示数据库中的表,包括 RESTAURANT 和 CUSTOMERREVIEW 表。

创建 JDBC 连接池

要创建 JDBC 连接池,以便系统中的业务对象可以共享数据库访问,应首先用与您数据库有关的信息定义一个 JDBC 连接池,然后将它注册到 Sun Java System Application Server中。

注意 – 在开始此过程之前,应确保管理服务器和应用程序服务器都在运行 (请参考第 23 页上的 “启动应用程序服务器”)。

为此教程创建 Oracle JDBC 连接池:

1. 在资源管理器的 “运行环境”标签中,依次展开 “服务器注册”、“已安装服务器”以及 Sun ONE Application Server 7 节点。

2. 右键单击 “未注册的 JDBC 连接池”节点,然后选择 “增加新的 JDBC 连接池”。

这将打开 “新建 JDBC 连接池”向导。

3. 键入 OraclePool 作为 JDBC 连接池的名称。

4. 启用 “从现有连接中提取”选项。

5. 从下拉菜单中选择 Oracle thin 字符串。

6. 单击 “下一步”,然后单击 “完成”。

将显示一个窗口,询问您是否要注册该资源。

7. 单击 “注册”按钮。

将显示 “JDBC 连接池注册”对话框。

8. 从列表中选择要注册到的服务器实例,然后单击 “注册”。

连接池注册后,将显示一条消息指出注册成功。

180 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 181: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

9. 单击 “关闭”按钮关闭窗口。

将显示已注册的 OraclePool 连接池。

如果看不到 OraclePool 连接池,请右键单击 “已注册的 JDBC 连接池”节点,然后选择 “刷新列表”。

创建 JDBC 数据源

使用 JDBC 数据源(也称为 JDBC 资源),可以通过 getConnection() 方法建立与数据库的连接。创建数据源之前,应确保管理服务器和应用程序服务器都在运行。

创建 JDBC 数据源:

1. 如有必要,应在资源管理器的 “运行环境”标签中依次展开 “服务器注册”、“已安装服务器”以及 Sun ONE Application Server 7 节点。

2. 右键单击 “未注册的 JDBC 数据源”节点,然后选择 “增加新数据源”。

这将打开 “新建 JDBC 资源”向导。

已注册的 Oracle 连接池

附录 C 使用 Oracle 数据库创建教程 181

Page 182: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

3. 启用 “使用现有的 JDBC 数据源”选项,然后从列表中选择 OraclePool。

4. 键入 jdbc/jdbc-oracle 作为 JNDI 名称,然后在 “已启用”字段中选择 “True”。

5. 单击 “完成”。

将显示一个窗口,询问您是否要注册该资源。

6. 单击 “注册”按钮。

将显示 “持久性管理器注册”对话框。

7. 从列表中选择要注册到的服务器实例,然后单击 “注册”。

数据资源注册后,将显示一条消息指出注册成功。

8. 单击 “关闭”按钮关闭窗口。

jdbc/jdbc-oracle 节点将显示在 “已注册的 JDBC 数据源”节点下。如果看不到该节点,请右键单击 “JDBC 数据源”节点,然后选择 “刷新列表”。

创建 JDBC 持久性管理器

持久性管理器是一个组件,它负责安装在容器中的实体 bean 的持久性。创建持久性管理器之前,应确保管理服务器和应用程序服务器都在运行。

创建 JDBC 持久性管理器:

1. 如有必要,应在资源管理器的 “运行环境”页中依次展开 “服务器注册”、“已安装服务器”、 Sun ONE Application Server 7 节点。

2. 右键单击 “未注册的持久性管理器”节点,然后选择 “增加持久性管理器”。

这将打开 “新建持久性管理器”向导。

3. 启用 “使用现有的 JDBC 资源”选项,然后从列表中选择 jdbc/jdbc-oracle。

4. 键入 jdo/OraclePm 作为 JNDI 名称,然后在 “已启用”字段中选择 “True”。

5. 单击 “完成”。

将显示一个窗口,询问您是否要注册该资源。

6. 单击 “注册”按钮。

将显示 “持久性管理器注册”对话框。

7. 从列表中选择要注册到的服务器实例,然后单击 “注册”。

持久性管理器注册后,将显示一条消息指出注册成功。

8. 单击 “关闭”按钮关闭窗口。

jdo/OraclePm 节点显示在 “已注册的持久性管理器”节点下。如果看不到该节点,请右键单击 “已注册的持久性管理器”节点,然后选择 “刷新列表”。

182 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 183: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

创建数据库表您必须在 Oracle Server 数据库中创建 DiningGuide 教程使用的两个数据库表。下面的说明描述了如何使用所提供的 SQL 脚本来创建表。 Microsoft Windows 用户可以通过复制并粘贴附录 B 中所提供的 SQL 脚本来创建这些表。 Solaris 和 Linux 用户可以使用脚本文件 diningguide_ora.sql,该文件在 DiningGuide 应用程序文件内提供。

在 Microsoft Windows 系统上的 Oracle 数据库中安装教程表:

1. 打开 Oracle 控制台,方法是:选择 “开始” → “程序” →“Oracle (您使用的版本)” → “应用程序开发” → “SQL Plus”。

2. 使用用户名和口令登录到 SQL Plus。例如,对缺省 Oracle 安装使用用户名 (scott) 和口令 (tiger)。

3. 当 SQL 提示符出现时,将附录 B 中的脚本复制并粘贴到提示符旁边。

提示 – 应避免复制 初的两个 DROP 语句,它们引用的是尚未创建的表,会产生无害的错误。但是,这些 DROP 语句将来会有用,例如重新运行脚本以便对表进行初始化时。

在 Solaris 或 Linux 环境中安装教程数据库:

1. 解压缩 开发人员资源门户 Web 站点的 DiningGuide.zip 文件。

例如,将它解压缩到 /MyZipFiles 目录。

2. 在命令提示符处,键入:

例如,

两个 DROP 语句将产生错误,但这些错误无害。

$ cd your-unzip-dir/DiningGuide/db$ sqlplus db-userid/db-password@db-servicename @diningguide_ora.sql

$ cd /MyZipFiles/DiningGuide/db$ sqlplus scott/tiger@MyDB @diningguide_ora.sql

附录 C 使用 Oracle 数据库创建教程 183

Page 184: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

使用 Oracle 数据库创建 EJB 组件这一节列出了使用 Oracle 数据库创建 EJB 层时,必须对第 3 章进行的更改。表 C-1 列出了相应的部分以及需要进行的更改。

表 C-1 对第 3 章进行的更改 (与 Oracle 有关)

节 更改

第 55 页上的 “为教程的表创建数据库结构”,步骤 2b。

1. 展开 “驱动程序”文件夹,右键单击 “Oracle thin”节点,然后选择 “新建数据库连接”。

2. 在对话框中,指定您的 Oracle URL、用户名以及口令。 3. 选中 “在此会话期间记住口令”,然后单击 “确定”。

4. 关闭 “驱动程序”文件夹。将出现一个 Oracle 连接。

同一节,步骤 5b。 从列表中选择 Oracle 连接。

第 57 页上的“创建 Restaurant 实体 Bean”

使用 Oracle 结构创建 Restaurant 实体 bean。

第 61 页上的 “创建 Customerreview 实体 Bean”

使用 Oracle 结构创建 Customerreview 实体 bean。

第 77 页上的 “为 Sun Java System Application Server 插件提供数据库信息”,步骤 9。

步骤 9。在 “ JNDI 名称”字段中键入 jdo/OraclePM。步骤 10:键入 Oracle 数据库用户名和口令。

第 83 页上的 “检查对数据库的增加”

1. 启动 SQLPlus。2. 登录到数据库。

3. 输入 SQL 语句。

第 84 页上的 “为 Customerreview Bean 创建测试客户端”

步骤 8。在 “ JNDI 名称”字段中键入 jdo/OraclePM。步骤 9。键入 Oracle 数据库用户名和口令。

第 102 页上的 “为 Sun Java System Application Server 插件提供数据库信息”

步骤 9。在 “ JNDI 名称”字段中键入 jdo/OraclePM。步骤 10:键入 Oracle 数据库用户名和口令。

184 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 185: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

使用 Oracle 数据库创建 Web 服务这一节列出了使用 Oracle 数据库创建 Web 服务时,必须对第 4 章进行的更改。表 C-2 列出了相应的部分以及需要进行的更改。

表 C-2 对第 4 章进行的更改 (与 Oracle 有关)

节 更改

第 121 页上的 “使用测试应用程序测试 Web 服务”,步骤 2

启动 SQLPlus,登录到数据库,然后按照描述测试记录的插入。

附录 C 使用 Oracle 数据库创建教程 185

Page 186: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

186 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 187: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

索引

Aaccessor 方法,向用户公开 , 68“安装文件系统”菜单项 , 55

Bbusiness 方法

CustomerreviewgetCustomerreviewDetail, 73getReview, 69

DiningGuideManagercreateCustomerreview, 96, 107getAllRestaurants, 92, 107getCustomerreviewDetail, 98, 107getCustomerreviewsByRestaurant, 94,

108getRestaurantDetail, 98, 108

RestaurantgetRating, 68, 83getRestaurantDetail, 73

Restaurant.getRestaurantDetail, 52business 方法, Swing 客户机

CustomerReviewTablegetCustomerReviewByName, 140jButton1ActionPerformed, 141putDataToTable, 139, 140, 143refreshView, 142, 143

RestaurantTablegetAllRestaurants, 137jButton1ActionPerformed, 139, 141putDataToTable, 138

部署对会话 beans 增加 Sun ONE Application Server 7 属

性 (Oracle), 185对实体 bean 增加 Sun ONE Application Server 7 属

性 (Oracle), 185会话 bean 的测试应用程序 , 106实体 bean 的测试应用程序 , 79, 86使用 IDE 卸下 , 104 至 106为会话 bean 增加 Sun ONE Application Server 7 属

性 (PointBase), 103 至 104为实体 bean 增加 Sun ONE Application Server 7 属

性 (PointBase), 77 至 79, 85“部署” 菜单项 , 120

Ccreate 方法

Customerreview.create, 64, 80, 86DiningGuideManager.create, 90 至 91, 106JNDI 查找代码 , 90Restaurant.create, 62, 81, 87

CustomerReview 表 , 描述 , 34Customerreview 实体 bean

create 方法,创建 , 64测试 , 84创建 , 54 至 69getReview 方法,创建 , 69

Customerreview_TestApp, 85bean 方法,测试 , 86 至 88部署 , 86

187

Page 188: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

创建 , 84 至 85卸下 , 104 至 106

CustomerReviewTable

复制到 DiningGuide 应用程序中 , 133 至 134显示 , 39, 135, 136

参数测试客户机中的顺序 , 80更改顺序 , 80

测试企业 beanbusiness 方法,测试 , 83create 方法,测试 , 81, 86测试客户机页 , 79, 106finder 方法,测试 , 82J2EE 命令窗口中的结果 , 80, 120IDE 的输出窗口中的结果 , 120IDE 输出窗口中的结果 , 80

测试应用程序Customerreview_TestApp, 85DGApp, 117DiningGuideManager_TestApp, 101Restaurant_TestApp, 74

测试应用程序工具测试客户机,部署 , 79, 86, 106测试客户机,创建 , 74 至 79, 84 至 85, 101 至 104测试客户机,使用 , 80 至 84, 106 至 108会话 bean,测试 , 101 至 108将实体 bean 增加到 EJB 模块中 , 102实体 bean,测试 , 80 至 84使用 , 45web 服务,测试 , 117 至 128

“查看数据”菜单项 , 41, 84, 88持久性管理器

以所有其它用户身份创建 (PointBase), 32用途 , 31

持续性管理器创建 (Oracle), 182 至 183

创建 web 服务 , 46, 113 至 115创建 web 服务客户机 , 118“创建服务器实例”菜单项 , 28“创建新的 EJB 测试应用程序”菜单项 , 74, 101

DDGApp, 121DGWebService, 113DiningGuide Swing 客户机

安装和使用 , 47从 web 服务生成 , 122执行 , 39

DiningGuide 应用程序

部署 , 46, 119EJB 层 , 50 至 53功能规范 , 38功能描述 , 37Swing 客户机,检查 , 137 至 143Swing 客户机,增加到应用程序中 , 133 至 134Swing 客户机,执行 , 134数据库表 , 描述 , 34数据库脚本 (Oracle), 175数据库脚本 (PointBase), 174体系结构 , 41限制 , 48, 54压缩后的源文件 , 21, 177应用程序方案 , 38用户的视图 , 39

DiningGuideManager 会话 beangetCustomerreviewDetail 方法 , 98

DiningGuideManager 会话 beancreate 方法,编码 , 90 至 91createCustomerreview 方法 , 84, 96 至 97,

107, 124测试 , 106 至 108创建 , 88getAllRestaurants 方法 , 92 至 93, 107getCustomerreviewDetail 方法 , 107getCustomerreviewsByRestaurant 方法

, 94 至 95, 108getRestaurantDetail 方法 , 98, 108

DiningGuideManager_TestApp

bean 方法,测试 , 106 至 108部署 , 106创建 , 101 至 104

documentation, related, 19

188 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 189: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

EEJB 层概述 , 43, 50 至 53EJB QL,在 finder 方法中使用 , 66EJB 生成器

本地或远程接口 , 54, 88会话 bean,创建 , 88 至 89实体 bean,创建 , 54 至 61使用 , 45

Ffinder 方法

Customerreview.findByRestaurantName,66, 82

测试 , 82Restaurant.findAll, 52, 66, 82

G构造函数

CustomerreviewDetail, 72RestaurantDetail, 71

H会话 bean

business 方法,创建 , 92 至 95本地或远程接口 , 88create 方法,测试 , 106create 方法,修改 , 90测试 , 101 至 108创建 , 88 至 101EJB 引用,增加 , 99 至 101验证 , 99

JJ2EE 应用程序

部署 , 119创建 , 118DGApp, 118

JDBC 连接池

创建 (Oracle), 180 至 181以所有其它用户身份创建 (PointBase), 32用途 , 31

JDBC 驱动程序

启用 (Oracle), 178启用 (PointBase), 31

JDBC 数据源

创建 (Oracle), 182以所有其它用户身份创建 (PointBase), 32用途 , 31

JNDI 查找代码 , 90接口,本地或远程

对于实体 bean, 54会话 bean 的 , 88

K客户机文件方法

getAllRestaurants, 127getCustomerreviewsByRestaurant, 122

NNetscape 浏览器 , 支持的版本 , 22

OOracle 数据库

安装类型 4 JDBC 驱动程序 , 178连接到 IDE, 179 至 180参见数据库

PPointBase 数据库

安装类型 4 JDBC 驱动程序 , 31支持的版本 , 22

Q前言 , 13

索引 189

Page 190: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

RRestaurant 表 , 描述 , 34Restaurant 实体 bean

create 方法 , 62, 81, 87创建 , 54 至 69findall 方法 , 52getRating 方法 , 68, 83getRestaurantDetail 方法 , 52

Restaurant_TestApp

bean 方法,测试 , 80 至 83部署 , 79创建 , 74 至 79卸下 , 104 至 106

RestaurantTable

复制到 DiningGuide 应用程序中 , 133 至 134显示 , 39, 135

runide.sh 脚本 , 23任务概述 , 44 至 46

SSwing 客户机

检查代码 , 137 至 143增加到 DiningGuide 应用程序中 , 133 至 134执行 , 135

Sun Java System Application Serverstarting the admin server (default domain), 25 至 ??starting the application server from Start menu, 24停止 , 136

Sun ONE Application Server 7启动管理服务器(标准用户) , 26 至 29启动管理服务器(超级用户) , ?? 至 26启动应用程序服务器 , 29 至 30确认为缺省服务器 , 30数据库连接 , 31 至 33

Sun ONE Application Server 7 服务器

为会话 bean 设置的插件属性 (PointBase), 103 至104

要对会话 beans 设置的插件属性 (Oracle), 185要对实体 bean 设置的插件属性 (Oracle), 185要为实体 bean 设置的插件属性 (PointBase), 77 至

79, 85Sun ONE Studio 5 IDE

创建数据库方案 (Oracle), 185创建数据库方案 (PointBase), 55打开数据库连接 (Oracle), 185打开数据库连接 (PointBase), 55建立数据库连接 (PointBase), 31 至 33连接到 Oracle 服务器 , 179 至 180启动 IDE, 23设置数据库连接 (Oracle), 177 至 183

Sun ONE Studio 5, Standard Edition, 获取位置 , 21“生成 Web 服务文件”菜单项 , 115生成的 web 服务 , 112生成的运行环境类 , 112“生成客户机文件”菜单项 , 130示例应用程序

StockApp 和 UDDI 注册 , 47实体 Bean

创建 , 54 至 61实体 bean

business 方法,测试 , 83business 方法,创建 , 68本地或远程接口 , 54create 方法,测试 , 80create 方法,创建 , 62测试 , 80 至 83finder 方法,测试 , 82finder 方法,创建 , 66验证 , 68增加到 EJB 模块中 , 102主键类 , 61

使用测试应用程序工具 , 45数据库

安装 Oracle JDBC 驱动程序 , 178安装 PointBase JDBC 驱动程序 , 31创建教程表 (Oracle), 184创建数据库方案 (Oracle), 185创建数据库方案 (PointBase), 55从方案创建实体 bean, 54 至 61打开连接 (Oracle), 185打开连接 (PointBase), 55建立连接 (PointBase), 31 至 33SQL 脚本教程 (Oracle), 175SQL 脚本教程 (PointBase), 174设置连接 (Oracle), 177 至 183

190 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月

Page 191: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

在 IDE 中查看数据 , 41, 84, 88支持的版本 , 22

Wweb 服务

测试 , 117 至 128创建 , 113 至 115公开基础集合类型的类类型 , 97 至 99客户机文件 , 112描述 , 111 至 112生成 WSDL, 129生成客户机文件 , 130与其它开发者共享 , 129 至 131

web 服务客户机方法createCustomerreview, 141getAllRestaurants, 137getCustomerreviewsByRestaurant, 140

Web 服务描述语言 (WSDL),生成 , 129web 浏览器 , 支持的版本 , 22

X详细资料类

创建 , 70 至 72描述 , 45, 51

卸下应用程序如何 , 104 至 106原因 , 104, 119

“新建 CMP 实体 EJB”菜单项 , 57“新建 EJB 测试应用程序”菜单项 , 74“新建 J2EE 应用程序”菜单项 , 118“新建 Java Bean”菜单项 , 70“新建 Web 服务测试客户机”命令 , 117“新建 Web 服务”菜单项 , 113

Y“验证 EJB”菜单项 , 68, 99

Z“增加 Business 方法”菜单项 , 68“增加 Create 方法”菜单项 , 62“增加 Finder 方法”菜单项 , 66“增加构造函数”菜单项 , 71“增加管理服务器”菜单项 , 26“增加模块”菜单项 , 118执行

会话 bean 的测试应用程序 , 106实体 bean 的测试应用程序 , 79, 86

索引 191

Page 192: docs.oracle.com版权所有 © 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. 保留所有权利。 美国政府权利 - 商业软件

192 Sun Java Studio J2EE 应用程序教程 • 2004 年 4 月