级别: 中级 Sami Joueidi, 高级 Rational 工程师, IBM
2008 年 12 月 08 日 本文将带您练习利用 Ajax 和 IBM® Rational® Application Developer 中的关系元组列表(Relational Record List)、下拉列表框(Combo Box)、选项卡面板(Panels-Tabbed),及数据树(Data Tree)组件,进行天气预报应用程序的设计和实现所需的操作步骤及编写代码的工作。本文还阐述了访问来自有两个关系表的 Relational Record List 中元素的技术。
关于本文
本文指导您逐步地使用 Asynchronous JavaScript and XML(AJAX,以下称为 Ajax)和 IBM® Rational® Application Developer Version 7.0 进行应用程序的设计和开发。文中包含如何使用各种 Java™Server Faces(JSF)组件连同 Ajax 的实践技术,并且向您展示了如何克服 Relational Record List 中的内嵌缓冲技术。本文阐述了如何初始化会话范围变量,使之显示出与应用程序启动时 Combo Box 控件的初始值相对应的数据。
您还将了解到向 Web 页面添加 Tabbed Panel 控件,以及配置 Data Tree,使其与 Relational Record List 一起工作的步骤。文中结尾向您展示了访问来自包含两个关系表的 Relational Record List 中的数据元素的技术。
本文没有详细介绍实例中用到的所有技术,但如果您想要了解更多,那么参考资料中引用的一些文章介绍了它们。主要用到的技术是 Ajax、使用了 IBM Enhanced Faces 组件的 JSF,及服务数据对象(service data objects,SDOs)。
背景知识及系统需求
这些指导假设您了解 Java™ 语言的基础知识,但您不需要 Java 方面的扩展经验。然而,本文假设您基本了解 Rational Application Developer 开发环境的使用。本文还假设您基本了解 Ajax 和 SDOs。参见 参考资料,获得更多关于这些技术的信息。
要运行本文中的实例,您的工作站必须安装了 IBM®
Rational® Software Architect 或 Rational Application Developer。本文中使用的 Rational Application Developer 的版本是 7.0。
创建 WeatherForecastDB 数据库
要创建应用程序数据库,您将完成以下这三个任务:
- 下载并将 CreateWeatherForecastDatabase.zip 导入到您的工作区。
- 利用提供的 Java 应用程序创建名为 WeatherForecastDB 的支持的 Derby 数据库。
- 创建到 WeatherForecastDB 数据库的连接。
下载并导入 Java 工程
天气预报应用程序使用 Derby 数据库存储信息。对于本实例,您将使用 Java 应用程序来创建数据库。如果您想要了解更多关于如何利用 Rational Application Developer 中的 Data 透视图手工创建数据库的信息,请阅读标题为“Hello World (Updated): Rational Application Developer V7, Create Java, Web Service, and database applications” 的 IBM®
developerWorks® 上的文章(参见 参考资料 中的链接)。
要开始,就遵照以下这些步骤:
- 下载并将 CreateWeatherForecastDatabase.zip 文件保存到您的计算机中(参见 下载)。
- 在您的桌面上启动 Rational Application Developer。如果出现了询问工作区目录的窗口,输入
c:\temp\weatherforecast,然后单击 OK。
- 如果出现了 Welcome 窗口就将其关闭。
- 导入 CreateWeatherForecastDatabase.zip 文件:
- 在工作平台中,选择 Window > Open Perspective >
Java 来切换到 Java 透视图。
- 选择 File > Import > Other > Project Interchange,将工程导入到您的工作区中。
- 单击 Next。
- 在 From zip file 旁边,单击 Browse,导航到您保存 CreateWeatherForecastDatabase.zip 文件的地方。
- 单击 Select All。
- 单击 Finish。
接下来,为 Java 工程设置 Java 链编路径。
- 在 Package Explorer 视图中右键单击 CreateWeatherForecastDatabase(图 1)来设置 Java 链编路径,以防在您导入工程时,没有将其带过来。
图 1. 设置 Java 链编路径
- 选择 Properties(参见图 2)。
- 单击 Java Build Path。
- 单击 Libraries 选项卡。确保添加了 derby.jar 文件的路径。如果您没有找到它,那么您需要通过以下这些步骤手工地添加它:
- 单击 Add External JARs。
- 输入以下路径:
C:\Program
Files\IBM\SDP70Shared\plugins\com.ibm.datatools.db2.cloudscape.driver_1.0.0.v200610121320\driver\derby.jar
- 单击 Open。
- 单击 OK。
图 2. derby.jar 文件的路径
重要的提示:
这些指导假设您已经选择了 Rational Application Developer Version 7.0 的默认安装,并且您正使用 Rational Application Developer 中包含的 Embedded Derby 文件,没有数据库安全性。
如果没有,请在 Java 链编路径和类位置中相应地将连接修改为 derby.jar 文件的路径。同样,您可能需要在 CreateWeatherForecastTablesDB.java 文件中编辑驱动器、协议、用户 ID,和密码的条目。
创建 WeatherForecastDB 数据库
现在您要准备创建 WeatherForecastDB 数据库:
- 在 Package Explorer 下,展开 CreateWeatherForecastDatabase >
default package。
- 右键单击 CreateWeatherForecastTablesDB.java,然后选择 Run
As > Java Application。
- 注意 Console 视图中最后一条消息,“Committed transactions”。此消息说明 Java 应用程序已经成功地完成了这些任务:
- 在 c:\temp 目录下创建了 WeatherForecastDB 数据库
- 创建了表、主键、外键,和索引
- 加载了实例要使用的测试数据
创建数据库连接
现在您已经创建了 WeatherForecastDB 数据库,您需要创建数据库连接。您将在 Database Explorer 视图中创建到 WeatherForecastDB 数据库的连接。
备选方案:
下面的步骤介绍了如何手工地创建数据库连接。如果您喜欢,您可以利用 SDO Creation 向导创建连接。
- 选择 Window > Open Perspective > Other 来切换到 Data 透视图。
- 选择 Show all 复选框,然后选择 Data。
- 单击 OK。
- 如果询问您启用 Core Database Development 功能,就单击 OK。
- 在 Database Explorer 视图中,右键单击 Connections (在左下角),并单击 New Connection。
- 在 Connection identification 下(图 3),选择 Use default naming
convention。
- 选择 Derby 10.1。
- 对于 Database location,输入
C:\temp\WeatherForecastDB。
- 取消选择 Create the database if required,因为您已经创建了数据库。
- 对于 Class location,输入此路径:
/C:/Program Files/IBM/SDP70Shared/plugins/com.ibm.datatools.db2.cloudscape.driver_
1.0.0.v200610121320/driver/derby.jar
- 在 User Information 下,输入
Weather 作为用户 ID。密码为空。
- 单击 Test Connection ,看看连接是否建立了。如果可以建立,您应该会看到提示“Connection to Derby is successful”的窗口。
- 单击 OK 关闭窗口。
- 单击 Next。
- 单击 Finish 创建连接。
图 3. 连接的参数
- 在 Database Explorer 视图下,展开 WeatherForecastDB connection,看看图 4 显示的数据库表(LARGESTCITIES、STATES、STATESANDCITIES 和 TENDAYFORECAST)。
图 4. 数据库表
图 5 中的图显示了刚创建的表和它们之间的关系。
图 5. 表及其关系
创建天气预报应用程序
现在您已经铺好了地基,以下是接下来的步骤:
- 创建天气预报动态 Web 工程。
- 利用 JavaServer™ Faces 技术创建 JSP 页面。
- 创建会话范围变量。
- 创建 Relational Record Lists。
- 向 JSP 页面添加这些组件和 Ajax 支持:
- Table
- Combo Box
- Panel Group-Box
- 部署并测试天气预报应用程序。
- 关闭 largestCityPopulationSB Relational Record List 的缓存技术。
- 再次部署并测试应用程序。
- 初始化会话范围变量。
- 再次部署并测试应用程序。
创建 WeatherForecastProject 项目
天气预报应用软件的第一部分显示了一个给定城市的人口。
在本章中,您将创建动态 Web 项目以及您的第一个使用 JavaServer™ Faces (JSF) 技术的 JavaServer Page (JSP)。 基础的天气预报应用软件将使用一个组合框来显示不同的美国城市。 基于所选择的城市,将从数据库中获取城市人口和等级,并显示在一个关联记录列表中。 JSF 技术被用于构建这个动态 Web 应用程序。
- 在菜单栏中,选择File > New > Project。
- 在 Select a wizard 中,选中 Show All Wizards。
- 向下滚动并选中 Web > Dynamic Web Project。
- 点击 Next。
- 如果得到提示,点击 OK 确认您想要激活 Web 开发。
- 在 Name 字段中,输入
WeatherForecastProject。
-
重要: 对于配置,选择 Faces Project。
- 确保 Add project to an EAR 复选框被选中。
- 点击 Finish。
- 点击 Yes 切换到 Web 透视图。
图 6. 创建 Web 项目
创建 comboBoxExample.jsp JSP 页面
您现在有了一个新的 Web 项目。 您的下一步是构建 comboBoxExample.jsp 页面:
- 关闭 WebDiagram.gph,如果它被打开了。
- 右键点击 WeatherforecastProject,然后选择 New > Web Page 以登录 New Page 向导。
- 对于文件名,输入
comboBoxExample.jsp。
- 在 Basic Templates 下,选择 JSP。
- 点击 Options,选择 JavaServer Faces。
- 单击 Close。
- 点击 Finish。
- 点击 Finish。
图 7. 创建 comboBoxExample.jsp 页面
文件 comboBoxExample.jsp 在 WeatherForecastProject/WebContent 下被创建。 当 Rational Application Developer 打开页面时,您准备好设计页面了。
创建一个 sessionScope 变量,名为 largestCityVar
- 从 Page Data 视图,其位于 Web 透视图中的 左下 区域,展开 Scripting Variables。
- 右键点击 sessionScope,然后选择 New > Session Scope Variable。
- 对于 Variable 名称,输入
largestCityVar。
- 对于 Type,输入
java.lang.String。
- 点击 OK。
创建一个关联记录列表,名为 largestCitiesSB
- 在 Web 透视图中,进入 Page Data 视图,其位于 左下 区域。
- 右键点击 Relational Records ,并选择 New > Relational Record List。
- 对于 Name,输入
largestCitiesSB。
- 点击 Next。
- 点击 New。
- 选择 Use an existing connection。
提示:
您正在使用您之前手动创建的数据库连接。 如果您还没有创建连接,您可以使用 SDO Creation 向导来创建到数据库的连接。
- 选择WeatherForecastDB,并点击Next。
- 对于 User ID,保留为 Weather。
- 保留 Password 字段为空。
- 点击 Next。
- 点击 Finish。
- 在 Table 下,向下滚动,展开 WEATHER,选择 LARGESTCITIES。
- 点击 Next。
- 点击 None。 您将会注意到,只有 LARGEST_CITY 仍然被选中,因为它是主键。
- 点击 Finish。
图 8. 创建关联记录列表 largestCitiesSB
创建关联记录列表 largestCityPopulationSB
注意:
这时,您将应用一个对关联记录列表的过滤器,只选中相应城市的记录,城市由 largestCityVar sessionScope 变量来指定。
- 从 Page Data 页签中,其位于 Web 透视图中的左下区域,右键点击 Relational Records,并选择 New > Relational Record List。
- 名称输入
largestCityPopulationSB。
- 点击 Next。
- 在 Table 下,向下滚动,展开 WEATHER,选择 LARGESTCITIES。
- 点击 Next。
- 在 Tasks 下,点击 Filter results。
- 点击加号(+)。
- 选择 LARGEST_CITY,然后,从 Column 的下拉菜单中,选择 LIKE。
- 选择 Variable,然后点击椭圆形按钮(三个点: ...).
- 展开 sessionScope,并选择 largestCityVar。
图 9. 过滤设置
- 点击 OK。
- 在此点击 OK。
- 单击 Close。
- 在 Tasks 下,点击 Order Results。
- 移动到 Order by 下的 Ranking and LARGEST_CITY。
- 单击 Close。
图 10. 排序结果
- 点击 Finish。
向 JSP 页面中添加组件和 Ajax 支持
向 JSP 页面中添加一个表
- 在 HTML 标记下,通过使用工具板将一个表拖拽到页面上,并指定这些尺寸:
-
行: 1
-
列: 2
-
表格宽度: 100%
-
边框宽度: 0 像素
图 11. 指定表格尺寸
- 点击 OK。
- 5. 在表格的 Properties 视图中,确保 Table 被选中,并点击 table leaf,并指定这些选项:
-
对齐: 左对齐
-
宽度: 100%
-
高度: 100%
图 12. 表格页行高
- 在单元格的 Properties 视图中,将光标放在第一个单元格中,指定如下版式:
-
水平: 左
-
垂直: 高
-
宽度: 20%
-
自动换行: 未选中
- 将您的光标放在第二个单元格中,并指定版式:
-
水平: 左
-
垂直: 高
-
宽度: 80%
-
自动换行: 未选中
- 点击 File > Save All 保存您的工作。
增加一个组合框
- 在第一个单元格中,输入
Select a City: .
- 从 Enhanced Faces Components 工具下,在您刚才输入的文本旁,拖拽一个 组合框 到第一个单元格中。
增加一个 Panel-Group Box
- 拖拽一个 Panel-Group Box 到第二个单元格中。 这是将被 Ajax 请求更新的页面区域。
- 对于 Select Type,选择 Box ,并点击 OK。
图 13. 添加一个 Panel-Group Box
调整 Panel 属性
- 选择面板,并切换到 Properties 视图。
- 确保 hx:panelBox 被选中。
- 输入这些值:
-
宽度: 100%
-
高度: 100%
-
垂直: 高
-
水平:左
向面板中添加 Ajax 支持
- 选择 Panel Box,并切换到 Properties 视图。
- 确保 hx:panelBox 被选中。
- 选择 hx:panelBox 的 Ajax 。
- 选中 Allow Ajax updates 复选框。
- 点击 Submit 作为 Ajax 请求类型。
图 14. 选择 Ajax 请求类型
- 点击 File > Save All 保存您的变化。
通过使用组合框 onchange 事件初始化 Ajax 请求
- 选择 Combo Box 组件。
- 切换到 Quick Edit 视图(在 Properties 视图旁边)。
- 在 Quick Edit 视图中:
- 从左边的事件列表中选择 onchange 事件。
- 点击 Use predefined behavior 复选框。
- 在指定标签上选择激活 Ajax behavior action。
- 选择 box1 作为目标,然后按下 Tab 键。
- 点击 File > Save All 保存您的工作。
图 15. 使用onchange 事件初始化 Ajax 请求
将 largestCitiesSB 关联记录列表绑定到组合框
- 从 Page Data 页签中,展开 Relational Records > largestCitiesSB (Service Data Object) > largestCitiesSB(LARGESTCITIES)。
- 将 LARGEST_CITY(String) 拖拽到组合框。 组合框在运行时填入最大的城市。
将 All Cities 作为一个额外选择添加到组合框中
- 切换到组合框 Properties 视图。
- 点击 Add Choice,并输入这些值:
-
标签:
All Cities (All Cities 显示数据库中所有城市的信息。)
-
值:
% (% 是一个 SQL 通配符。)
- 切换到组合框 Properties 视图。
- 选择 All Cities,并点击 Move Up。
将 largestCityVar 变量绑定到组合框
- 从 Page Data 页签中,展开 Scripting Variables > sessionScope。
- 将 largestCityVar 拖拽到组合框。 此变量将会使用组合框的值进行更新(或者是当选定一个特定城市时用最大城市的名字,或者是当所有城市被选择时用 % 通配符)。
组合框属性现在应当如图 16 所示。
图 16. 更新的组合框属性
将 largestCityPopulationSB 关联记录列表添加到 Panel-Box
- 从 Page Data 页签中,展开 Relational Records > largestCityPopulationSB (Service Data Object)。
- 将 largestCityPopulationSB (LARGESTCITIES) 拖拽到 Panel-Box,这样您就可以显示所选择城市的信息了。
- 编辑标签(通过点击每个标签内部),如表 1 所示(也参见图 17):
表 1. 按以下次序编辑标签
| 列名 | 标签 | 控制类型 |
|---|
| 等级 | 等级 | 输出字段 |
|---|
| LARGEST_CITY | Largest City | 输出字段 |
|---|
| STATE | State | 输出字段 |
|---|
| POPULATION | Population | 输出字段 |
|---|
图 17. 编辑标签
- 点击 Finish 关闭 Configure Data Controls 窗口。
替换表格中的每一行的背景颜色
- 点击 Display options 页。
- 确保 Row classes 显示 rowClass1,rowClass2(参见图 18)。 这些是两个 CSS 类,由一个逗号分开,有不同的背景颜色。 这些值通常在项目内部的样式文件 stylesheet.css 中定义。
图 18. 用于替换行演示的 CSS 类
- 从 Classes 列中删除 columnClass1 项,因为当 CSS 被应用到表格中时,columnClass 覆盖了 rowClasses。
图 19. 删除 columnClass1 项
- 选择 File > Save All 保存您的变化。 您的页面现在看起来应该如图 20 所示。
图 20. 修改页面
就这样样吧。 您准备好测试此页面并观察其行为。
测试页面
- 在 WeatherForecastProject/WebContent 下,右键单击 comboBoxExample.jsp 文件,并选择 Run As > Run on Server。
- 选中 Set server as project default,并点击 Finish。
- 等待服务器启动和显示 comboBoxExample.faces 页面。
当页面显示出来时,您可能注意到的第一件事情是,表格是空的。 然而,组合框显示了一个城市的名字(Austin)。 我们下一步将处理此问题,但是首先,注意到有其它行为。
图 21. 测试页面
- 点击组合框,并选择 Chicago 作为城市。
- 再次点击组合框,并选择 Austin 作为城市。 注意,会显示有关 Chicago 的信息。
图 22. 测试页面: 2
- 再次点击组合框,并选择 Chicago 作为城市。 注意,会显示有关 Austin 的信息。
图 23. 测试页面: 3
 |
为何是此行为?
在 largestCityPopulationSB 关联记录列表中的数据将信息缓存起来以改善性能。 当您从一个页面浏览到另一个页面时,缓存机制工作在一种标准环境中。 然而,当使用 Ajax时,会引起这种行为。
|
|
关闭 largestCityPopulationSB 关联记录列表
注意:
关联记录列表没有属性来设置或重置缓存。 相反,您需要编辑页面编码来关闭它。
- 关闭 comboBoxExample.faces 页面,点击其页签上的 X 。 您将被切换回 comboBoxExample.jsp 视图。
- 右键点击 comboBoxExample.jsp 页面内部,并选择 Edit Page Code 以打开 ComboBoxExample.java 文件。
- 从 Edit 下拉菜单中,点击 Edit > Find/Replace。
- 在搜索内容中,输入
List getLargestCityPopulationSB(),然后点击 Find。
- 通过添加两个斜杠标记,输入注释取消
(largestCityPopulationSB == null) 判断语句: //. 通过每次运行时强制使用 doLargestCityPopulationSBFetchAction() 方法,这将关闭缓存。 代码 getLargestCityPopulationSB() 应当如列表 1 所示。
列表 1. 编辑页面代码以关闭缓存
public List getLargestCityPopulationSB() {
// if (largestCityPopulationSB == null) {
doLargestCityPopulationSBFetchAction();
// }
return largestCityPopulationSB;
}
|
- 关闭 ComboBoxExample.java 文件。
- 点击 File > Save All 保存您的工作。
再次测试页面
- 在 WeatherForecastProject/WebContent 下,右键单击 comboBoxExample.jsp 文件,并选择 Run As > Run on Server。
- 等待服务器启动和显示 comboBoxExample.faces 页面。
- 当页面显示出来时,点击组合框,并选择 Chicago 作为城市。 注意,这次会实际显示有关 Chicago 的信息。
初始化 sessionScope 变量
现在,您已经解决了缓存问题,让我们处理一下其它问题,其显示在启动时相应于组合框中信息的城市有关信息。
要在页面启动时初始化 largestCityVar,我们编辑 comboBoxExample.jsp 的页面代码,并修改 getLargestCitiesSB() 方法。
 |
问题原因
组合框的值使用 largestCityVar,并且其中的值来自于关联记录列表 largestCitiesSB 的 Largest_City 元素。 显示 City 信息的关联记录列表 largestCityPopulationSB 具有一个使用 largestCityVar 的过滤器。
问题是,会话范围变量 largestCityVar 没有初始化,并且在 JSP 页面启动时一直是空值。 这就是 largestCityPopulationSB 在启动时没有显示任何信息的原因。
|
|
使用 Largest_City 的第一个 SDO 元素的值来初始化 largestCityVar :
- 关闭 comboBoxExample.faces 页面,点击其页签上的 X 。 您将被切换回 comboBoxExample.jsp 页面。
- 右键点击 comboBoxExample.jsp 页面内部,并选择 Edit Page Code 以打开 ComboBoxExample.java 文件。
- 从 Edit 下拉菜单中,点击 Edit > Find/Replace。
- 在搜索内容中,输入
List getLargestCitiesSB(),然后点击 Find。
- 将列表 2 的代码添加到方法(参见资源了解更多有关 SDO 和 DataObject 的内容)中:
列表 2. 使用第一个 SDO 元素的值初始化 largestCityVar
if (largestCitiesSB == null)
{ doLargestCitiesSBFetchAction();
// Add the following code to initialize the "largestCityVar" variable.
// +++ Start of Added Code
if (getSessionScope().get("largestCityVar") == null && largestCitiesSB != null) {
// Get the first Object
DataObject myfirstObject = (DataObject) largestCitiesSB.get(0);
// Assign the first SDO value for element LARGEST_CITY to the variable.
getSessionScope().put("largestCityVar", myfirstObject.get("LARGEST_CITY"));
}
// +++ end of Added Code
}
return largestCitiesSB;
}
|
- 关闭 comboBoxExample.java 文件。
- 再次点击 File > Save All 保存您的变化。
再次测试页面
- 在 WeatherForecastProject/WebContent 下,右键单击 comboBoxExample.jsp 文件,并选择 Run As > Run on Server。
- 等待服务器启动和显示 comboBoxExample.faces 页面。
注意,在启动时显示了相应于组合框入口的信息。
- 点击组合框,并选择 All Cities。 现在,您将会看见前 20 个城市的列表以及它们的信息。 这就是 largestCityVar 为什么使用 % 匹配符作为其值的原因。 因此,Where SQL 语句显示:
where LARGEST_CITY LIKE %。 另外也要注意,在表中的交互行背景颜色。 关闭 comboBoxExample.faces。
 |
可选步骤
如果您想要页面在启动时显示一个特定城市(例如,纽约)的信息,或者是显示所有城市的信息,对于第一种情况,您需要初始化largestCityVar 的值为 New York,对于第二种情况,您需要初始化 largestCityVar 的值为 %。
例如,这是纽约的 getLargestCitiesSB() 代码:
// Add the following code to initialize the "largestCityVar" variable.
// +++ Start of Added Code
if (getSessionScope().get("largestCityVar") == null && largestCitiesSB != null)
{// Assign New York to the variable.
getSessionScope().put("largestCityVar", "New York");}
// +++ end of Added Code |
这是带有 % 通配符的所有城市的代码:
// Add the following code to initialize the "largestCityVar" variable.
// +++ Start of Added Code
if (getSessionScope().get("largestCityVar") == null && largestCitiesSB != null)
{// Assign % to the variable.
getSessionScope().put("largestCityVar", "%");}
// +++ end of Added Code |
|
|
- 关闭 comboBoxExample.jsp 页面。
将一个 Data Tree JSP 页面添加到应用程序中
天气预测应用程序的这一部分显示了州中一个给定城市的 10 天的天气预报。
在本章中,您将完成以下七个主要步骤:
- 使用 JavaServer™ Faces 技术创建第二个 JSP 页面。
- 创建会话范围变量。
- 创建关联记录列表。
- 向 JSP 页面添加这些控件和 Ajax 支持。
- 表
- 输入隐藏组件
- Data Tree
- 面板组框
- Tabbed 面板
- 关闭关联记录列表缓存
- 访问州明细情况
- 部署和测试天气预测应用程序。
创建 dataTreeExample.jsp JSP 页面
首先,您将使用 Java™Server Faces 技术创建您的第二个 JSP 页面。 此页面将会使用一个 Data Tree 在一个层次视图中显示所有的州和城市。 其将使用 Panels-Tabbed JSF 组件。 第一个面板将在一个关联记录列表上显示所选择城市的 10 天预报。 第二个面板将显示其状态的详细内容。
开始之前,停止服务器:
- 在 Servers 视图中,右键单击 WebSphere Application Server v6.1,并且选择 Stop。
重要:
与 Rational Application Developer 包括在一起的嵌入式 Derby 数据库,只允许同时有一个活动连接。 相反,如果您实用 IBM DB2®,就不会有此限制。 因此,当您需要创建或修改关联记录列表时,您必需停止 WebSphere Application Server,停止其数据库连接。
按以下步骤创建 JSP 页面:
- 在 Web 透视图中,右键点击 WeatherforecastProject,然后选择 New > Web Page 以启动 New Page 向导。
- 对于文件名,输入
dataTreeExample.jsp。
- 在 Basic Templates 下,选择 JSP。
- 点击 Options,选择 JavaServer Faces。
- 单击 Close。
- 点击 Finish。
图 24. 创建第二个 JavaServer 页面
文件 comboBoxExample.jsp 在 WeatherForecastProject/WebContent 下被创建。 在 Rational Application Developer 打开页面意以后,您就准备好设计此页面了。
创建 sessionScope 变量
- 创建一个 sessionScope 变量,名为 stateVar
- 从 Web 透视图中,点击位于左下角区域的 Page Data 页签,并展开 Scripting Variables。
- 右键点击 sessionScope,然后选择 New > Session Scope Variable。
- 对于 Variable 名称,输入
stateVar。
- 对于 Type,输入
java.lang.String。
- 点击 OK。
- 创建一个 sessionScope 变量,名为 cityVar
- 遵循同样的指导,创建另一个 sessionScope 变量,名为 cityVar,类型为
java.lang.String。
创建关联记录列表
您将创建两个关联记录列表。
创建一个关联记录列表,名为 stateCitiesSB。
- 从 Page Data 视图中,其位于 Web 透视图中的左下区域,右键点击 Relational Records,并选择 New > Relational Record List。
- 名称输入
stateCitiesSB。
- 点击 Next。
- 如果您看到 Database Authorization 窗口:
- 点击 OK。
- 点击 New。
- 选择 Use an existing connection。
- 选择WeatherForecastDB,并点击Next。
- 对于 User ID,保留为 Weather。
- 保留 Password 字段为空。
- 点击 Next。
- 点击 Finish。
- 在 Table 下,向下滚动,展开 WEATHER,选择 STATES。
- 点击 Next。
- 点击 None 取消列的选择。 您将会注意到,只有 STATE 仍然被选中,因为它是主键。
- 在 Tasks 下,点击 Add another database table through a relationship。
- 选择 WEATHER.STATES <- WEATHER.STATESANDCITIES。
图 25. 通过一个关联关系添加另一个数据库表
- 点击 Finish。
- 展开 Relation:
STATES_STATESANDCITIES > STATESANDCITIES。
- 确保 LARGEST_CITY: String 被选中。
- 点击 Finish。
图 26. 创建 stateCitiesSB 关联记录列表
创建另一个关联记录列表,名为 tenDayForecastSB
注释:
这次,您将应用一个过滤器,仅选择那些符合所选中城市和州的记录,其在 cityVar 和 stateVar sessionScope 变量中指定。
- 从 Page Data 页签中,其位于 Web 透视图中的左下区域,右键点击 Relational Records,并选择 New > Relational Record List。
- 输入
tenDayForecastSB 作为名称。
- 点击 Next。
- 在 Table 下,向下滚动,展开 WEATHER,选择 TENDAYFORECAST。
- 点击 Next。
- 在 Tasks 下,点击 Filter results。
- 点击加号(+)。
- 对于 Column,选择 STATE =。
- 选择 Variable,然后点击椭圆形按钮(三个点: ...).
- 展开 sessionScope,并选择 stateVar。
- 点击 OK。
- 再此点击 OK。
- 再次点击加号(+)。
- 对于 Column,选择 CITY =。
- 选择 Variable,然后点击椭圆形按钮(三个点:
- 展开 sessionScope,并选择 cityVar。
- 点击 OK。
- 点击 OK。
- 单击 Close。
- 点击 Finish。
图 27. 在关联记录列表上应用过滤器
向 JSP 页面添加组件和 Ajax 支持
向 JSP 页面添加一个表:
- 使用工具板拖拽一个表到 HTML Tag 下的页面上。 指定这些值:
-
行: 2
-
列: 2
-
表格宽度: 100%
-
边框宽度: 0 像素
- 点击 OK。
- 在表的 Properties 视图中,选择 table 页节点,并指定布局(参见图 28):
-
对齐: 左对齐(确保表的页节点仍然被选中)。
-
宽度: 100%
-
高度: 100%
图 28. 向 JSP 页面上添加一个表
- 在单元格的 Properties 视图中,将光标放在左上角单元格上,指定这些值:
-
水平: 左
-
垂直:高
-
宽度: 20%
-
自动换行: 未选中
- 将光标放在右上角单元格上,并指定如下格式:
-
水平:左
-
垂直:高
-
宽度: 80%
-
自动换行: 未选中
- 点击 File > Save All 保存您的工作。
向 JSP 页面上添加两个隐藏输入的组件:
- 在 Enhanced Faces Components 下,拖拽到一个 Input-Hidden 组件到 bottom-left 单元格中。
- 将 Properties 中的 ID 更改为
txtState。
- 仍然在 Enhanced Faces Components 下,拖拽到另一个 Input-Hidden 组件到 bottom-right 单元格中。
- 将 Properties 中的 ID 更改为
txtCity。
将脚本变量绑定到 Input 组件
- 从 Page Data 视图中,展开 Scripting Variables > sessionScope。
- 拖拽 stateVar 到 txtState。
- 拖拽 cityVar 到 txtCity。
- 点击 File > Save All。
注意:
- 您将使用隐藏输入组件来更新脚本变量,如下面的步骤所概述。
- 一些组件,例如 Input-Hidden,缺省在工具板上是隐藏的。 要在一个工具板中选择一个隐藏的组件:
- 右键点击 Palette 视图内部,并选择 Customize。
- 对于每一个您想要在工具板上显示的组件,清楚 Hide 复选框。
向 JSP 页面田间一个 Data Tree
注意:
一个 Data Tree 组件使用一个层级列表(List of States > State > City)显示每个州下的城市。
- 在 Enhanced Faces Components 下,拖拽一个 Data Tree 到 top-left 单元格。
- 当您看到对话框,问:“This control requires new project resources. Copy them now?”,点击 Yes。
- 从 Data Tree Properties 视图(图 29)中,选择 odc:tree 页节点,指定以下这些值:
绑定关联记录列表 statesCitiesSB 到 Data Tree
- 从 Page Data 页签中,展开 Relational Records > statesCitiesSB (Service Data Object)。
- 拖拽 statesCitiesSB (STATES) 到 Data Tree。
图 29. Data Tree Properties 视图
- 从 Data Tree Properties 视图中,点击 Tree Node List 页节点。
- 在 ";Select the nodes to display" 下,选择 Root。
- 对于 Label 值,输入
List of States。
- 在 "Select the nodes to display" 下,点击 + 符号,展开 State List 节点。
- 选择 stateCitiesSB,并确保 STATE 显示在 Label 值中。
- 展开 stateCitiesSB 节点。
- 选中 STATES_STATESANDCITIES 节点。
- 从 Label 值的下拉菜单中,选择 LARGEST_CITIES。
图 30. Data Tree Node 列表
- 点击 File > Save All 保存您的工作。
图 31 显示了 Data Tree 应当显示的样子。
图 31. Data Tree 层级结构
在图 31 中,List of States 是 Root 节点。 节点 stateCitiesSB 保留了 States 的名字,并且节点 STATES_STATESANDCITIES 保留了运行时的 Largest Cities 的名字。 其相应于图 32 中的关联记录列表 stateCitiesSB 层级结构。
图 32. 关联记录列表 stateCitiesSB 层级结构
当您在 Data Tree 中点击一个城市的名称时,您需要捕获其相应的 State (父节点),因为 State 和 City 都被作为参数来访问,更新关联记录列表的 tenDayForecastSB 过滤器,通过使用变量 stateVar 和 cityVar。
注意:
要得到父节点,您将添加另一个属性到 STATES_STATESANDCITIES 节点,其通过使用 odc:treeColumnData 页签。
添加一个属性到 Data Tree
- 从 JSP 页面中,page, 选择 Data Tree。
- 从 Properties 视图中,确保 <odc:tree> 被选中。
- 选中 Display tree as a table。
- 添加以下两个标签:
-
标签: Column 1, Width: 20
-
标签: Column 2, Width: 20
- 在 Properties 视图中,点击 Tree Node List 页节点。
- 在 "Select the nodes to display" 下,展开列表 States > stateCitiesSB。
- 选择 STATES_STATESANDCITIES 节点(参见图 33)。
- 在 "Column data" 下,点击 Add 增加一个属性。
- 选择 STATE,然后按下 Tab 键。
图 33. 增加 State 作为一个属性
- 从 Properties 视图中,再次点击 <odc:tree>。
- 取消选中 Display tree as a table。
- 在以下的消息上,点击 Yes : "Do you really want to remove the
TreeTable tag and its content from this table?"
注意:
通过取消选中 "Display tree as a table",在 Properties 视图下的 STATES_STATESANDCITIES 节点的 Column 数据将不再显示 STATE。 然而,属性页签被隐藏,并且将保留 STATE 值。 它将通过 Tree 节点事件处理器(在本例中,将是onhighlight 事件)中的 JavaScript 来访问,您将在以后会看到。
您可以验证,属性已经被通过切换到 JSPSource 页签添加进来了。 在图 34 中的屏幕截屏显示了此代码被添加上了:
<odc:treeColumnData id=":columnData1": attributeName=":STATE":></odc.treeColumnData>
|
图 34. 验证代码被添加上
- 点击 File > Save All 保存您的工作。
添加一个 Panel-Group Box 到 JSP 页面上
- 拖拽一个 Panel-Group 框到 top-right 单元格中。 这是将被 Ajax 请求更新的页面区域。
- 对于 Type,选择 Box ,并点击 OK。
调整 Panel Properties
- 选择 panel,并切换到 Properties 视图。
- 确保 hx:panelBox 被选中,并指定以下这些值:
-
宽度: 100%
-
高度: 100%
-
垂直: 高
-
水平: 左
将 Ajax 支持添加到面板上
- 选择 panel,并切换到 Properties 视图(参见图 35)。
- 确保 hx:panelBox 被选中。
- 为
hx:panelBox 选择 Ajax 页节点。
- 点击 Allow Ajax updates 复选框。
- 点击 Submit 作为 Ajax 请求类型。
图 35. Properties 视图
- 点击 File > Save All。
初始化 Ajax 请求
使用 onhighlight 事件用于 STATES_STATESANDCITIES 节点,以初始化 Ajax 请求:
- 从 Data Tree 中,选择 STATES_STATESANDCITIES 节点。
- 切换到 Quick Edit 视图(在 Properties 视图旁边)。
- 在左边的事件列表中,选择 onhighlight 事件。
- 点击 Use predefined behavior 复选框。
- 在指定标签上选择激活 Invoke Ajax behavior 操作。
- 选择 box1 作为目标。
- 对于 Target,使用
form1:box1 替换 box1 ,并点击 Tab 键。
此操作的原因:
在 Rational Application Developer 的 7.0 版本中,您必需完全限定 Panel-Group Box 的 ID(不要使用 "box1",而使用 "form1:box1")。 否则,Ajax Submit 请求将不会正确工作。
- 点击 File > Save All。
- 点击 onhighlight 事件里的任何地方。
- 增加代码如列表 3 所示
列表 3. onhighlight 事件的代码
try {
var eobj = thisEvent.eobject;
var obj = document.getElementById("form1:txtCity");
var obj2 = document.getElementById("form1:txtSTATE");
if (obj && obj2) {
obj.value= eobj.eGet('LARGEST_CITY');
obj2.value = eobj.eGet('STATE');
}
}
catch (e) {
alert(e+": "+e.message);
} |
- 点击 File > Save All。
onhighlight 事件应当如图 36 所示。
图 36. onhighlight 事件的代码
onhighlight 事件当用户点击树节点时触发。 JavaScript 分派其值(在本例中是,the Largest City name),还有与节点(在本例中是,the associated State name)相关联的隐藏属性放在两个输入文本组件中: 分别是 txtState 和 txtCity。 变量 sessionScope stateVar 和 cityVar 都进行相应地更新。
- 切换到 JSP Source 页签,并验证代码(也可以参见图 37 中的屏幕输出):
<odc:treeNodeAttr
className="commonj.sdo.DataObject(DynWDO`stateCitiesSB`STATEANDCITIES)"
id="treenodeattr3" attributeName="LARGEST_CITY">
<odc:behavior event="onhighlight" id="behavior1"
behaviorAction="get" targetAction="form1:box1"
onActionFunction="return func_1(this event);"></odc:behavior>
|
图 37. odc:behavior 页签的工作区
向带有两个页签的 JSP 页面中添加一个 Panels-Tabbed 在组件
- 在 Enhanced Faces Components 下,从 Palette 中,拖拽一个 Panels-Tabbed 组件到 JSP 页面上的 Panel Box (box1)。
- 点击 Tabbed Panel 进行选择,然后点击 Properties视图。
- 选择 odc:tabbedPanel ,输入以下这些值:
- 取消选择 Show Next and Back buttons。
图 38. Panels-Tabbed Properties 视图
- 点击 Panel List 页节点,并修改 bfpanel1 和 bfpanel2 的标签,分别输入
Ten Day Forecast 和 State Details (参见图 39)。
图 39. 在 Panel List 页节点中修改 bfpanel1 和 bfpanel2
增加关联记录列表 tenDayForecastSB 到 Ten Day Forecast 页签中
- 在 JSP 页面中,点击 Ten Day Forecast 页签选中它。
- 从 Page Data 页签中,展开 Relational Records > tenDayForecastSB (Service Data Object)。
- 拖拽 tenDayForecastSB (TENDAYFORECAST) 到 Panels-Tabbed区域。
- 取消选中 TENDAYIDX。
- 编辑标签(通过点击每个标签内部),如表 2 所示,也参见图 40。
表 2. 按以下次序编辑标签
| 列名 | 标签 | 控制类型 |
|---|
| STATE | State | 输出字段 |
|---|
| CITY | City | 输出字段 |
|---|
| FORECASTDATE | Forecast Date | 输出字段 |
|---|
| FORECAST | Forecast | 输出字段 |
|---|
| TEMPERATURE | Temperature | 输出字段 |
|---|
| PRECIPITATION | Precipitation % | 输出字段 |
|---|
图 40. 编辑标签
- 点击 Finish 关闭 Configure Data Controls 窗口。
替换表格中的每一行的背景颜色
- 点击页节点 Display 选项。
- 确保 Row 显示 rowClass1,rowClass2。
- 从 Column 类中删除 columnClass1 项。
- 选择 File > Save All。
您的页面应当看起来如图 41 的屏幕截屏所示。
图 41. 修订页面
关闭缓存
如同在早先章节中所说明的,您需要关闭缓存以显示更新的城市选择。
关闭 tenDayForecastSB 缓存
- 右键点击 dataTreeExample.jsp 页面,并选择 Edit Page Code 以打开 dataTreeExample.java 文件。
- 从 Edit 下拉菜单中,点击 Edit > Find/Replace。
- 在搜索内容中,输入
List getLargestCitiesSB(),然后点击 Find。
- 使用注释符来注销
if (tenDayForecastSB == null) { 语句。 通过每次运行时强制使用 doTenDayForecastSBFetchAction() 方法,这将关闭缓存。 操作 getTenDayForecastSB() 应当如列表 4 所示。
列表 4. 关闭 tenDayForecastSB 缓存
public List getTenDayForecastSB() {
// if (tenDayForecastSB == null) {
doLargestCityPopulationSBFetchAction();
// }
return tenDayForecastSB;
} |
- 点击 Close 以关闭 Find/Replace。
- 关闭 DataTreeExample.java 文件。
- 通过点击 File > Save All 保存您的工作。
测试页面
重要:
在设计 JSP 页面的过程中,Data Tree 可能会丢失其配置。 总是确保 Data Tree 的 Tree Node List 反映了您之前所作的配置,并保存您的工作。
- 在 WeatherForecastProject/WebContent 下,右键单击 dataTreeExample.jsp 文件,并选择 Run As > Run on Server。
- 如果窗口 Disconnect ForecastWeatherDB 出现,点击 Finish 以关闭它。
- 等待服务器启动和显示 dataTreeExample.faces 页面。
- 点击 Data Tree 展开 Alabama。
- 单击 Birmingham。 数据表显示了该城市 10 天的天气预报。
访问 State Details
我们将使用有关所选择州的详细内容来填充 State Details 页签
您将执行这两个主要的任务:
- 创建包含 STATES 和 STATESANDCITIES 页签的关联记录列表。 您将基于所选择的州过滤信息。
- 将 Java 代码添加到 dataTreeExample.jsp 页面代码,以访问关联记录列表元素。
提示:
本文向您展示了如何从一个关联记录列表通过编程方式访问数据元素。 但是,您可以使用一个关联记录作为一个替代,来显示不包含任何代码的信息。
- 开始之前,停止服务器: 在 Servers 视图中,右键单击 WebSphere Application Server v6.1,并且选择 Stop。
- 下一步,创建一个关联记录列表,名为
stateDetailsSB。
- 从 Page Data 视图中,其位于 Web 透视图中的左下区域,右键点击 Relational Records,并选择 New > Relational Record List。
- 名称输入
stateDetailsSB。
- 点击 Next。
- 对于 User ID,保留为 Weather。
- 保留 Password 为空。
- 点击 OK。
- 在 Table 下,向下滚动,展开 WEATHER,并选择 STATES。
- 点击 Next。
- 在 Tasks 下,点击 Add another database table through a relationship 链接。
- 选择 WEATHER.STATES <- WEATHER.STATESANDCITIES (参见图 42)。
图 42. 选择一个关联关系
- 点击 Next。
- 然后点击 Finish。
注意:
因为您在本例中没有明确地命名关联关系,Rational Application Developer 会自动地提供名称: STATES_STATESANDCITIES 。 如果您想要重新命名此关联关系,只需要简单地选择它,右键点击,并从下拉菜单中选择 Rename Relationship。 关联关系的名称将显示在关联关系标签 name=: 下的 stateDetailsSB.xml 文件中
<relationships childKey=";//_cnnew1@tables.1/@foreignKeys.0";
parentKey=";//@tables.0/@primaryKey"; name=";STATES_STATESANDCITIES";
exclusive=";false";/>
|
您可以找到 WebContent/WEB-INF/wdo 下的 stateDetailsSB.xml 文件。
- 现在,在 Tasks 下,点击 Filter results。
- 选择STATES,并点击 + 符号。
- 在 Tasks 下,点击 Filter results。
- 点击加号(+)。
- 选择 STATES,并从 Column 的下拉菜单中,选择等于符号(=)。
- 选择 Variable,并点击带有三个点的按钮(. . . ).
- 展开 sessionScope,并选择 stateVar。
- 点击 OK。
- 再此点击 OK。
- 单击 Close。
- 然后点击 Finish。
向 dataTreeExample.jsp 页面中添加 Java 代码
- 右键点击 dataTreeExample.jsp 页面,并选择 Edit Page Code 以打开 dataTreeExample.java 文件。
- 在
getSDOConnectionWrapper()method 的末尾,输入在列表 5 中所显示的代码。
列表 5. 添加到 dataTreeExample.jsp 页面中的代码
: : : return SDOConnectionWrapper; } : :
// Add this code below public String getStateInfo() {
String stateInfo = "";
List stateList = getStateDetailsSB();
if (stateList.size() != 0) {
try {
DataObject graph = getStateDetailsSBMediator().getGraph(getStateDetailsSBParameters());
DataObject states = graph.getDataObject("STATES.0");
String strState = states.getString("STATE");
String strStateNickName = states.getString("STATE_NICKNAME");
String strCapital = states.getString("CAPITAL");
String strEstimatedPoplulation = states.getString("ESTIMATED_2006_POPULATION");
String strLargestCity = states.getDataObject("STATES_STATESANDCITIES").
getString("LARGEST_CITY");
stateInfo = "The nick name for the state of " + strState +
" is " + strStateNickName + ".
The estimated 2006 population is " + strEstimatedPoplulation + ".
Its largest city is " + strLargestCity + "
and its capital is " + strCapital + ".";
} catch (Throwable e) {
logException(e);
}
}
return stateInfo;
} |
- 保存您的工作: File > Save All。
注意:
- 以上代码是一个例子,向您展示了如何在另一个 DataObject 对象中访问一个 DataObject。 关联记录列表
stateDetailsSB 有一个过滤器,选择那些只属于在 stateVar 中定义的状态的记录。 代码 getStateInfo() 使用代码 "DataObject states = graph.getDataObject("STATES.0");" 访问 DataObject STATES。 此语句通过调用 states.getString("CAPITAL"),提供了对 STATES(例如,CAPITAL)中的不同元素的访问。 但是,您也需要访问所选择州的最大城市的名称。 "LARGEST_CITY" 是属于 STATESANDCITIES 的一个元素。
- DataObjects 可能包含其它 DataOjbects。 在本例中,stateDetailsSB 包含 STATES 和 STATESANDCITIES,它们通过 STATES_STATESANDCITIES 关联关系进行关联。 代码
";states.getDataObject(";STATES_STATESANDCITIES";).getString(";LARGEST_CITY";));"; 访问 ";LARGEST_CITY";,其是第二个 DataObject 中的一个元素。
- 访问元素是区分大小写的。 要查看
stateDetailsSB 元素,打开 WebContent/WEB-INF/wdo 下的 stateDetailsSB.xml 文件。
关闭关联记录列表 stateDetailsSB 缓存
- 从 JSP 页面上的 Edit 下拉菜单中,点击 Edit > Find/Replace。
- 在搜索内容中,输入
List getStateDetailsSB(),然后点击 Find。
- 使用注释符来注销
if (stateDetailsSB == null) { 语句。 通过每次运行时强制使用 doStateDetailsSBFetchAction() 方法,这将关闭缓存。
操作 getStateDetailsSB() 应当如列表 6 所示。
列表 6. 编辑页面代码以关闭缓存
public List getStateDetailsSB() {
// if (stateDetailsSB == null) {
doStateDetailsSBFetchAction();
// }
return stateDetailsSB;
} |
- 点击 Close 以关闭 Find/Replace。
- 关闭 DataTreeExample.java 文件。
- 选择 File > Save All 保存您的工作。
将 stateInfo 添加到 JSP 页面
- 点击 State Detail 页签。
- 从 Page Data 视图中,展开 Page Bean。
- 将 stateInfo (java.lang.String) 拖拽到 State Detail 页签。
- 在 Label 下,删除 StateInfo (将其设为空的)。
图 43. 将 stateInfo 添加到 JSP 页面
- 点击 Finish。
- 点击 File > Save All。
再次测试页面
注意:
如同在前面所提到的,在设计 JSP 页面的过程中,Data Tree 可能会丢失其配置。 总是确保 Data Tree 的 Tree Node List 反映了您之前所作的配置,并保存您的工作。
- 在 WeatherForecastProject/WebContent 下,右键单击 dataTreeExample.jsp,并选择 Run As > Run on Server。
- 点击 Finish 以断开 WeatherForecastDB 的连接。
- 等待服务器启动和显示 dataTreeExample.faces 页面。
当页面显示出来时:
- 点击 Data Tree 选择一个城市。 注意,10 天的城市天气预报现在显示出来了。
- 点击 State Details 页签。 您将看到州的详细信息,包括最大城市的名称。
总结
本文介绍了如何在 Ajax 环境中使用各种 JSF 组件。通过执行逐步的练习和示范,您已经学习了如何设计出使用 Combo Box、Data Tree,Relational Record Lists 或 SDOs、Panels-Box,和 Panels-Tabbed 组件的应用程序。您还学习了访问来自包含另一个 DataObject 的 DataObject 的元素的技术。
参见参考资料来了解更多关于本文中使用的各种技术。
致谢
作者感谢 Yury Kats 提供的技术的帮助。Yury 是 IBM Rational Application Developer 团队的开发人员,致力于 JSF 实现、组件,和工具。他写过许多 developerWorks 的文章。
下载 | 描述 | 名字 | 大小 | 下载方法 |
|---|
| 示例中使用的数据库文件 | CreateWeatherForecastDatabase.zip | 5KB | HTTP |
|---|
参考资料 学习
获得产品和技术
讨论
关于作者  | |  | Sami Joueidi 持有电子工程的硕士学位。他是一名 IBM 认证架构师,并担任 IBM 架构委员会工作。作为 IBM Rational 团队的一员,他关注于软件架构管理。 |
对本文的评价
|