使用定制化的標簽
盡管你可以在JSP頁面中植入Java代碼並在服務器方執行,但是,JSP也支持使用定制標簽來插入動態內容,它有一種機制可以讓你在JSP頁面中插入你自己的、與HTML類似的標簽。換句話說,你的JSP網頁能夠使用插入Java代碼的簡單標簽語法產生動態的內容。但定制標簽的用處不是很大。
創建一個定制標簽比在JSP網頁中使用簡單的scriptlet要復雜得多,因為定制標簽需要用幾個步驟來把你的Java組件和JSP代碼連接起來。不過,定制標簽在分發和重復使用的時候就非常簡單了。對定制標簽的支持將在JSP創建工具中實現。
在下面的例子中產生動態內容的JSP網頁就使用了定制標簽。注意,在這個例子中我們不再需要引入Java類、聲明變量或寫任何Java代碼:
<%@ taglib uri="/tlds/menuDB.tld" prefix="menu" %>
Today's Menu
Lunch
<%@ include file="lunch_menu.html" %>
Our Special of the Day
從上面的語句中我們可以看出,這個頁面明顯比前面的scriptlet例子要簡單許多,因為它沒有包含初始化對象和執行相應的方法。但是JSP網頁代碼僅僅只是一部分;對於每一個定制標簽,還包括下面的三個組件:
(1)包含定制標簽的網頁,比如說,上面的代碼片斷中就使用了insertCatchOfDay 的定制標簽。在使用定制標簽之前,頁面必須指定Taglib Directive來提供標簽庫描述符(對標簽定義)的位置。當執行定制標簽的時候,網頁還有代表性的定義了一個和多個標簽屬性(比如在這個例子中的“meal”)來確定動態內容。
(2)標簽庫描述符。它是一個定義了定制化標簽並把它和Tag Handler連接起來的XML文件。一個標簽庫描述符包含了標簽的不同屬性,相關Tag Handler的名稱(位置)以及JSP引擎需要處理定制標簽的其他信息。
(2)Tag Handler。 它是一個與定制標簽聯合執行操作的Java類。例如,在上面的insertCatchOfDay標簽中,Tag Handler就是執行數據庫查詢得到相應菜單項的Java類。
我們已經看到了一個使用定制標簽的JSP網頁,下面讓我們來看一看另外的兩個組件。
Tag Handler
tag handler是一個與servlet比較相似的Java類。但是servlet能夠執行Servlet接口,還能夠被HTML GET或POST請求所執行。tag handler也能夠執行一個標簽接口(javax.servlet.jsp.Tag)以及在定制標簽被JSP引擎處理的時候執行。
如果定制標簽包含了屬性,那麼tag handler就必須定義這些屬性以及每一個的get/set方法。例如,當定義上面insertCatchOfDay定制標簽的tag handler的時候,我們必須定義“meal”屬性和與它相關的get和set 方法:
private String meal = null;
public void setMeal(String s) {
meal = s;
}
public String getMeal() {
return meal;
}
Tag Library Descriptor
如果你所有的時間都在處理Java技術而不知道關於 XML方面的東西,那麼標簽庫描述符組件可能看起來會比較陌生。但是你也不需要擔心,因為你不需要學習一門新的編程語言。標簽庫描述符僅僅使用與HTML相似的標簽語法來定義定制標簽的名字和屬性,這更象定義一個對象。
下面的標簽庫描述符定義了insertCatchOfDay標簽。注意,這個文件定義了定制標簽的名稱,屬性和相關的Tag Handler類:
xml version="1.0" ?>
insertCatchOfDay
com.sun.CatchOfDayHandler
Queries menu database for the catch of the day。
meal
與定義屬性的名稱一樣,標簽庫描述符也能夠定義數據類型並指定其屬性(無論是否需要);在Tag Handler被執行之前,它允許JSP引擎去做某些錯誤檢查。還有其他的信息,比如說為了使用JSP創建工具,庫名和版本號也可以包含在標簽庫中。
更多的例子
在下面的例子中,第一個例子在JSP頁面中使用了HTTP請求對象 (HttpServletRequest) 來判斷用戶浏覽器的版本並從三個HTML頁面中的一個中返回相應的內容:
<%@ page language=="java" info="Example JSP #1" %>
<%! String agent; %>
<%
agent = request.getHeader("User-Agent");
if ( agent.startsWith("Mozilla/4.0") {
%>
<%-- Return content for 4.0 browsers --%>
<%@ include file="ver4.html" %>
<%
}
else if ( agent.startsWith("Mozilla/3.0") {
%>
<%-- Return content for 3.0 browsers --%>
<%@ include file="ver3.html" %>
<%
}
else {
%>
<%-- Return content for other/unknown browsers --%>
<%@ include file="other.html" %>
<%
}
%>
注意:此頁面無須聲明或初始化HTTP請求對象就可以直接對它進行訪問。請求和響應(HttpServletResponse)對象都能夠隱含地在JSP 頁面中使用。和servlet一樣,JSP頁面能夠使用請求對象從HTML窗體中獲得參數值。
<%@ page language="java" info="Example JSP #2" %>
<%@ include file="header.html" %>
<%! String selections[], info; %>
Here are your current selections:
<%
selections = request.getParameterValues("items");
if (selections != null) {
%>
<%
for(int x = 0; x < selections.length; x++) {
%>
<%= selections[x] %> : <%= db.getInfo(selections[x]) %>
<%
}
%>
<%
}
else {
%>
(no items selected)
<%
}
%>
<%@ include file="footer.html" %>
在這個例子中,當每一個參數值都被讀取以後,JavaBean組件便查詢所需要的信息。在JSP網頁中使用Bean這種方法可以容易地從數據庫中返回動態web內容。
結論
如果你正在尋找一種能簡便建立連接服務器方Java組件的web程序的方法,那麼JavaServer Page正是你所需要的。除了EJB,RMI,JDBC和JavaBean外,分離HTML表述代碼和web程序,也使得JSP網頁組織起來運行變得更容易了。事實上,由於web設計人員幾乎無須Java開發人員的幫助就可以建立JSP頁面,所以你再也不同擔心創建web網頁和寫HTML代碼了。
<全文完>