11.1 概述
JavaServer Pages(JSP)使得我們能夠分離頁面的靜態HTML和動態部分。HTML可以用任何通常使用的Web製作工具編寫,編寫方式也和原來的一樣;動態部分的代碼放入特殊標記之內,大部分以“<%”開始,以“%>”結束。例如,下面是一個JSP頁面的片斷,如果我們用http://host/OrderConfirmation.jsp?title=Core+Web+Programming這個URL打開該頁面,則結果顯示“Thanks for ordering Core Web Programming”。
Thanks for ordering
<I><%= request.getParameter("title") %></I>
JSP頁面文件通常以.jsp爲擴展名,而且可以安裝到任何能夠存放普通Web頁面的地方。雖然從代碼編寫來看,JSP頁面更象普通Web頁面而不象Servlet,但實際上,JSP最終會被轉換成正規的Servlet,靜態HTML直接輸出到和Servlet service方法關聯的輸出流。
JSP到Servlet的轉換過程一般在出現第一次頁面請求時進行。因此,如果你希望第一個用戶不會由於JSP頁面轉換成Servlet而等待太長的時間,希望確保Servlet已經正確地編譯並裝載,你可以在安裝JSP頁面之後自己請求一下這個頁面。
另外也請注意,許多Web服務器允許定義別名,所以一個看起來指向HTML文件的URL實際上可能指向Servlet或JSP頁面。
除了普通HTML代碼之外,嵌入JSP頁面的其他成分主要有如下三種:腳本元素(Scripting Element),指令(Directive),動作(Action)。腳本元素用來嵌入Java代碼,這些Java代碼將成爲轉換得到的Servlet的一部分;JSP指令用來從整體上控制Servlet的結構;動作用來引入現有的組件或者控制JSP引擎的行爲。爲了簡化腳本元素,JSP定義了一組可以直接使用的變量(預定義變量),比如前面代碼片斷中的request就是其中一例。
注意本文以JSP 1.0規範爲基礎。和0.92版相比,新版本的JSP作了許多重大的改動。雖然這些改動只會使JSP變得更好,但應注意1.0的JSP頁面幾乎和早期的JSP引擎完全不兼容。
11.2 JSP語法概要表 JSP元素 語法 說明 備註
JSP表達式 <%= expression %> 計算表達式並輸出結果。 等價的XML表達是:
<jsp:expression>
expression
</jsp:expression>
可以使用的預定義變量包括:request,response,out,session,application,config,pageContext。這些預定義變量也可以在JSP Scriptlet中使用。
JSP Scriptlet <% code %> 插入到service方法的代碼。 等價的XML表達是:
<jsp:scriptlet>
code
</jsp:scriptlet>
JSP聲明 <%! code %> 代碼被插入到Servlet類(在service方法之外)。 等價的XML表達是:
<jsp:declaration>
code
</jsp:declaration>
page指令 <%@ page att="val" %> 作用於Servlet引擎的全局性指令。 等價的XML表達是
<jsp:directive.page att="val"\>。
合法的屬性如下表,其中粗體表示默認值:
import="package.class"
contentType="MIME-Type"
isThreadSafe="true|false"
session="true|false"
buffer="size kb|none"
autoflush="true|false"
extends="package.class"
info="message"
errorPage="url"
isErrorPage="true|false"
language="java"
include指令 <%@ include file="url" %> 當JSP轉換成Servlet時,應當包含本地系統上的指定文件。 等價的XML表達是:
<jsp:directive.include
file="url"\>.
其中URL必須是相對URL。
利用jsp:include動作可以在請求的時候(而不是JSP轉換成Servlet時)引入文件。
JSP註釋 <%-- comment --%> 註釋;JSP轉換成Servlet時被忽略。 如果要把註釋嵌入結果HTML文檔,使用普通的HTML註釋標記<-- comment -->。
jsp:include動作 <jsp:include
page="relative URL"
flush="true"/> 當Servlet被請求時,引入指定的文件。 如果你希望在頁面轉換的時候包含某個文件,使用JSP include指令。
注意:在某些服務器上,被包含文件必須是HTML文件或JSP文件,具體由服務器決定(通常根據文件擴展名判斷)。
jsp:useBean動作 <jsp:useBean att=val*/> 或者
<jsp:useBean att=val*>
...
</jsp:useBean> 尋找或實例化一個Java Bean。 可能的屬性包括:
id="name"
scope="page|request
|session|application"
class="package.class"
type="package.class"
beanName="package.class"
jsp:setProperty動作 <jsp:setProperty att=val*/> 設置Bean的屬性。既可以設置一個確定的值,也可以指定屬性值來自請求參數。 合法的屬性包括:
name="beanName"
property="propertyName|*"
param="parameterName"
value="val"
jsp:getProperty動作 <jsp:getProperty
name="propertyName"
value="val"/> 提取並輸出Bean的屬性。
jsp:forward動作 <jsp:forward
page="relative URL"/> 把請求轉到另外一個頁面。
jsp:plugin動作 <jsp:plugin
attribute="value"*>
...
</jsp:plugin> 根據瀏覽器類型生成OBJECT或者EMBED標記,以便通過Java Plugin運行Java Applet。
11.3 關於模板文本(靜態HTML)
許多時候,JSP頁面的很大一部分都由靜態HTML構成,這些靜態HTML也稱爲“模板文本”。模板文本和普通HTML幾乎完全相同,它們都遵從相同的語法規則,而且模板文本也是被Servlet直接發送到客戶端。此外,模板文本也可以用任何現有的頁面製作工具來編寫。
唯一的例外在於,如果要輸出“<%”,則模板文本中應該寫成“<\%”。
12.1 JSP腳本元素
JSP腳本元素用來插入Java代碼,這些Java代碼將出現在由當前JSP頁面生成的Servlet中。腳本元素有三種格式:
表達式格式<%= expression %>:計算表達式並輸出其結果。
Scriptlet格式<% code %>:把代碼插入到Servlet的service方法。
聲明格式<%! code %>:把聲明加入到Servlet類(在任何方法之外)。
下面我們詳細說明它們的用法。
12.1.1 JSP表達式
JSP表達式用來把Java數據直接插入到輸出。其語法如下:
<%= Java Expression %>
計算Java表達式得到的結果被轉換成字符串,然後插入到頁面。計算在運行時進行(頁面被請求時),因此可以訪問和請求有關的全部信息。例如,下面的代碼顯示頁面被請求的日期/時間:
Current time: <%= new java.util.Date() %>
爲簡化這些表達式,JSP預定義了一組可以直接使用的對象變量。後面我們將詳細介紹這些隱含聲明的對象,但對於JSP表達式來說,最重要的幾個對象及其類型如下:
request:HttpServletRequest;
response:HttpServletResponse;
session:和request關聯的HttpSession
out:PrintWriter(帶緩衝的版本,JspWriter),用來把輸出發送到客戶端
下面是一個例子:
Your hostname: <%= request.getRemoteHost() %>
最後,如果使用XML的話,JSP表達式也可以寫成下面這種形式:
<jsp:expression>
Java Expression
</jsp:expression>
請記住XML元素和HTML不一樣。XML是大小寫敏感的,因此務必使用小寫。有關XML語法的說明,請參見《XML教程 》
12.1.2 JSP Scriptlet
如果你要完成的任務比插入簡單的表達式更加複雜,可以使用JSP Scriptlet。JSP Scriptlet允許你把任意的Java代碼插入Servlet。JSP Scriptlet語法如下:
<% Java Code %>
和JSP表達式一樣,Scriptlet也可以訪問所有預定義的變量。例如,如果你要向結果頁面輸出內容,可以使用out變量:
<%
String queryData = request.getQueryString();
out.println("Attached GET data: " + queryData);
%>
注意Scriptlet中的代碼將被照搬到Servlet內,而Scriptlet前面和後面的靜態HTML(模板文本)將被轉換成println語句。這就意味着,Scriptlet內的Java語句並非一定要是完整的,沒有關閉的塊將影響Scriptlet外的靜態HTML。例如,下面的JSP片斷混合了模板文本和Scriptlet:
<% if (Math.random() < 0.5) { %>
Have a <B>nice</B> day!
<% } else { %>
Have a <B>lousy</B> day!
<% } %>
上述JSP代碼將被轉換成如下Servlet代碼:
if (Math.random() < 0.5) {
out.println("Have a <B>nice</B> day!");
} else {
out.println("Have a <B>lousy</B> day!");
}
如果要在Scriptlet內部使用字符“%>”,必須寫成“%\>”。另外,請注意<% code %>的XML等價表達是:
<jsp:scriptlet>
Code
</jsp:scriptlet>
12.1.3 JSP聲明
JSP聲明用來定義插入Servlet類的方法和成員變量,其語法如下:
<%! Java Code %>
由於聲明不會有任何輸出,因此它們往往和JSP表達式或Scriptlet結合在一起使用。例如,下面的JSP代碼片斷輸出自從服務器啓動(或Servlet類被改動並重新裝載以來)當前頁面被請求的次數:
<%! private int accessCount = 0; %>
自從服務器啓動以來頁面訪問次數爲:
<%= ++accessCount %>
和Scriptlet一樣,如果要使用字符串“%>”,必須使用“%\>”代替。最後,<%! code %>的XML等價表達方式爲:
<jsp:declaration>
Code
</jsp:declaration>
12.2 JSP指令
JSP指令影響Servlet類的整體結構,它的語法一般如下:
<%@ directive attribute="value" %>
另外,也可以把同一指令的多個屬性結合起來,例如:
<%@ directive attribute1="value1"
attribute2="value2"
...
attributeN="valueN" %>
JSP指令分爲兩種類型:第一是page指令,用來完成下面這類任務:導入指定的類,自定義Servlet的超類,等等;第二是include指令,用來在JSP文件轉換成Servlet時引入其他文件。JSP規範也提到了taglib指令,其目的是讓JSP開發者能夠自己定義標記,但JSP 1.0不支持該指令,有希望它將成爲JSP 1.1的主要改進之一。
12.2.1 page指令
page指令的作用是定義下面一個或多個屬性,這些屬性大小寫敏感。
import="package.class",或者import="package.class1,...,package.classN":
用於指定導入哪些包,例如:<%@ page import="java.util.*" %>。import是唯一允許出現一次以上的屬性。
contentType="MIME-Type" 或contentType="MIME-Type; charset=Character-Set":
該屬性指定輸出的MIME類型。默認是text/html。例如,下面這個指令:
<%@ page contentType="text/plain" %>。
和下面的Scriptlet效果相同:
<% response.setContentType("text/plain"); %>
isThreadSafe="true|false"
默認值true表明Servlet按照標準的方式處理,即假定開發者已經同步對實例變量的訪問,由單個Servlet實例同時地處理多個請求。如果取值false,表明Servlet應該實現SingleThreadModel,請求或者是逐個進入,或者多個並行的請求分別由不同的Servlet實例處理。
session="true|false"
默認值true表明預定義變量session(類型爲HttpSession)應該綁定到已有的會話,如果不存在已有的會話,則新建一個並綁定session變量。如果取值false,表明不會用到會話,試圖訪問變量session將導致JSP轉換成Servlet時出錯。
buffer="size kb|none"
該屬性指定JspWrite out的緩存大小。默認值和服務器有關,但至少應該是8 KB。
autoflush="true|false"
默認值true表明如果緩存已滿則刷新它。autoflush很少取false值,false值表示如果緩存已滿則拋出異常。如果buffer="none",autoflush不能取false值。
extends="package.class"
該屬性指出將要生成的Servlet使用哪個超類。使用該屬性應當十分小心,因爲服務器可能已經在用自定義的超類。
info="message"
該屬性定義一個可以通過getServletInfo方法提取的字符串。
errorPage="url"
該屬性指定一個JSP頁面,所有未被當前頁面捕獲的異常均由該頁面處理。
isErrorPage="true|false"
該屬性指示當前頁面是否可以作爲另一JSP頁面的錯誤處理頁面。默認值false。
language="java"
該屬性用來指示所使用的語言。目前沒有必要關注這個屬性,因爲默認的Java是當前唯一可用的語言。
定義指令的XML語法爲:
<jsp:directive.directiveType attribute=value />
例如,下面這個指令:
<%@ page import="java.util.*" %>
它的XML等價表達是:
<jsp:directive.page import="java.util.*" />
12.2.2 include指令
include指令用於JSP頁面轉換成Servlet時引入其他文件。該指令語法如下:
<%@ include file="relative url" %>
這裏所指定的URL是和發出引用指令的JSP頁面相對的URL,然而,與通常意義上的相對URL一樣,你可以利用以“/”開始的URL告訴系統把URL視爲從Web服務器根目錄開始。包含文件的內容也是JSP代碼,即包含文件可以包含靜態HTML、腳本元素、JSP指令和動作。
例如,許多網站的每個頁面都有一個小小的導航條。由於HTML框架存在不少問題,導航條往往用頁面頂端或左邊的一個表格製作,同一份HTML代碼重複出現在整個網站的每個頁面上。include指令是實現該功能的非常理想的方法。使用include指令,開發者不必再把導航HTML代碼拷貝到每個文件中,從而可以更輕鬆地完成維護工作。
由於include指令是在JSP轉換成Servlet的時候引入文件,因此如果導航條改變了,所有使用該導航條的JSP頁面都必須重新轉換成Servlet。如果導航條改動不頻繁,而且你希望包含操作具有儘可能好的效率,使用include指令是最好的選擇。然而,如果導航條改動非常頻繁,你可以使用jsp:include動作。jsp:include動作在出現對JSP頁面請求的時候纔會引用指定的文件,請參見本文後面的具體說明。
12.3 實例:腳本元素和指令的應用
下面是一個使用JSP表達式、Scriptlet、聲明、指令的簡單例子。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>JavaServer Pages</TITLE>
</HEAD>
<BODY BGCOLOR="#FDF5E6" TEXT="#000000" LINK="#0000EE"
VLINK="#551A8B" ALINK="#FF0000">
<CENTER>
<TABLE BORDER=5 BGCOLOR="#EF8429">
<TR><TH CLASS="TITLE">
JSP應用實例</TABLE>
</CENTER>
<P>
下面是一些利用各種JSP功能生成的動態內容:
<UL>
<LI><B>表達式.</B><BR>
你的主機名: <%= request.getRemoteHost() %>.
<LI><B>JSP Scriptlet.</B><BR>
<% out.println("查詢字符串: " +
request.getQueryString()); %>
<LI><B>聲明(和表達式).</B><BR>
<%! private int accessCount = 0; %>
服務器啓動以來訪問次數: <%= ++accessCount %>
<LI><B>指令(和表達式).</B><BR>
<%@ page import = "java.util.*" %>
當前日期: <%= new Date() %>
</UL>
</BODY>
</HTML>
12.4 JSP預定義變量
爲了簡化JSP表達式和Scriptlet的代碼,JSP提供了8個預先定義的變量(或稱爲隱含對象)。這些變量是request、response、out、session、application、config、pageContext和page。
12.4.1 request
這是和請求關聯的HttpServletRequest,通過它可以查看請求參數(調用getParameter),請求類型(GET,POST,HEAD,等),以及請求的HTTP頭(Cookie,Referer,等)。嚴格說來,如果請求所用的是HTTP之外的其他協議,request可以是ServletRequest的子類(而不是HttpServletRequest),但在實踐中幾乎不會用到。
12.4.2 response
這是和應答關聯的HttpServletResponse。注意,由於輸出流(參見下面的out)是帶緩衝的,因此,如果已經向客戶端發送了輸出內容,普通Servlet不允許再設置HTTP狀態代碼,但在JSP中卻是合法的。
12.4.3 out
這是用來向客戶端發送內容的PrintWriter。然而,爲了讓response對象更爲實用,out是帶緩存功能的PrintWriter,即JspWriter。JSP允許通過page指令的buffer屬性調整緩存的大小,甚至允許關閉緩存。
out一般只在Scriptlet內使用,這是因爲JSP表達式是自動發送到輸出流的,很少需要顯式地引用out。
12.4.4 session
這是和請求關聯的HttpSession對象。前面我們已經介紹過會話的自動創建,我們知道,即使不存在session引用,這個對象也是自動綁定的。但有一個例外,這就是如果你用page指令的session屬性關閉了會話,此時對session變量的引用將導致JSP頁面轉換成Servlet時出錯。
12.4.5 application
這是一個ServletContext,也可以通過getServletConfig().getContext()獲得。
12.4.6 config
這是當前頁面的ServletConfig對象。
12.4.7 pageContext
主要用來管理頁面的屬性。
12.4.8 page
它是this的同義詞,當前用處不大。它是爲了Java不再是唯一的JSP編程語言而準備的佔位符。
JSP動作利用XML語法格式的標記來控制Servlet引擎的行爲。利用JSP動作可以動態地插入文件、重用JavaBean組件、把用戶重定向到另外的頁面、爲Java插件生成HTML代碼。
JSP動作包括:
jsp:include:在頁面被請求的時候引入一個文件。
jsp:useBean:尋找或者實例化一個JavaBean。
jsp:setProperty:設置JavaBean的屬性。
jsp:getProperty:輸出某個JavaBean的屬性。
jsp:forward:把請求轉到一個新的頁面。
jsp:plugin:根據瀏覽器類型爲Java插件生成OBJECT或EMBED標記。
13.1 jsp:include動作
該動作把指定文件插入正在生成的頁面。其語法如下:
<jsp:include page="relative URL" flush="true" />
前面已經介紹過include指令,它是在JSP文件被轉換成Servlet的時候引入文件,而這裏的jsp:include動作不同,插入文件的時間是在頁面被請求的時候。jsp:include動作的文件引入時間決定了它的效率要稍微差一點,而且被引用文件不能包含某些JSP代碼(例如不能設置HTTP頭),但它的靈活性卻要好得多。
例如,下面的JSP頁面把4則新聞摘要插入一個“What's New ?”頁面。改變新聞摘要時只需改變這四個文件,而主JSP頁面卻可以不作修改:
WhatsNew.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>What's New</TITLE>
</HEAD>
<BODY BGCOLOR="#FDF5E6" TEXT="#000000" LINK="#0000EE"
VLINK="#551A8B" ALINK="#FF0000">
<CENTER>
<TABLE BORDER=5 BGCOLOR="#EF8429">
<TR><TH CLASS="TITLE">
What's New at JspNews.com</TABLE>
</CENTER>
<P>
Here is a summary of our four most recent news stories:
<OL>
<LI><jsp:include page="news/Item1.html" flush="true"/>
<LI><jsp:include page="news/Item2.html" flush="true"/>
<LI><jsp:include page="news/Item3.html" flush="true"/>
<LI><jsp:include page="news/Item4.html" flush="true"/>
</OL>
</BODY>
</HTML>
13.2 jsp:useBean動作
jsp:useBean動作用來裝載一個將在JSP頁面中使用的JavaBean。這個功能非常有用,因爲它使得我們既可以發揮Java組件重用的優勢,同時也避免了損失JSP區別於Servlet的方便性。jsp:useBean動作最簡單的語法爲:
<jsp:useBean id="name" class="package.class" />
這行代碼的含義是:“創建一個由class屬性指定的類的實例,然後把它綁定到其名字由id屬性給出的變量上”。不過,就象我們接下來會看到的,定義一個scope屬性可以讓Bean關聯到更多的頁面。此時,jsp:useBean動作只有在不存在同樣id和scope的Bean時才創建新的對象實例,同時,獲得現有Bean的引用就變得很有必要。
獲得Bean實例之後,要修改Bean的屬性既可以通過jsp:setProperty動作進行,也可以在Scriptlet中利用id屬性所命名的對象變量,通過調用該對象的方法顯式地修改其屬性。這使我們想起,當我們說“某個Bean有一個類型爲X的屬性foo”時,就意味着“這個類有一個返回值類型爲X的getFoo方法,還有一個setFoo方法以X類型的值爲參數”。
有關jsp:setProperty動作的詳細情況在後面討論。但現在必須瞭解的是,我們既可以通過jsp:setProperty動作的value屬性直接提供一個值,也可以通過param屬性聲明Bean的屬性值來自指定的請求參數,還可以列出Bean屬性表明它的值應該來自請求參數中的同名變量。
在JSP表達式或Scriptlet中讀取Bean屬性通過調用相應的getXXX方法實現,或者更一般地,使用jsp:getProperty動作。
注意包含Bean的類文件應該放到服務器正式存放Java類的目錄下,而不是保留給修改後能夠自動裝載的類的目錄。例如,對於Java Web Server來說,Bean和所有Bean用到的類都應該放入classes目錄,或者封裝進jar文件後放入lib目錄,但不應該放到servlets下。
下面是一個很簡單的例子,它的功能是裝載一個Bean,然後設置/讀取它的message屬性。
BeanTest.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Reusing JavaBeans in JSP</TITLE>
</HEAD>
<BODY>
<CENTER>
<TABLE BORDER=5>
<TR><TH CLASS="TITLE">
Reusing JavaBeans in JSP</TABLE>
</CENTER>
<P>
<jsp:useBean id="test" class="hall.SimpleBean" />
<jsp:setProperty name="test"
property="message"
value="Hello WWW" />
<H1>Message: <I>
<jsp:getProperty name="test" property="message" />
</I></H1>
</BODY>
</HTML>
SimpleBean.java
BeanTest頁面用到了一個SimpleBean。SimpleBean的代碼如下:
package hall;
public class SimpleBean {
private String message = "No message specified";
public String getMessage() {
return(message);
}
public void setMessage(String message) {
this.message = message;
}
}
13.3 關於jsp:useBean的進一步說明
使用Bean最簡單的方法是先用下面的代碼裝載Bean:
<jsp:useBean id="name" class="package.class" />
然後通過jsp:setProperty和jsp:getProperty修改和提取Bean的屬性。不過有兩點必須注意。第一,我們還可以用下面這種格式實例化Bean:
<jsp:useBean ...>
Body
</jsp:useBean>
它的意思是,只有當第一次實例化Bean時才執行Body部分,如果是利用現有的Bean實例則不執行Body部分。正如下面將要介紹的,jsp:useBean並非總是意味着創建一個新的Bean實例。
第二,除了id和class外,jsp:useBean還有其他三個屬性,即:scope,type,beanName。下表簡要說明這些屬性的用法。 屬性 用法
id 命名引用該Bean的變量。如果能夠找到id和scope相同的Bean實例,jsp:useBean動作將使用已有的Bean實例而不是創建新的實例。
class 指定Bean的完整包名。
scope 指定Bean在哪種上下文內可用,可以取下面的四個值之一:page,request,session和application。
默認值是page,表示該Bean只在當前頁面內可用(保存在當前頁面的PageContext內)。
request表示該Bean在當前的客戶請求內有效(保存在ServletRequest對象內)。
session表示該Bean對當前HttpSession內的所有頁面都有效。
最後,如果取值application,則表示該Bean對所有具有相同ServletContext的頁面都有效。
scope之所以很重要,是因爲jsp:useBean只有在不存在具有相同id和scope的對象時纔會實例化新的對象;如果已有id和scope都相同的對象則直接使用已有的對象,此時jsp:useBean開始標記和結束標記之間的任何內容都將被忽略。
type 指定引用該對象的變量的類型,它必須是Bean類的名字、超類名字、該類所實現的接口名字之一。請記住變量的名字是由id屬性指定的。
beanName 指定Bean的名字。如果提供了type屬性和beanName屬性,允許省略class屬性。
13.4 jsp:setProperty動作
jsp:setProperty用來設置已經實例化的Bean對象的屬性,有兩種用法。首先,你可以在jsp:useBean元素的外面(後面)使用jsp:setProperty,如下所示:
<jsp:useBean id="myName" ... />
...
<jsp:setProperty name="myName"
property="someProperty" ... />
此時,不管jsp:useBean是找到了一個現有的Bean,還是新創建了一個Bean實例,jsp:setProperty都會執行。第二種用法是把jsp:setProperty放入jsp:useBean元素的內部,如下所示:
<jsp:useBean id="myName" ... >
...
<jsp:setProperty name="myName"
property="someProperty" ... />
</jsp:useBean>
此時,jsp:setProperty只有在新建Bean實例時纔會執行,如果是使用現有實例則不執行jsp:setProperty。
jsp:setProperty動作有下面四個屬性: 屬性 說明
name name屬性是必需的。它表示要設置屬性的是哪個Bean。
property property屬性是必需的。它表示要設置哪個屬性。有一個特殊用法:如果property的值是“*”,表示所有名字和Bean屬性名字匹配的請求參數都將被傳遞給相應的屬性set方法。
value value屬性是可選的。該屬性用來指定Bean屬性的值。字符串數據會在目標類中通過標準的valueOf方法自動轉換成數字、boolean、Boolean、byte、Byte、char、Character。例如,boolean和Boolean類型的屬性值(比如“true”)通過Boolean.valueOf轉換,int和Integer類型的屬性值(比如“42”)通過Integer.valueOf轉換。
value和param不能同時使用,但可以使用其中任意一個。
param param是可選的。它指定用哪個請求參數作爲Bean屬性的值。如果當前請求沒有參數,則什麼事情也不做,系統不會把null傳遞給Bean屬性的set方法。因此,你可以讓Bean自己提供默認屬性值,只有當請求參數明確指定了新值時才修改默認屬性值。
例如,下面的代碼片斷表示:如果存在numItems請求參數的話,把numberOfItems屬性的值設置爲請求參數numItems的值;否則什麼也不做。
<jsp:setProperty name="orderBean"
property="numberOfItems"
param="numItems" />
如果同時省略value和param,其效果相當於提供一個param且其值等於property的值。進一步利用這種藉助請求參數和屬性名字相同進行自動賦值的思想,你還可以在property(Bean屬性的名字)中指定“*”,然後省略value和param。此時,服務器會查看所有的Bean屬性和請求參數,如果兩者名字相同則自動賦值。
下面是一個利用JavaBean計算素數的例子。如果請求中有一個numDigits參數,則該值被傳遞給Bean的numDigits屬性;numPrimes也類似。
JspPrimes.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>在JSP中使用JavaBean</TITLE>
</HEAD>
<BODY>
<CENTER>
<TABLE BORDER=5>
<TR><TH CLASS="TITLE">
在JSP中使用JavaBean</TABLE>
</CENTER>
<P>
<jsp:useBean id="primeTable" class="hall.NumberedPrimes" />
<jsp:setProperty name="primeTable" property="numDigits" />
<jsp:setProperty name="primeTable" property="numPrimes" />
Some <jsp:getProperty name="primeTable" property="numDigits" />
digit primes:
<jsp:getProperty name="primeTable" property="numberedList" />
</BODY>
</HTML>
注:NumberedPrimes的代碼略。
13.5 jsp:getProperty動作
jsp:getProperty動作提取指定Bean屬性的值,轉換成字符串,然後輸出。jsp:getProperty有兩個必需的屬性,即:name,表示Bean的名字;property,表示要提取哪個屬性的值。下面是一個例子,更多的例子可以在前文找到。
<jsp:useBean id="itemBean" ... />
...
<UL>
<LI>Number of items:
<jsp:getProperty name="itemBean" property="numItems" />
<LI>Cost of each:
<jsp:getProperty name="itemBean" property="unitCost" />
</UL>
13.6 jsp:forward動作
jsp:forward動作把請求轉到另外的頁面。jsp:forward標記只有一個屬性page。page屬性包含的是一個相對URL。page的值既可以直接給出,也可以在請求的時候動態計算,如下面的例子所示:
<jsp:forward page="/utils/errorReporter.jsp" />
<jsp:forward page="<%= someJavaExpression %>" />
13.7 jsp:plugin動作
jsp:plugin動作用來根據瀏覽器的類型,插入通過Java插件 運行Java Applet所必需的OBJECT或EMBED元素。
附錄:JSP註釋和字符引用約定
下面是一些特殊的標記或字符,你可以利用它們插入註釋或可能被視爲具有特殊含義的字符。 語法 用途
<%-- comment --%> JSP註釋,也稱爲“隱藏註釋”。JSP引擎將忽略它。標記內的所有JSP腳本元素、指令和動作都將不起作用。
<!-- comment --> HTML註釋,也稱爲“輸出的註釋”,直接出現在結果HTML文檔中。標記內的所有JSP腳本元素、指令和動作正常執行。
<\% 在模板文本(靜態HTML)中實際上希望出現“<%”的地方使用。
%\> 在腳本元素內實際上希望出現“%>”的地方使用。
\' 使用單引號的屬性內的單引號。不過,你既可以使用單引號也可以使用雙引號,而另外一種引號將具有普通含義。
\" 使用雙引號的屬性內的雙引號。參見“\'”的說