簡介
JSP動作元素(action elements),動作元素為請求處理階段提供信息。動作元素遵循 XML 元素的語法,有一個包含元素名的開始標籤,可以有屬性、可選的內容、 與開始標籤匹配的結束標籤。
JSP2.0 規範中定義了 20 個標準的動作元素。
種類
第一類是與存取JavaBean有關的,包括:
<jsp:useBean><jsp:setProperty><jsp:getProperty>
第二類是JSP1.2就開始有的基本元素,包括6個動作元素
<jsp:include><jsp:forward><jsp:param><jsp:plugin><jsp:params><jsp:fallback>
第三類是JSP2.0新增加的元素,主要與JSP Document有關,包括六個元素
<jsp:root><jsp:declaration><jsp:scriptlet><jsp:expression><jsp:text><jsp:output>
第四類是JSP2.0新增的動作元素,主要是用來動態生成XML元素標籤的值,包括3個動作
<jsp:attribute><jsp:body><jsp:element>
第五類是JSP2.0新增的動作元素,主要是用在Tag File中,有2個元素
<jsp:invoke><jsp:dobody>
用法
include
該動作把指定檔案插入正在生成的頁面。其語法如下:
前面已經介紹過include指令,它是在JSP檔案被轉換成Servlet的時候引入檔案,而這裡的jsp:include動作不同,插入檔案的時間是在頁面被請求的時候。jsp:include動作的檔案引入時間決定了它的效率要稍微差一點,而且被引用檔案不能包含某些JSP代碼(例如不能設定 HTTP頭),但它的靈活性卻要好得多。
useBean
jsp:useBean動作用來裝載一個將在JSP頁面中使用的JavaBean。這個功能非常有用,因為它使得我們既可以發揮Java組件重用的優勢,同時也避免了損失JSP區別於Servlet的方便性。jsp:useBean動作最簡單的語法為:
這行代碼的含義是:“創建一個由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
Reusing JavaBeans in JSP
<jsp:setProperty name="test"
property="message"
value="Hello WWW" />
Message:
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;
}
使用Bean最簡單的方法是先用下面的代碼裝載Bean:
然後通過jsp:setProperty和jsp:getProperty修改和提取Bean的屬性。不過有兩點必須注意。第一,我們還可以用下面這種格式實例化Bean:
Body
它的意思是,只有當第一次實例化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屬性。
jsp:setProperty
jsp:setProperty用來設定已經實例化的Bean對象的屬性,有兩種用法。首先,你可以在jsp:useBean元素的外面(後面)使用jsp:setProperty,如下所示:
...
<jsp:setProperty name="myName"
property="someProperty" ... />
此時,不管jsp:useBean是找到了一個現有的Bean,還是新創建了一個Bean實例,jsp:setProperty都會執行。第二種用法是把jsp:setProperty放入jsp:useBean元素的內部,如下所示:
...
<jsp:setProperty name="myName"
property="someProperty" ... />
此時,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
在JSP中使用JavaBean
Some
digit primes:
註:NumberedPrimes的代碼略。
jsp:getProperty
jsp:getProperty動作提取指定Bean屬性的值,轉換成字元串,然後輸出。jsp:getProperty有兩個必需的屬性,即: name,表示Bean的名字;property,表示要提取哪個屬性的值。下面是一個例子,更多的例子可以在前文找到。
...
<li>Number of items:</li>
<li>Cost of each:</li>
jsp:forward
jsp:forward動作把請求轉到另外的頁面。jsp:forward標記只有一個屬性page。page屬性包含的是一個相對URL。page的值既可以直接給出,也可以在請求的時候動態計算,如下面的例子所示:
<jsp:forward page="" />
jsp:plugin
jsp:plugin動作用來根據瀏覽器的類型,插入通過Java外掛程式 運行Java Applet所必需的OBJECT或EMBED元素。