JSP 最佳實踐:組合 JavaBean 組件和 JSP 技術
2024-09-05 00:19:28
供稿:網友
jsp 最佳實踐:組合 javabean 組件和 jsp 技術
使用 javabean 和 jsp 參數在 web 頁面之間傳遞數據
級別:入門
brett mclaughlin([email protected])
作家,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 添加了更多的靈活性和功能。在那之前請好好讀一下這些文章,到時候咱們網上見。