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

js

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

使用 JavaBean 和 JSP 参数在 Web 页面之间传递数据
级别:入门
Brett McLaughlin(brett@oreilly.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="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="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="spacer.gif" width="1"
height="5"></td>
<td height="5"><img src="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 添加了更多的灵活性和功能。在那之前请好好读一下这些文章,到时候咱们网上见。

时间: 2024-08-25 03:44:20

JSP 最佳实践:组合 JavaBean 组件和 JSP 技术的相关文章

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

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

JSP最佳实践: 使用JSTL来更新JSP页面

简介:JSP 标准标记库(Standard Tag Library,JSTL)是一组以标准化格式实现许多通用的Web站点 功能的定制标记.在 JSP 最佳实践这一部分,Brett McLaughlin将向您介绍JSTL,阐述如何转变JSP页面 来使用高功能性的标记. JSP技术的优势之一在于其定制标记库工具.除了核心JSP标记,如 jsp:include 之外,定制标记库工 具使您能够创建唯一的标记来描述以站点或应用程序为导向的操作.一旦您创建了定制标记库(简称 taglib),当您扩展项目或转

JSP 最佳实践:用 jsp:include 控制动态内容

include|js|动态|控制 本文是 Java"知情人士"Brett McLaughlin 继第一篇 JSP 最佳实践文章后的后续文章,在文中,作者向您演示了如何扩展 JSP 技术中用于动态内容的包含功能.了解静态 include 伪指令和动态 jsp:include 元素之间的差异,搞清楚如何混合搭配这二者以获取最优性能.在新的 JSP 最佳实践系列的前一篇文章中,您了解了如何使用 JSP include 伪指令将诸如页眉.页脚和导航组件之类的静态内容包含到 Web 页面中.和服

JSP最佳实践: 用jsp:include控制动态内容

简介:本文是 Java Brett McLaughlin 继第一篇 JSP 最佳实践文章后的后续文章,在文中,作者向 您演示了如何扩展 JSP 技术中用于动态内容的包含功能.了解静态 include 伪指令和动态 jsp:include 元素之间的差异,搞清楚如何混合搭配这二者以获取最优性能. 在新的 JSP 最佳实践系列的前一篇文章中,您了解了如何使用 JSP include 伪指令将诸如页眉.页 脚和导航组件之类的静态内容包含到 Web 页面中.和服务器端包含一样,JSP include 伪

JSP最佳实践: 自定义标记中的错误处理

简介:在自定义标记中引用更多交互性的同时,也会增加错误出现的可能性,尤其是以非法参数形式 出现的错误.在本期的 JSP最佳实践中,Brett McLaughlin 向您展示了如何在源代码中捕获和忽略 IllegalArgumentException 异常. 在我们讨论 JSP 自定义标记的时候,我们一直都设法回避了错误处理的重要细节.在我们已经推出的 JSP 最佳实践系列的前面一半的文章中,大多数讲的都是 JSP 容器提供的功能,比如说 param . out 和 import 标记.在这些情况

JSP最佳实践: 为您的JSP标记创建自定义属性

简介:BrettMcLaughlin 继续他的 JSP 最佳实践系列,这次他将用一个属性来扩展自定义的时间戳标 记( lastModified ),这个属性让页面作者可以选择他们自己的时间戳格式. 上一期的 JSP 最佳实践介绍了在JSP页面中使用自定义标记库的基础知识.在那一期可以学到如何定 义简单的标记并通过标记库描述符(tag library descriptor,TLD)让其他 JSP 作者可以使用该标记. 在这个星期,我们将以您已经知道的有关自定义标记的知识为基础.我们上次采用的实例标

JSP最佳实践: 使用JSP include机制改进外观

简介:本文是新的 JSP 最佳实践系列文章的第一部分,它介绍了 JavaServer Pages include 机制. 请跟随 Java 编程专家 Brett McLaughlin 学习如何使用 include 将静态的头文件和脚注文件加入您的 网站或 Web 应用程序页面中. 欢迎阅读 Java 专区中最新的 最佳实践系列文章.如果您看过先前的系列文章,那么您会知道最佳实 践旨在让您快速了解各种 Java 技术的有用方面.这一系列的最佳实践专门讨论 JavaServer Pages(JSP

JSP最佳实践: 将自定义标记库打包

简介:将标记库存放在本地文件系统中的确有利于内部(in-house)开发和测试,但是这并非永远都 是好的解决方案.自定义标记库应该能够被广泛地访问,也就是说,必须以一种标准的和安全的方式来发 布它们.BrettMcLaughlin 解释了如何将您的自定义标记库打包到 JAR 文件,以便在任何 JSP 兼容的 Web 容器中更容易地维护.发布和安装它们. 到目前为止,我们在本系列中讲到的都是自定义标记库在本地文件系统中的情况,在这种情况下,我 们可以很容易地访问和操作这些自定义标记库.然而,虽然本

JSP最佳实践: taglib简介

简介:Scriptlet对于快而杂(fast-and-dirty)的编码来说是一种不错的选择,但是从长远来看,您需 要为您的JSP页面选择一种不那么杂乱的解决方案.在本期的 JSP最佳实践中,BrettMcLaughlin 向您展示 了如何将scriptlet转化成JSP自定义标记,然后将其用于您的JSP开发中. 在 JSP最佳实践的 上一期,您学习了一种基于scriptlet的技术,这种技术被用来将上次修改的时间 戳添加到JavaServer Page(JSP)文件中.不幸的是,比起它所提供的