JSP 最佳实践:组合 JavaBean 组件和 JSP 技术

80酷酷网    80kuku.com

  jsJSP 最佳实践:组合 JavaBean 组件和 JSP 技术

使用 JavaBean 和 JSP 参数在 Web 页面之间传递数据
级别:入门
Brett McLaughlin(brettoreilly.com)
作家,O'Reilly and Associates
2003 年 7 月

Web 架构设计师 Brett McLaughlin 演示了 JavaBean 组件和 JSP 技术的结合如何使您能够在 Web 页面之间存储并传递数据,以及这样做如何能实现更为动态的站点设计。
到目前为止,我们在 JSP 最佳实践 系列文章中着重讨论的都是较为基本的主题。在前两篇文章中,您学习了如何使用 JSP include 机制来将外部内容引入到您的网站或 Web 应用程序。我们使用了两种不同的 include 伪指令:静态 include 命令和动态 jsp:include 标记。

迄今为止,还无需创建父页面(在我们的示例中是一个网站主页面)和所包含内容之间的任何类型的通信。但是这种方案过于简单。当要对实际 Web 站点或 Web 应用程序接口进行编程时,您通常需要一种通信机制在父页面和所包含文件之间传递数据。例如,您的网站可能有一个标题或消息是源自主页面的,并需要将它提供给页面头或页面尾。在这篇文章中,您将学习如何在页面之间传递数据,以及如何在所包含的页面中使用该数据。

注:本系列文章中的所有最佳实践都基于 JavaServer Pages 技术。要运行其中任何一个实践示例,需要在本地机器或测试服务器上安装符合 JSP 技术的 Web 容器。您还需要使用文本编辑器或 IDE 来对 JSP 页面进行编码。

用于存储数据的 JavaBean 组件
让我们研究一下这样一个网站:其中的每个页面都有简短的“标语”(比如“Books: A shelf full of learning”或“CDs: Music worth listening to”)和标题。父页面(有时叫做主页面)确定了每个页面的标语,而页面头(包含的页面)要处理 HTML 以输出该标语。为使该方案工作,主页面必须能够将标语传递到页面头,而且页面头必须能够接受页标题并按请求显示它。

首先我们需要某种用于存储被传递数据的对象。碰巧的是(并非偶然)JavaBean 组件既适合该目的又与 JSP 技术非常匹配。bean 只需要用取值方法(accessor)和赋值方法(mutator)来处理数据。您可能从其它 Java 编程经历中得知,get() 是个取值方法,因为它访问数据,而 set() 是个赋值方法,因为它修改数据。

清单 1 显示了我们所需的那种 bean 的代码。PageHeaderInfo bean 包含了有关网站页面头的信息。

清单 1. PageHeaderInfo JavaBean

<![CDATA[
package com.newInstance.site.beans;

import java.io.Serializable;

public class PageHeaderInfo implements Serializable {

/** The title of the page */
private String pageTitle;

/** The slogan of the page */
private String pageSlogan;

public String getPageTitle() {
return pageTitle;
}

public void setPageTitle(String pageTitle) {
this.pageTitle = pageTitle;
}

public String getPageSlogan() {
return pageSlogan;
}

public void setPageSlogan(String pageSlogan) {
this.pageSlogan = pageSlogan;
}
}
]]>



对于第一个练习,请将该文件保存为 PageHeaderInfo.java,然后对它进行编译。接下来,将得到的类文件 PageHeaderInfo.class 放入 Web 应用程序的 WEB-INF/classes 目录。请确保包括了包层次结构,但是可随意更改包名。这个已编译类的示例路径如下:

$<TOMCAT-ROOT>/webapps/$<WEB-APP-NAME>/WEB-INF/classes/com/newInstance/
site/beans/PageHeaderInfo.class



可以使用类似于此的路径使该类可被 Web 应用程序中的 servlet、JSP 页面和其它类使用。如果到目前为止您按照描述的那样执行了所有步骤,那么现在可以将数据填充到 PageHeaderInfo bean 中,然后在各个 JSP 页面中检索它。

传递已存储的数据
在我们的网站方案中,页面头包含了将各个标语传递给不同页面的代码。您可能记得前一篇文章中提过,页面头(header.jsp)是个包含的文件,由 jsp:include 元素管理。因为我们使用的是动态 jsp:include 标记而非静态 include 伪指令,因此很容易将数据传递到页面头。jsp:param 元素提供了这项功能,可以将该元素嵌套在 jsp:include 元素中。清单 2 演示了如何使用这些元素将数据传递给站点主页面的 header.jsp 文件。

清单 2. 在 JSP 页面之间传递数据

<![CDATA[
<% page language="java" contentType="text/html" %>
<html>
<head>
<title>newInstance.com</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1" />
<link href="/styles/default.css" rel="stylesheet" type="text/css" />
</head>

<body>
<jsp:include page="header.jsp" flush="true">
<jsp:param name="pageTitle" value="newInstance.com"/>
<jsp:param name="pageSlogan"
value="Java and XML :: Turning theory into practice" />
</jsp:include>
<% include file="/navigation.jsp" %>
<jsp:include page="bookshelf.jsp" flush="true" />

<jsp:include page="/mt-blogs/index.jsp" flush="true" />

<% include file="/footer.jsp" %>
</body>
</html>
]]>



您可以看到,标题是作为标语传入的。

您或许已经注意到:设置用于传递数据的页面时实际上不必使用 JavaBean 组件,因为 bean 只用于接收数据。但是我总是先对 bean 进行编码,这是有道理的。JSP 参数名必须与 JavaBean 特性名相匹配,先对 bean 进行编码确保了您在对 JSP 页面进行编码时能正确设置这些参数名。

接收数据
对 JSP 参数和 JavaBean 特性进行编码并且将数据传递给 header.jsp 页面之后,该页面可以开始接收数据了。清单 3 显示了 header.jsp 页面。其中大部分代码是 HTML,但是请务必注意 JSP 语句,在您研究了代码之后我将对此进行说明。

清单 3. 将数据传递给其它 JSP 页面

<![CDATA[
<!-- Begin header section -->
<% page language="java" contentType="text/html" %>
<jsp:useBean id="pageHeaderInfo"
class="com.newInstance.site.beans.PageHeaderInfo">
<jsp:setProperty name="pageHeaderInfo" property="*" />
</jsp:useBean>

<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="91" height="50" align="right" valign="top"
bgcolor="#330066"><font color="#FFFFFF"><img
src="http://www.pushad.com/images/header-lions.gif"
width="90" height="60"></font></td>
<td colspan="3" align="left" valign="top"
bgcolor="#000000"><table width="100%" height="60" border="0"
cellpadding="0" cellspacing="0">
<tr>
<td width="261" rowspan="2"><img
src="http://www.pushad.com/images/header-title.gif" width="261" height="60"></td>
<td class="pagetitle" width="249" height="55" align="right"
valign="bottom"><jsp:getProperty name="pageHeaderInfo"
property="pageSlogan"/></td>
<td width="10" height="55"> </td>
</tr>
<tr>
<td height="5"><img src="http://www.pushad.com/images/spacer.gif" width="1"
height="5"></td>
<td height="5"><img src="http://www.pushad.com/images/spacer.gif" width="1"
height="5"></td>
</tr>
</table></td>
<td width="141" bgcolor="#000000">
<font color="#FFFFFF"> </font>
</td>
</tr>
<!-- End header section -->
]]>



第一段代码将该页面标识为 JSP 页面,然后声明该页面需要访问 PageHeaderInfo bean,这是通过使用 jsp:useBean 标记实现的。id 为 JSP 页面可以使用的 bean 设置了一个别名,class 是 bean 的全限定 Java 类名。jsp:useBean 标记中嵌套的是 jsp:setProperty 标记,它指定了该 bean(由其别名标识)应当使用任何请求数据设置所有可用的特性。这意味着对于 bean 中的每个特性(例如 pageTitle 和 pageSlogan),都要有一个匹配的请求参数。这些请求参数可以来自使用 Web 浏览器的客户机,也可以来自包含此 JSP 页面的其它页面。在本例中,仅有的请求数据就是由父页面创建的。对于我们的示例站点而言,主页面(index.jsp)发送 pageTitle 和 pageSlogan,它们分别被设置成“newInstance.com”和“Java and XML: Turning theory into practice”。

填充了 bean 的特性值之后,该页就可以使用此数据了。对于 header.jsp,这个用法是通过使用 jsp:getProperty 标记在该页面的下方完成的。jsp:getProperty 带有一个 name 参数(标识从哪个对象获取数据)和一个 property 参数(指定应当轮询该对象的哪个特性)。然后将该特性的值插入到页面的输出,接下来将该输出插入到父页面,结果产生了一个无缝的动态页面标语。就这么简单,您可以在 JSP 页面之间传递数据了!您可以将任意多的 bean 添加到 JSP 页面中,每个 bean 都可以有无限多的特性,连最复杂的请求数据都能满足。

管理更改
每个开发人员最烦的就是进行更改。恰恰当您按照希望的方式对 bean 进行编码,正确地设置了所有特性,并且 JSP 页面准备使用它们时,您的应用程序或站点需求却发生变化,就似乎不可避免地要进行更改。如果这些更改要求添加新特性(它们通常会如此),那么您必须编辑 JavaBean 源代码,重新编译它,并确保 JSP 可以访问这个新的 bean 类。但是在某些情况下,您或许什么都不用做。如果您的页面正在存储和接收不再使用的特性(也就是说,您不再指向给定的页面组件,即使它仍然存在于站点目录中),您或许可以让代码保留原样。事实上,我就碰到了这种情况!

我个人 Web 页面的 header.jsp 页面以前常常输出 HTML 站点的页面头。以前,该页面引入标题以便在页面的 head 的 title 元素中使用它。但是后来我对此做了更改,不再使用页面头 JSP 页面中的页标题。但是我不必费心地将 pageTitle 特性从 PageHeaderInfo bean 中除去;事实上,我甚至没有从大多数将该标题发送给头页面的 JSP 页面中除去 jsp:param 元素。我认为不值得花功夫去做,而且我知道让这些数据留在那也没什么坏处(再说我将来有一天可能还会需要它!)。因此,如果发现您的情况一样,请别紧张 - 将时间花在添加很酷的新功能比花在摆弄这种琐事上要有趣的多。

下一次
一旦您熟悉了在 JSP 页面之间传递数据,就请亲自尝试编写一些有用的 JavaBean 代码,并看看是否可以在自己的站点上使它们运行。通过摆弄这些 bean 以及 jsp:useBean、jsp:param 和 jsp:get/setProperty 构造,您应当能搞出一些很酷的东西!在下一篇“最佳实践”文章中,我将说明使用 JSP 为您的主站点引入外部内容的另一种方法。JSTL 标记模仿了友好的 include 标记,并且为 JSP 添加了更多的灵活性和功能。在那之前请好好读一下这些文章,到时候咱们网上见。



分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: