如果希望用户能够将某个页面加入书签,且该页面要求输入参数,则可以使用 URL 来传递这些参数。本教程介绍了如何动态地创建包含参数的 URL,以及如何通过可加入书签的页面来访问这些参数。
|
|
目录
|
![[]](/im/a.gif) |
 |
关于可加入书签的 URL
缺省情况下,通过 IDE 构建的 Web 应用程序使用 forward 分发机制从一个页面转换到另一个页面。这意味着 Web 应用程序的控制器将在内部实现新页面的转换,然后将响应(新的 Web 页)发送到浏览器。在浏览器真正知晓服务器端所发生的这一情况之前,它仍处于同一页面上。这就是为什么浏览器为当前页显示的 URL 仍是上一页的 URL 的原因。采用 forward 分发机制存在的一个问题是用户无法将页面加入书签。要返回到某个页面的唯一方法是:先导航到应用程序的起始页,然后再导航到所需的页面。
如果希望将某个页面加入书签,则可以使用 redirect 分发机制。通过使用 redirect 分发机制,Web 应用程序的控制器可以指示浏览器获取另一个 URL。这种解决方案只适用于页面不要求输入参数的情况。例如,如果页面显示的是特定人员 ID 的详细数据,则当用户使用已加入书签的 URL 访问该页时,该页将无法正常显示,因为它要求输入该人员的 ID。
如果希望用户能够将某个页面加入书签,且该页面要求输入参数,则可以使用 URL 来传递这些参数。本教程介绍了如何动态地创建包含参数的 URL,以及如何通过可加入书签的页面来访问这些参数。
设计起始页
首先创建一个起始页,并在该页上添加一个表组件。然后,使用“表布局”对话框配置该表,以便从 PERSON 数据库表中获取各项。此外,还应当为该表配置一个超级链接组件。
- 打开“服务器”窗口,确保捆绑的数据库正在运行。如果“Bundled Database 服务器”节点未带有绿色标记,请右键单击该节点,然后选择“启动 Bundled Database”。
-
创建一个新的 Web 应用程序,并将其命名为
BookmarkableLinks。
图 1 显示了在此部分中创建的页面。
图 1:起始页的设计 |
- 将一个“表”组件从组件面板的“基本”类别拖动到该页上,并将其
title 属性设置为 Travelers。
- 右键单击该表组件,然后从弹出式菜单中选择“表布局”。
- 在“表布局”对话框中,单击“添加数据提供器”。
- 在“添加数据提供器”对话框中,展开“数据源”> "Travel" >“表”,然后选择 "PERSON"。单击“添加”。
此时,“表布局”对话框中的“选定”列会显示该表的所有列。
- 在“选定”列中选择 "PERSON.FREQUENTFLYER",然后单击 "<" 按钮将其移动到“可用”列中。
- 在“表布局”对话框中,单击“新建”以添加一个新列。
- 在“列详细信息”部分中,对新列进行以下三处更改。请参见图 2。
- 删除“页眉文本”字段中的
tablecolumn4。
- 从“组件类型”下拉列表中选择
超级链接。
- 在“值表达式”文本字段中键入
Details。
图 2:“表布局”对话框 |
- 单击“确定”,关闭“表布局”对话框并更新表组件。
可视设计器将显示具有四列的表组件,其中最右侧的列包含 "Details" 超级链接组件。
创建可加入书签的 URL
接下来,需要设置超级链接组件的 url 属性,
以便使其包含人员 ID 参数。
- 在表组件中,单击其中一个 "Details" 超级链接。此操作将会选择所有的 "Details" 超级链接。
- 在“属性”窗口中,将其
url 属性设置为以下值:
/faces/Details.jsp?personId=#{currentRow.value['PERSON.PERSONID']}
URL 将指向在下一部分中创建的 Details 页。
创建 Details 页
现在将创建应用程序的第二页(称为 "Details")。在该页上,放置一个表组件,并将该组件与 TRIP 数据库表相连。
- 在“项目”窗口中,右键单击位于 "BookmarkableLinks" 节点下方的“Web 页”节点,然后选择“新建”>“页”。在“文件名”字段中键入
Details,然后单击“完成”。
图 3 显示了在此部分中设计的页面。
图 3:Details 页的设计 |
- 将一个“表”组件拖动到该页上,并将其
title 属性设置为 Trips。
- 右键单击该表,然后选择“表布局”。
- 在“表布局”对话框中,单击“添加数据提供器”。
- 展开“数据源”> "Travel" >“表”,然后选择 "TRIP"。单击“添加”。
“表布局”对话框中将填充 TRIP 数据库表的信息。
- 单击“确定”,关闭“表布局”对话框并更新表组件。
修改 SQL 查询
接下来,需要修改 tripRowSet 对象中的 SQL 查询,以便让该查询只返回指定人员的行程。
-
在“概要”窗口中,展开 "SessionBean1" 节点。右键单击 "tripRowSet" 节点,然后选择“编辑 SQL 语句”。
查询编辑器将以 "tripRowSet" 为标签出现在编辑区域中。
- 在查询编辑器的设计网格中,右键单击 "PERSONID" 行中的任意单元格,然后选择“添加查询条件”。
- 从“比较”下拉列表中选择
= 等于,并选中“参数”单选按钮。
- 单击“确定”。
在 "PERSONID" 行的 "Criteria" 列中将会出现 "=?",它在 SQL 查询中添加以下 WHERE 子句:
| 代码样例 1:SQL 查询中的 WHERE 子句 |
WHERE TRAVEL.TRIP.PERSONID = ? |
添加代码
对于此应用程序,Details 页中的表组件必须只显示对应于 Page1 页的表组件中所选择的人员姓名的行程信息。要创建这个主从关系,需要修改 Details 页的 prerender 方法,以通过请求参数获取人员 ID。
- 单击 "Details" 标签以打开该页。
- 单击 "Java" 按钮以查看 Details 页的源代码。
- 滚动到
prerender() 方法并添加下面以粗体显示的代码。
| 代码样例 2:通过请求参数获取人员 ID |
public void prerender() {
// Get the person id from the request parameters
String personId = (String)
getExternalContext().getRequestParameterMap().get("personId");
if (personId != null) {
try {
getSessionBean1().getTripRowSet().setObject(1, personId);
tripDataProvider.refresh();
} catch (Exception e) {
error("Cannot select trips for " + personId);
log("Cannot select trips for " + personId, e);
}
}
} |
- 按 Ctrl-Shift-F 组合键重新设置代码格式。
运行并测试应用程序
- 单击“运行主项目”按钮以部署并运行应用程序。浏览器将呈现 Page1,如图 4 所示。
图 4:已完成的起始页
|
- 单击 "Details" 链接以切换到 "Details" 页,该页将显示与所选择的游客相对应的行程。
- 通过浏览器菜单为该页创建一个书签。
- 打开一个新的浏览器窗口,然后使用刚创建的书签打开该页。
只要应用服务器和数据库服务器正在运行,就可以正常显示已加入书签的页面。 注意:对于一些浏览器来说,Details 页的 URL 中会含有会话 ID 参数。这不会导致在创建书签或重新创建书签时出现问题,因为会话 ID 随后将会失效,并且将创建新的会话。当确保浏览器已启用了 Cookie 时,就可以防止出现这种情况。
利用可加入书签的 URL 执行更多操作
以下是一些有关创建可加入书签的 URL 的其他提示:
- 要创建可加入书签的 URL,必须使用超级链接组件,而不是操作组件。如果选择让用户单击按钮,则可以使用图像超级链接组件和类似按钮的图像。
- 内部导航机制将
http://localhost:28080/Bookmarks/ 映射到 /faces,而 /faces 又将映射到已部署的项目的 web 目录中。如果页面位于 web 下的子目录中,请将该子目录添加到在 url 属性中指定的 URL,例如 /faces/foo/bar/Details.jsp。请确保 URL 以 /faces 开头,而不是 faces。
- 本教程直接在
url 属性中计算 URL。或者,也可以使用 getter 方法(该方法返回计算的 URL)在受管 Bean(例如页面 Bean 或会话 Bean)中添加属性,然后将 url 属性与此 Bean 属性绑定。
试试看。 在本教程中,使用了 getRequestParameterMap 方法来获取请求参数。另一种获取请求参数的方法是:利用受管 Bean 的属性设置。请尝试执行以下步骤来了解如何使用这种方法。
- 在 Details 页的 Java 源代码中,添加下面的代码以创建 personId 属性:
| 代码样例 3:创建 personId 属性 |
private String personId;
public void setPersonId(String personId) {
this.personId = personId;
}
public String getPersonId() {
return this.personId;
}
|
-
在“项目”窗口中,双击“受管 Bean”节点以便在 XML 编辑器中打开该文件。修改 managed-beans.xml 的输入内容,以使 Details Bean 包含下面以粗体显示的代码。
| 代码样例 4:managed-beans.xml 的输入内容 |
<managed-bean>
<managed-bean-name>Details</managed-bean-name>
<managed-bean-class>bookmarkablelinks.Details</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>personId</property-name>
<value>#{param.personId}</value>
</managed-property>
</managed-bean>
|
请注意,变量名 param 对应于此请求的请求参数的映射。
- 在 Details 页中编辑
prerender 方法,并注释掉以下行:
String personId = (String) getExternalContext().getRequestParameterMap().get("personId");
删除查找 personId 请求参数的逻辑,因为通过在创建 Bean 时计算 #{param.personId} 表达式的值,已经插入了该参数的值。执行 try/catch 块中的代码,并且让该代码使用实例变量 personId 中的值,而不是 prerender() 方法的局部变量。 确保添加请求参数时使用 String 属性,即使可以很自然地认为该值是整数(这可能适用于人员的 ID)。虽然表达式计算试图进行正确的转换,但是如果无法成功转换所传入的值,它就会抛出异常。最好的方法是在 prerender 方法中处理转换问题。
另请参见:
更多的开发者资源:
有关为开发者提供的更多教程、文章、提示、论坛、更新和专家建议,请访问 Sun Developer Network (SDN) 上的 Java Studio Creator 开发者资源,网址为 http://gceclub.sun.com.cn/prodtech/javatools/jscreator/。
此页的最新修改时间:2006 年 4 月 14 日
|