




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、 第4章 JSP技術模型本章內容 4.1JSP語法概述 4.2 JSP頁面生命周期 4.3 理解page指令屬性 4.4 JSP腳本元素 4.5 JSP隱含變量 4.6 作用域對象 4.7 JSP組件包含4.1 JSP語法概述 在JSP頁面中可以包含的元素如表4-1所示。 表4-1 JSP頁面元素JSPJSP頁面元素頁面元素簡要說明簡要說明標簽語法標簽語法聲明聲明變量與定義方法小腳本執(zhí)行業(yè)務邏輯的Java代碼表達式用于在JSP頁面輸出表達式的值指令指定轉換時向容器發(fā)出的指令動作向容器提供請求時的指令EL表達式JSP 2.0引進的表達式語言$applicationScope.email注釋用于文
2、檔注釋模板文本HTML標簽和文本同HTML規(guī)則 下面是一個簡單的JSP頁面,它輸出頁面被訪問的次數。 程序4.1 counter.jsp % page % %! count = 0; % % % 該頁面已被訪問該頁面已被訪問 次。次。 4.1 JSP語法概述4.1 JSP語法概述 4.1.1 JSP腳本元素 4.1.2 JSP指令 4.1.3 JSP動作 4.1.4 表達式語言 4.1.5 JSP注釋 4.1.1 JSP腳本元素 在JSP頁面中有三種腳本元素: JSP聲明 JSP小腳本 JSP表達式。 1. JSP聲明 JSP聲明(declaration)用來在JSP頁面中聲明變量和定義方法。
3、聲明是以“”結束的標簽,其中可以包含任意數量的合法的Java聲明語句。下面是JSP聲明的一個例子: 注意,由于聲明包含的是聲明語句,所以每個變量的聲明語句必須以分號結束。 下面的代碼在一個標簽中聲明了一個變量和一個方法。 1. JSP聲明 也可以將上面的兩個Java聲明語句寫在兩個JSP聲明標簽中。 1. JSP聲明 小腳本(scriptlets)是嵌入在JSP頁面中的Java代碼段。小腳本是以“”結束的標簽。例如,程序4.1中的下面一行就是JSP小腳本。 小腳本在每次訪問頁面時都被執(zhí)行,因此count變量在每次請求時都增1。2. JSP小腳本 由于小腳本可以包含任何Java代碼,所以它通常用
4、來在JSP頁面嵌入計算邏輯。同時還可以使用小腳本打印HTML模板文本。如下面代碼與程序4.1的代碼等價: % out.print(); count+; out.print(該頁面已被訪問 + count +次。 ); out.print(); %2. JSP小腳本 這里變量out是一個隱含對象,將在4.5節(jié)中討論out對象。與其他元素不同,小腳本的起始標簽“%”后面沒有任何特殊字符,在小腳本中的代碼必須是合法的Java語言代碼。 例如,下面的代碼是錯誤的,因為它沒有使用分號結束。 2. JSP小腳本 JSP表達式是以“”結束的標簽,它作為Java語言表達式的占位符。 下面是JSP表達式的例子。
5、 在頁面每次被訪問時都要計算表達式,然后將其值嵌入到HTML的輸出中。3. JSP表達式 與變量聲明不同,表達式不能以分號結束,因此下面的代碼是非法的。 使用表達式可以向輸出流輸出任何對象或任何基本數據類型(int、boolean、char等)的值,也可以打印任何算術表達式、布爾表達式或方法調用返回的值。 提示:在JSP表達式的百分號和等號之間不能有空格3. JSP表達式 下面代碼聲明了一些變量并通過表達式輸出。 程序程序4.2 4.2 expression.jspexpression.jsp3. JSP表達式4.1.2 JSP指令 JSP指令向容器提供關于JSP頁面的總體信息。在JSP頁面中
6、,指令是以“”結束的標簽。 指令有三種類型:page指令、include指令和taglib指令。 4.1.2 JSP指令 三種指令的語法格式如下: 在上面的指令標簽中,attribute-list表示一個或多個針對指令的屬性/值對,多個屬性之間用空格分隔。 page指令通知容器關于JSP頁面的總體特性。 例如,下面的page指令通知容器頁面輸出的內容類型和使用的字符集。 1. page指令 include指令指令實現把另一個文件(HTML、JSP等)的內容包含到當前頁面中。下面是include指令的一個例子 2. include指令 taglib指令用來指定在JSP頁面中使用標準標簽或自定義標
7、簽的前綴與標簽庫的URI,下面是taglib指令的例子。 3. taglib指令 關于指令的使用需注意下面幾個問題:標簽名、屬性名及屬性值都是大小寫敏感的。屬性值必須使用一對單引號或雙引號括起來。在等號(=)與值之間不能有空格。 3. taglib指令4.1.3 JSP動作 JSP動作(actions)是頁面發(fā)給容器的命令,它指示容器在頁面執(zhí)行期間完成某種任務。動作的一般語法為: 動作是一種標簽,在動作標簽中,prefix為前綴名,actionName為動作名,attribute-list表示針對該動作的一個或多個屬性/值對。4.1.3 JSP動作 在JSP頁面中可以使用三種動作: JSP標準
8、動作 標準標簽庫(JSTL)中的動作 用戶自定義動作 例如,下面一行指示容器把另一個JSP頁面copyright.jsp的輸出包含在當前JSP頁面的輸出中: 下面是常用的JSP標準動作: jsp:include,在當前頁面中包含另一個頁面的輸出。 jsp:forward,將請求轉發(fā)到指定的頁面。 jsp:useBean,查找或創(chuàng)建一個JavaBeans對象。 jsp:setProperty,設置JavaBeans對象的屬性值。 jsp:getProperty,返回JavaBeans對象的屬性值。 jsp:plugin,在JSP頁面中嵌入一個插件(如Applet)。 4.1.3 JSP動作4.1
9、.4 表達式語言 表達式語言(Expression Language,EL)是JSP 2.0新增加的特性,它是一種可以在JSP頁面中使用的簡潔的數據訪問語言。它的格式為: $expression 表達式語言是以$開頭,后面是一對大括號,括號里面是合法的EL表達式。該結構可以出現在JSP頁面的模板文本中,也可以出現在JSP標簽的屬性中。 $param.userName 該EL顯示請求參數userName的值。4.1.5 JSP注釋 JSP注釋的格式為: JSP注釋是以“”結束的標簽。注釋不影響JSP頁面的輸出,但它對用戶理解代碼很有幫助。 Web容器在輸出JSP頁面時去掉JSP注釋內容,所以在調
10、試JSP頁面時可以將JSP頁面中一大塊內容注釋掉,包括嵌套的HTML和其他JSP標簽。4.1.5 JSP注釋 還可以在小腳本或聲明中使用一般的Java風格的注釋,也可以在頁面的HTML部分使用HTML風格的注釋,如下所示: 4.2 JSP頁面生命周期 4.2.1 JSP頁面也是Servlet 4.2.2 JSP生命周期階段 4.2.3 JSP生命周期方法示例 4.2.4 理解頁面轉換過程 4.2.5 理解轉換單元 JSP頁面盡管從結構上看與HTML頁面類似,但它實際上是作為Servlet運行的。 當JSP頁面第一次被訪問時,Web容器解析JSP文件并將其轉換成相應的Java文件,該文件聲明了一
11、個Servlet類,我們將該類稱為頁面實現類。 接下來,Web容器編譯該類并將其裝入內存,然后與其他Servlet一樣執(zhí)行并將其輸出結果發(fā)送到客戶端。4.2.1 JSP頁面也是Servlet4.2.2 JSP生命周期階段 下面的JSP頁面todayDate.jsp用于顯示當前日期。下面以該頁面為例說明JSP頁面的生命周期的7個階段。 程序4.3 todayDate.jsp 當客戶通過http:/localhost:8080/helloweb/todayDate.jsp 首次訪問該頁面時,Web容器執(zhí)行該JSP頁面要經過7個生命周期階段,如圖4-1所示。4.2.2 JSP生命周期階段4.2.2
12、JSP生命周期階段 JSP生命周期的前四個階段將JSP頁面轉換成一個Servlet類并裝載和創(chuàng)建該類實例,后三個階段初始化、提供服務和銷毀階段。表4-2按生命周期的順序列出了每個階段及說明。 表4-2 JSP頁面生命周期階段階段名稱階段名稱說明說明 頁面轉換對頁面解析并創(chuàng)建一個包含對應Servlet的Java源文件 頁面編譯對Java源文件編譯 加載類將編譯后的類加載到容器中 創(chuàng)建實例創(chuàng)建一個Servlet實例 調用jspInit()調用其他方法之前調用該方法初始化 調用_jspService()對每個請求調用一次該方法 調用jspDestroy()當Servlet容器決定停止Servlet服
13、務時調用該方法1. 轉換階段 Web容器讀取JSP頁面對其解析,并將其轉換成Java源代碼。JSP文件中的元素都轉換成頁面實現類的成員。在這個階段,容器將檢查JSP頁面中標簽的語法,如果發(fā)現錯誤將不能轉換。例如,下面的指令就是非法的,因為在Page中使用了大寫字母P,這在轉換階段被捕獲。 除了檢查語法外,容器還將執(zhí)行其他有效性檢查,其中一些涉及驗證: 一旦驗證完成,Web容器將JSP頁面轉換成Java源文件,它實際是一個Servlet,該文件存放在workCatalinalocalhosthelloweborgapachejsp目錄中。1. 轉換階段 JspPage接口只聲明了兩個方法:jsp
14、Init()和jspDestroy()。所有的JSP頁面都應該實現這兩個方法。HttpJspPage接口中聲明了一個方法:_jspService()。下面是這三個JSP方法的格式: public void jspInit(); public void _jspService(HttpServletRequest request, HttpServletResponse response) public void jspDestroy();1. 轉換階段 每個容器銷售商都提供一個特定的類作為頁面實現類的基類。在Tomcat中,JSP頁面轉換的類就繼承了org.apache.jasper.runt
15、ime.HttpJspBase類,該類提供了Servlet接口的所有方法的默認實現和JspPage接口的兩個方法jspInit()和jspDestroy()的默認實現。在轉換階段,容器把_jspService()添加到JSP頁面的實現類中,這樣使該類成為三個接口的一個具體子類。1. 轉換階段 在將JSP頁面轉換成Java文件后,Web容器調用Java編譯器javac編譯該文件。在編譯階段,編譯器將檢查在聲明中、小腳本中以及表達式中所寫的全部Java代碼。 例如,下面的聲明標簽盡管能夠通過轉換階段,但由于聲明語句沒以分號結束,所以不是合法的Java聲明語句,因此在編譯階段會被查出。 2. 編譯階
16、段 可能注意到,當JSP頁面被首次訪問時,服務器響應要比以后的訪問慢一些。這是因為在JSP頁面向客戶提供服務之前必須要轉換成Servlet類的實例。對每個請求,容器要檢查JSP頁面源文件的時間戳以及相應的Servlet類文件以確定頁面是否是新的或是否已經轉換成類文件。 因此,如果修改了JSP頁面,將JSP頁面轉換成Servlet的整個過程要重新執(zhí)行一遍。2. 編譯階段 Web容器將頁面實現類編譯成類文件,然后加載到內存中。3. 加載類 Web容器調用頁面實現類的構造方法創(chuàng)建一個Servlet類的實例。4. 實例化 Web容器調用jspInit()初始化Servlet實例。該方法是在任何其他方法
17、調用之前調用的,并在頁面生命期內只調用一次。通常在該方法中完成初始化或只需一次的設置工作,如獲得資源及初始化JSP頁面中使用聲明的實例變量。5. 調用jspInit() 對該頁面的每次請求容器都調用一次_jspService(),并給它傳遞請求和響應對象。JSP頁面中所有的HTML元素,JSP小腳本以及JSP表達式在轉換階段都成為該方法的一部分。6.調用_jspService() 當容器決定停止該實例提供服務時,它將調用jspDestroy(),這是在Servlet實例上調用的最后一個方法,它主要用來清理jspInit()獲得的資源。 一般不需要實現jspInit()和jspDestroy()
18、,因為它們已經由基類實現了。但可以根據需要使用JSP的聲明標簽覆蓋這兩個方法。然而,不能覆蓋_jspService(),因為該方法由Web容器自動產生。4.調用jspDestroy()4.2.3 JSP生命周期方法示例 下面的lifeCycle.jsp頁面覆蓋了jspInit()和jspDestroy(),當該頁面第一次被訪問時將在控制臺中看到“jspInit”,當應用程序關閉時,將會看到“jspDestroy”。 程序4.4 lifeCycle.jsp4.2.3 JSP生命周期方法示例 當Web容器首次裝入頁面時,它將調用jspInit()。在JSP頁面的生命周期中,count變量可能被多次
19、訪問,每次都將執(zhí)行_jspService()。由于小腳本變成_jspService()的一部分,count+每次都會被執(zhí)行使計數器增1。最后,當頁面被銷毀時,容器調用jspDestroy()。 注意,_jspService()不能被覆蓋。4.2.4 理解頁面轉換過程 JSP頁面生命周期的第一階段是轉換階段,在該階段JSP頁面被轉換成包含相應Servlet的Java文件。容器根據下面規(guī)則將JSP頁面中的元素轉換成Servlet代碼。所有JSP聲明都轉換成頁面實現類的成員,它們被原樣拷貝。例如,聲明的變量轉換成實例變量,聲明的方法轉換成實例方法。所有JSP小腳本都轉換成頁面實現類的_jspServ
20、ice()的一部分,它們也被原樣拷貝。小腳本中聲明的變量轉換成_jspService()的局部變量,小腳本中的語句轉換成_jspService()中的語句。所有的JSP表達式都轉換成為_jspService()的一部分,表達式的值使用out.print()語句輸出。有些指令在轉換階段產生Java代碼,例如,page指令的import屬性轉換成頁面實現類的import語句。所有的JSP動作都通過調用針對廠商的類來替換。所有表達式語言EL通過計算后使用out.write()語句輸出。所有模板文本都成為_jspService()的一部分,模板內容使用out.write()語句輸出。所有的JSP注釋都
21、被忽略。4.2.4 理解頁面轉換過程4.2.5 理解轉換單元 在JSP頁面中可以使用指令把另一個文件(如JSP頁面、HTML頁面等)的內容包含到當前頁面中。容器在為當前JSP頁面產生Java代碼時,它也把被包含的文件的內容插入到產生的頁面實現類中。 這些被轉換成單個頁面實現類的頁面集合稱為轉換單元。有些JSP標簽影響整個轉換單元而不只是它們所在的頁面。4.2.5 理解轉換單元 關于轉換單元,請記住下面要點:page指令影響整個轉換單元。有些指令通知容器關于頁面的總體性質,例如,page指令的contentType屬性指定響應的內容類型,session屬性指定頁面是否參加HTTP會話。在一個轉換
22、單元中一個變量不能多次聲明。例如,如果一個變量已經在主頁面中聲明,它就不能在被包含的頁面中聲明。在一個轉換單元中不能使用動作對一個bean聲明兩次。4.3 理解page指令屬性 page指令用于告訴容器關于JSP頁面的總體特性,該指令適用于整個轉換單元而不僅僅是它所聲明的頁面。表4-3描述了page指令的常用的屬性。 表4-3 page指令的常用屬性屬性名說明默認值import導入在JSP頁面中使用的Java類和接口,其間用逗號分隔java.lang.*;javax.servlet.*;javax.servlet.jsp.*;javax.servlet.http.*;contentType指定
23、輸出的內容類型和字符集text/html;charset=ISO-8859-1pageEncoding 指定JSP文件的字符編碼ISO-8859-1session用布爾值指定JSP頁面是否參加HTTP會話 trueerrorPage用相對URL指定另一個JSP頁面用來處理當前頁面的錯誤nullisErrorPage用一個布爾值指定當前JSP頁面是否用來處理錯誤falselanguage指定容器支持的腳本語言javaextends任何合法的實現了javax.servlet.jsp.jspPage接口的java類與實現有關buffer指定輸出緩沖區(qū)的大小與實現有關autoFlush指定是否當緩沖區(qū)
24、滿時自動刷新trueinfo關于JSP頁面的任何文本信息與實現有關isThreadSafe指定頁面是否同時為多個請求服務trueisELIgnored指定是否在此轉換單元中對EL表達式求值若web.xml采用Servlet 2.4格式,默認值為true4.3.1 import屬性 import屬性的功能類似于Java程序的import語句,它是將import屬性值指定的類導入到頁面中。在轉換階段,容器對使用import屬性聲明的每個包都轉換成頁面實現類的一個import語句。可以在一個import屬性中導入多個包,包名用逗號分開即可: 4.3.1 import屬性 為了增強代碼可讀性也可以使用
25、多個page指令,如上面的page指令也可以寫成: 由于在Java程序中import語句的順序是沒有關系的,因此這里import屬性的順序也沒有關系。 容器總是導入java.lang.*、javax.servlet.*、javax.servlet.http.*和javax.servlet.jsp.* 包,所以不必明確地導入它們。4.3.1 import屬性4.3.2 contentType和pageEncoding屬性 contentType屬性用來指定JSP頁面輸出的MIME類型和字符集,MIME類型的默認值是text/html,字符集的默認值是ISO-8859-1。MIME類型和字符集之間
26、用分號分隔,如下所示。 如果頁面需要顯示中文,字符集應該指定為UTF-8,如下所示。 pageEncoding屬性指定JSP頁面的字符編碼,它的默認值為ISO-8859-1。如果設置了該屬性,則JSP頁面使用該屬性設置的字符集編碼;如果沒有設置這個屬性,則JSP頁面使用contentType屬性指定的字符集。如果頁面中含有中文,應該將該屬性值指定為UTF-8,如下: 4.3.2 contentType和pageEncoding屬性4.3.3 session屬性 session屬性指示JSP頁面是否參加HTTP會話,其默認值為true,在這種情況下容器將聲明一個隱含變量session(將在4.5
27、節(jié)學習更多的隱含變量)。如果不希望頁面參加會話,可以明確地加入下面一行: 4.3.4 errorPage與isErrorPage屬性 在頁面執(zhí)行過程中,嵌入在頁面中的Java代碼可能拋出異常。與一般的Java程序一樣,在JSP頁面中也可以使用try-catch塊處理異常。然而,JSP規(guī)范定義了一種更好的方法,它可以使錯誤處理代碼與主頁面代碼分離,從而提高異常處理機制的可重用性。 在該方法中,JSP頁面使用page指令的errorPage屬性將異常代理給另一個包含錯誤處理代碼的JSP頁面。4.3.4 errorPage與isErrorPage屬性 程序4.5的helloUser.jsp頁面中,e
28、rrorHandler.jsp被指定為錯誤處理頁面。 程序4.5 helloUser.jsp 對該JSP頁面的請求如果指定了name請求參數值,該頁面將正常輸出,如果沒有指定name請求參數值,將拋出一個異常,但它本身并沒有捕獲異常,而是通過errorPage屬性指示容器將錯誤處理代理給頁面errorHandler.jsp。 errorPage的屬性值不必是JSP頁面,它也可以是靜態(tài)的HTML頁面,例如: 顯然,在errorHandler.html文件中不能編寫小腳本或表達式產生動態(tài)信息。4.3.4 errorPage與isErrorPage屬性 isErrorPage屬性指定當前頁面是否作為
29、其他JSP頁面的錯誤處理頁面。isErrorPage屬性的默認值為false。如上例使用的errorHandler.jsp頁面中該屬性必須明確設置為true,如下所示。 程序4.6 errorHandler.jsp4.3.4 errorPage與isErrorPage屬性 在這種情況下,容器在頁面實現類中聲明一個名為exception的隱含變量。 注意,該頁面僅從異常對象中檢索信息并產生適當的錯誤消息。因為該頁面沒有實現任何業(yè)務邏輯,所以可以被不同的JSP頁面重用。 一般來說,為所有的JSP頁面中指定一個錯誤頁面是一個良好的編程習慣,這可以防止在客戶端顯示不希望的錯誤消息。4.3.4 erro
30、rPage與isErrorPage屬性 注意:如果不帶參數請求helloUser.jsp頁面,瀏覽器可能顯示“無法顯示網頁”的頁面。 此時,可以打開“工具”菜單的“Internet選項”對話框,在“高級”選項卡中,將“瀏覽”組中的“顯示友好HTTP錯誤信息”的復選框取消,再重新訪問頁面,則顯示JSP頁面中指定的錯誤頁面。4.3.4 errorPage與isErrorPage屬性4.3.5 在DD中配置錯誤頁面 可以在web.xml文件中為整個Web應用配置錯誤處理頁面。使用這種方法還可以根據異常類型的不同或HTTP錯誤碼的不同配置錯誤處理頁面。 在DD中配置錯誤頁面需要使用元素,它的子元素有,
31、和,它們分別指定處理錯誤的異常類型、HTTP錯誤碼和錯誤處理頁面。前兩個元素不能同時出現。 下面代碼聲明了一個處理算術異常的錯誤頁面。 java.lang.ArithmeticException /error/arithmeticError.jsp 4.3.5 在DD中配置錯誤頁面 還可以像下面這樣聲明一個更通用的處理頁面。 java.lang.Throwable /error/errorPage.jsp Throwable類是所有異常類的根類,因此對沒有明確指定錯誤處理頁面的異常,都將由該頁面處理。4.3.5 在DD中配置錯誤頁面 以下代碼為HTTP的狀態(tài)碼404配置了一個錯誤處理頁面,如下
32、所示。 404 /error/notFoundError.jsp 注意,元素的值必須以“/”開頭,它是相對于Web應用的上下文根目錄。另外,如果在JSP頁面中使用page指令的errorPage屬性指定了錯誤處理頁面,則errorPage屬性指定的頁面優(yōu)先。4.3.5 在DD中配置錯誤頁面4.3.6 language與extends屬性 language屬性指定在頁面的聲明、小腳本及表達式中使用的語言,默認值是java。 extends屬性指定頁面產生的Servlet的基類,該屬性僅在希望定制所產生的Servlet類的時候有用。默認的基類是廠商提供的。因此,該屬性很少被使用,下面一行給出了其語
33、法格式: 4.3.7 buffer與autoFlush屬性buffer屬性指定輸出緩沖區(qū)的大小。下面指令將緩沖區(qū)的大小設置為32kb。 緩沖區(qū)的值是以K字節(jié)為單位且kb是必須的autoFlush屬性指定是否在緩沖區(qū)滿時自動將緩沖區(qū)中的數據發(fā)送給客戶,該屬性的默認值為true。如果將其設置為false,而緩沖區(qū)又滿了,那么當再向緩沖區(qū)添加數據時會產生異常。下面將該屬性值設置為false。 4.3.8 info屬性 info屬性指定一個字符串值,它可由Servlet調用getServletInfo()返回。下面代碼給出了一種可能的用法。 在頁面中使用腳本檢索該值,該屬性的默認值依賴于實現。4.4
34、JSP腳本元素 由于聲明、小腳本和表達式允許在頁面中編寫腳本語言代碼,所以這些元素統稱為腳本元素。 JSP頁面使用Java語言作為腳本語言,因此腳本元素中代碼的編譯和運行行為受到Java編程語言的控制。4.4.1 變量的聲明及順序1.聲明的順序 因為在JSP頁面的聲明中定義的變量和方法都變成產生的Servlet類的成員,因此它們在頁面中出現的順序無關緊要。程序4.7說明了這一點。 程序4.7 area.jsp 在該例中,盡管半徑r、求面積的方法area()是在使用之后定義的,但頁面仍然能夠轉換、編譯和運行,最后輸出正確結果,如圖4-2所示。2. 小腳本的順序 由于小腳本被轉換成頁面實現類的_j
35、spService()的一部分,因此小腳本中聲明的變量成為該方法的局部變量,故它們出現的順序很重要,下面代碼說明了這一點。 該例中,s1是在聲明中定義的,它成為頁面實現類的成員變量,s與s2是在小腳本中聲明的,它們成為_jspService()的局部變量。s2在聲明之前使用,因此該代碼將不能被編譯。3. 變量的初始化 在Java語言中,實例變量被自動初始化為默認值,而局部變量使用之前必須明確賦值。因此在JSP聲明中聲明的變量被初始化為默認值,而在JSP小腳本中聲明的變量使用之前必須明確初始化,請看下面的代碼。 The value of i is The value of j is 變量i是使用
36、聲明()聲明的,它成為產生的Servlet類的實例變量并被初始化為0。變量j是使用小腳本()聲明的,它變成產生的_jspService()的局部變量并沒有被初始化。 由于Java要求局部變量在使用之前明確初始化,因此上述代碼是非法的且不能編譯。 需要注意的是,實例變量是在容器實例化Servlet時被創(chuàng)建的并只被初始化一次,因此在JSP聲明中聲明的變量在多個請求中一直保持它們的值。而局部變量對每個請求都創(chuàng)建和銷毀一次,因此在小腳本中聲明的變量在多個請求中不保持其值,而是在JSP容器每次調用_jspService()時被重新初始化。 要使上面的代碼能夠編譯,可以像下面這樣初始化變量j。 如果多次訪
37、問上面頁面,i的值將每次增1,輸出一個新值,而j的值總是輸出1。3. 變量的初始化4.4.2 使用條件和循環(huán)語句 小腳本用來在JSP頁面中嵌入計算邏輯,通常這種邏輯包含條件和循環(huán)語句。例如,下面的腳本代碼使用了條件語句檢查用戶的登錄狀態(tài),并基于該狀態(tài)顯示適當的消息。 % String username = request.getParameter(username); String password = request.getParameter(password); boolean isLoggedIn = false;if(username.equals(admin)&passwor
38、d.equals(admin) isLoggedIn = true; else isLoggedIn = false; if(isLoggedIn) out.print(歡迎你,+username+訪問該頁面!); else out.println(你還沒有登錄!); out.println(登錄); % 4.4.2 使用條件和循環(huán)語句 如果在條件語句中包含大量HTML代碼,可以使條件語句跨越JSP頁面多個小腳本,從而避免書寫多個out.println()語句。 歡迎你, 訪問該頁面! 這里可包含其他HTML代碼! 4.4.2 使用條件和循環(huán)語句 你還沒有登錄! 登錄 這里可包含其他HTML代
39、碼! 上面的代碼段中,if-else語句跨越三段小腳本。運行時,如果變量的值為true,則將第一和第二段小腳本之間的HTML代碼包含在輸出中,如果該值為false,則將第二和第三段小腳本之間的HTML代碼包含在輸出中。4.4.2 使用條件和循環(huán)語句 注意,大括號的用途是標記Java編程語言的代碼塊的開始和結束。忽略大括號可能在編譯時產生錯誤,在運行時引起未知行為,例如代碼: 歡迎你, 訪問該頁面! 將被轉換成: if (isLoggedIn) out.write(歡迎你,); out.print(username); out.write(訪問該頁面!);4.4.2 使用條件和循環(huán)語句 與條件語
40、句一樣,循環(huán)語句也可以跨越多段小腳本,使常規(guī)的HTML代碼段處于小腳本之間。下面例子使用循環(huán)計算并輸出100以內的素數。 程序4.8 prime.jsp 該頁面運行結果如圖4-3所示。 上述代碼使用兩段小腳本把HTML代碼包含在循環(huán)中,然后使用JSP表達式輸出素數n,之后輸出兩個空格。4.4.2 使用條件和循環(huán)語句4.4.3 請求時屬性表達式的使用 JSP表達式并不總是寫到頁面的輸出流中,它們也可以用來向JSP動作傳遞屬性值,例如: jsp:include page= / 在該例中,JSP表達式的值并不發(fā)送到輸出流,而是在請求時計算出該值,然后將它賦給動作的page屬性。以這種方式向動作傳遞一
41、個屬性值使用的表達式稱為請求時屬性表達式。4.4.3 請求時屬性表達式的使用 注意,請求時屬性表達式不能用在指令的屬性中,因為指令具有轉換時的語義,即容器僅在頁面轉換期間使用指令。因此,下例中的指令是非法的: % include file= %4.5 JSP隱含變量 在JSP頁面的轉換階段,Web容器在_jspService()中聲明并初始化一些變量,可以在JSP頁面小腳本中或表達式中直接使用這些變量,例如: % out.print(Hello World! ); % 該段小腳本中使用out對象的print()輸出一個字符串。out對象是由容器隱含聲明的,所以一般被稱為隱含對象隱含對象(imp
42、licit objects),這些對象是由容器創(chuàng)建,可象變量一樣使用,因此也被叫做隱隱含變量含變量(implicit variables)。表4-4 JSP頁面中可使用的隱含變量隱含變量 類或接口 說明 application javax.servlet.ServletContext接口 引用Web應用程序上下文 session javax.servlet.http.HttpSession接口 引用用戶會話 request javax.servlet.http.HttpServletRequest接口引用頁面的當前請求對象 response javax.servlet.http.HttpSer
43、vletResponse接口 用來向客戶發(fā)送一個響應 out javax.servlet.jsp.JspWriter類 引用頁面輸出流 page java.lang.Object類 引用頁面的Servlet實例 pageContex javax.servlet.jsp.PageContext類 引用頁面上下文 config javax.servlet.ServletConfig接口 引用Servlet的配置對象 exception java.lang.Throwable類 用來處理錯誤 以todayDate.jsp頁面為例,在轉換階段,Web容器自動將該頁面轉換成一個名為todayDate_j
44、sp.java的類文件,該文件位于workCatalinalocalhosthelloweborgapachejsp目錄中,該文件就是JSP頁面實現類。 程序4.9 todayDate_jsp.java 可以看到在_jspService中聲明了8個變量(加粗字體表示的)。4.5 JSP隱含變量 如果一個頁面是錯誤處理頁面,即頁面中包含下面的page指令。 則頁面實現類中將自動聲明一個exception隱含變量,如下所示。 Throwable exception = (Throwable) request.getAttribute (javax.servlet.jsp.jspException)
45、; 下面詳細討論這9個隱含變量的使用。 注意,這些隱含變量只能在JSP的小腳本和表達式中使用。4.5 JSP隱含變量4.5.1 request與response變量 request是HttpServletRequest類型的隱含變量,response是HttpServletResponse類型的隱含變量,當頁面的Servlet向客戶提供服務時,它們作為參數傳遞給_jspService()。 在JSP頁面中使用它們與在Servlet中使用完全一樣,即用來分析請求和發(fā)送響應,如下代碼所示。 4.5.1 request與response變量 你的IP地址為: 你的主機名為:4.5.2 out變量 o
46、ut是javax.servlet.jsp.JspWriter類型的隱含變量,打印輸出所有的基本數據類型、字符串以及用戶定義的對象??梢栽谛∧_本中直接使用它,也可在表達式中間接使用它產生HTML代碼,例如: 對上面兩行代碼,在頁面實現類中都使用out.print()語句輸出。 下面的腳本使用out變量的print()打印輸出不同類型的數據。 0); out.print(anInt*3.5/100-500); out.print(aFloatObj); out.print(aFloatObj.floatValue(); out.print(aFloatObj.toString(); %4.5.2
47、out變量4.5.3 application變量 application是javax.servlet.ServletContext類型的隱含變量,它是JSP頁面所在的Web應用程序的上下文的引用(ServletContext接口),下面兩段小腳本是等價的。4.5.3 application變量 4.5.4 session變量 session是javax.servlet.http.HttpSession類型的隱含變量,它在JSP頁面中表示會話對象。要使用會話對象,必須要求JSP頁面參加HTTP會話,即要求將JSP頁面的page指令的session屬性值設置為true。 默認情況下,session
48、屬性的值為true。如果明確將session屬性設置為false,容器將不會聲明該變量,對該變量的使用將產生錯誤,如下所示。 會話ID = 4.5.5 pageContext變量 pageContext是javax.servlet.jsp.PageContext類型的隱含變量,它是一個頁面上下文對象。PageContext類是一個抽象類,容器廠商提供了一個具體子類(如JspContext),它有下面三個作用。 4.5.5 pageContext變量 (1)存儲隱含對象的引用。pageContext對象是作為管理所有在JSP頁面中使用的其他對象的一個地方,包括用戶定義的和隱含的對象,并且它提供了
49、一個訪問方法來檢索它們。 (2)提供了在不同作用域內返回或設置屬性的方便的方法。 (3)提供了forward()和include()實現將請求轉發(fā)到另一個資源和將一個資源的輸出包含到當前頁面中的功能,它們的格式如下。 public void include(String relativeURL):將另一個資源的輸出包含在當前頁面的輸出中,與RequestDispatcher()接口的include()功能相同。 public void forward(String relativeURL):將請求轉發(fā)到參數指定的資源,與RequestDispatcher接口的forward()功能相同。4.5
50、.5 pageContext變量 例如,從Servlet中將請求轉發(fā)到另一個資源,需要寫下面兩行代碼。 RequestDispatcher rd = request.getRequestDispatcher(other.jsp); rd.forward(request, response); 在JSP頁面中,通過使用pageContext變量僅需一行就可以完成上述功能。 pageContext.forward(other.jsp);4.5.5 pageContext變量 4.5.6 page變量 page變量是java.lang.Object類型的對象,聲明如下 Object page = t
51、his; 它指的是生成的Servlet實例,該變量很少被使用。4.5.7 config變量 config是javax.servlet.ServletConfig類型的隱含變量。可通過DD文件為Servlet傳遞一組初始化參數,然后在Servlet中使用ServletConfig對象檢索這些參數。 類似地,也可以為JSP頁面?zhèn)鬟f一組初始化參數,這些參數在JSP頁面中可以使用config隱含變量來檢索。4.5.7 config變量 要實現這一點,應首先在DD文件web.xml中使用聲明一個Servlet,然后,使用元素使其與JSP文件關聯。對該命名的Servlet的所有的初始化參數就可以在JSP頁
52、面中通過config隱含變量使用。 initTestServlet / /initTest.jspinitTest.jsp company Beijing New Techonology CO.,LTD email initTestServlet /initTest.jsp 4.5.7 config變量 代碼聲明了一個名為initTestServlet的Servlet并將它映射到/initTest.jsp文件,同時為該Servlet指定了company和email初始化參數,該參數在initTest.jsp文件中使用隱含變量config檢索到,如下所示。 公司名稱: 郵箱地址:4.5.7 co
53、nfig變量4.5.8 exception變量 exception是java.lang.Throwable類型的隱含變量,它被用來作為其他頁面的錯誤處理器。為使頁面能夠使用exception變量,必須在page指令中將isErrorPage的屬性值設置為true,如下所示。 程序4.10 errorPage.jsp 該頁面中,將page指令的isErrorPage屬性設置為true,容器明確定義了exception變量。該變量指向使用該頁面作為錯誤處理器的頁面拋出的未捕獲的java.lang.Throwable對象。4.6 作用域對象 在JSP頁面中有四個作用域對象,它們的類型分別是Servl
54、etContext、HttpSession、HttpServletRequest和PageContext,這四個作用域分別稱為: 應用(application)作用域 會話(session)作用域 請求(request)作用域 頁面(page)作用域, 如表4-5所示。 4.6 作用域對象 在JSP頁面中,所有的隱含對象以及用戶定義的對象都處于這四種作用域之一,這些作用域定義了對象存在性和從JSP頁面和Servlet中的可訪問性。 應用作用域對象具有最大的訪問作用域,頁面作用域對象具有最小的訪問作用域。 作用域名 對應的對象 存在性和可訪問性 應用作用域 application 在整個Web應
55、用程序有效會話作用域 session 在一個用戶會話范圍內有效 請求作用域 request 在用戶的請求和轉發(fā)的請求內有效 頁面作用域 pageContext 只在當前的頁面(轉換單元)內有效 表4-5 JSP作用域對象4.6 作用域對象4.6.1 應用作用域 存儲在應用作用域的對象可被Web應用程序的所有組件共享并在應用程序生命期內都可以訪問。這些對象是通過ServletContext實例作為“屬性/值”對維護的。 在JSP頁面中,該實例可以通過隱含對象application訪問。因此,要在應用程序級共享對象,可以使用ServletContext接口的setAttribute()和getAt
56、tribute()。4.6.1 應用作用域 例如,在Servlet使用下面代碼將對象存儲在應用作用域中: Float one = new Float(42.5) ; ServletContext context = getServletContext(); context.setAttribute(foo, one); 在JSP頁面中就可使用下面代碼訪問context中數據: 4.6.2 會話作用域 存儲在會話作用域的對象可以被屬于一個用戶會話的所有請求共享并只能在會話有效時才可被訪問。 這些對象是通過HttpSession類的一個實例作為“屬性/值”對維護的。在JSP頁面中該實例可以通過隱含
57、對象session訪問。 因此,要在會話級共享對象,可以使用HttpSession接口的setAttribute()和getAttribute()。 4.6.2 會話作用域 在購物車應用中,用戶的購物車對象就應該存放在會話作用域中,它在整個的用戶會話中共享。 HttpSession session = request.getSession(true); ShoppingCart cart = (ShoppingCart)sessionsession.getAttribute(cart); if (cart = null) cart = new ShoppingCart(); / 將購物車存儲到
58、會話對象中 sessionsession.setAttribute(cart, cart); 4.6.3 請求作用域 存儲在請求作用域的對象可以被處理同一個請求的所有組件共享并僅在該請求被服務期間可被訪問。這些對象是由HttpServletRequest對象作為“屬性/值”對維護的。 在JSP頁面中,該實例是通過隱含對象request的形式被使用的。通常,在Servlet中使用請求對象的setAttribute()將一個對象存儲到請求作用域中,然后將請求轉發(fā)到JSP頁面,在JSP頁面中通過腳本或EL取出作用域中的對象。4.6.3 請求作用域 例如,下面代碼在Servlet中創(chuàng)建一個User對象
59、并存儲在請求作用域中,然后將請求轉發(fā)到valid.jsp頁面。User user = new User();user.setName(request.getParameter(name);user.setPassword(request.getParameter(password)request.setAttribute(user, user);RequestDispatcher rd = request.getRequestDispatcher(/valid.jsp);rd.forward(request,response); 下面是valid.jsp文件:4.6.3 請求作用域 這里,va
60、lid.jsp頁面根據數據庫驗證用戶信息,最后根據驗證處理的結果,或者將對象傳輸給會話作用域并將請求轉發(fā)給account.jsp,或者將請求轉發(fā)給loginError.jsp,它可以使用User對象產生一個適當的響應。4.6.3 請求作用域4.6.4 頁面作用域 存儲在頁面作用域的對象只能在它們所定義的轉換單元中被訪問。這些對象是由PageContext抽象類的一個具體子類的一個實例通過屬性/值對維護的。 在JSP頁面中,該實例可以通過隱含對象pageContext訪問。 為在頁面作用域中共享對象,可以使用javax.servlet.jsp.PageContext定義的兩個方法,其格式如下: pub
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 濰坊職業(yè)學院《基礎朝鮮語》2023-2024學年第一學期期末試卷
- 武漢工程科技學院《俄語聽譯》2023-2024學年第二學期期末試卷
- 酒泉職業(yè)技術學院《建筑表現基礎》2023-2024學年第二學期期末試卷
- 江蘇省如皋市達標名校2024-2025學年下學期第一次大考物理試題含解析
- 山東省濟寧兗州區(qū)七校聯考2024-2025學年初三下學期月考試卷(一)化學試題含解析
- 南京航空航天大學《地理與文化》2023-2024學年第一學期期末試卷
- 南京工業(yè)職業(yè)技術大學《工程項目管理軟件》2023-2024學年第二學期期末試卷
- 遼寧科技大學《體育鍛煉指導(三)》2023-2024學年第二學期期末試卷
- 內蒙古自治區(qū)根河市2025屆第二學期初三年級期末統一考試物理試題含解析
- 武漢軟件工程職業(yè)學院《心理統計與SPSS》2023-2024學年第二學期期末試卷
- 醫(yī)院患者診療信息安全風險評估和應急工作機制制定應急預案XX醫(yī)院患者診療信息安全風險應急預案
- 計算機科學與技術本科生畢業(yè)論文——基于Web的醫(yī)院預約掛號系統的設計與實現
- 老年智能手環(huán)產品需求說明書(PRD)
- T∕AOPA 0018-2021 直升機臨時起降場選址與建設規(guī)范
- 高考英語高頻688詞匯(核心版本)
- 七八年級人教古詩詞集錦
- 涪陵榨菜集團盈利能力分析工商管理專業(yè)
- 35kv配電系統繼電保護方案設計(共33頁)
- 中國收藏家協會個人會員入會申請表
- 醫(yī)院處方箋模板
- 底盤拆裝與調試教案
評論
0/150
提交評論