Java Servlet和JSP教程 11-12-13-

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)中實際上希望出現“<%”的地方使用。  
%\>  在腳本元素內實際上希望出現“%>”的地方使用。  
\'  使用單引號的屬性內的單引號。不過,你既可以使用單引號也可以使用雙引號,而另外一種引號將具有普通含義。  
\"  使用雙引號的屬性內的雙引號。參見“\'”的說

發佈了30 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章