通過避免使用腳本編制元素來簡化對(duì) JSP 應(yīng)用程序的軟件維護(hù)
![]() |
|
級(jí)別: 初級(jí)
Mark A. Kolb
(mak@taglib.com), 軟件工程師
2003 年 5 月 27 日
JSP 標(biāo)準(zhǔn)標(biāo)記庫(JSP Standard Tag Library,JSTL)是一個(gè)實(shí)現(xiàn) Web 應(yīng)用程序中常見的通用功能的定制標(biāo)記庫集,這些功能包括迭代和條件判斷、數(shù)據(jù)管理格式化、XML 操作以及數(shù)據(jù)庫訪問。在 developerWorks 上其新系列的第一篇文章中,軟件工程師 Mark Kolb 向您展示了如何使用 JSTL 標(biāo)記來避免在 JSP 頁面中使用腳本編制元素。您還將了解如何通過從表示層刪除源代碼來簡化軟件維護(hù)。最后,您將了解 JSTL 經(jīng)過簡化的表達(dá)式語言,它允許在不必使用功能齊全的編程語言的情況下對(duì) JSTL 操作指定動(dòng)態(tài)屬性值。
JavaServer Pages(JSP)是用于 J2EE 平臺(tái)的標(biāo)準(zhǔn)表示層技術(shù)。JSP 技術(shù)提供了用于執(zhí)行計(jì)算(這些計(jì)算用來動(dòng)態(tài)地生成頁面內(nèi)容)的腳本編制元素和操作。腳本編制元素允許在 JSP 頁面中包括程序源代碼,在為響應(yīng)用戶請(qǐng)求而呈現(xiàn)頁面時(shí)可以執(zhí)行這些源代碼。操作將計(jì)算操作封裝到很象 HTML 或 XML 標(biāo)記的標(biāo)記中,JSP 頁面的模板文本通常包含這些標(biāo)記。JSP 規(guī)范只將幾種操作定義成了標(biāo)準(zhǔn),但從 JSP 1.1 開始,開發(fā)人員已經(jīng)能夠以定制標(biāo)記庫的方式創(chuàng)建其自己的操作了。
JSP 標(biāo)準(zhǔn)標(biāo)記庫(JSTL)是 JSP 1.2 定制標(biāo)記庫集,這些標(biāo)記庫實(shí)現(xiàn)大量服務(wù)器端 Java 應(yīng)用程序常用的基本功能。通過為典型表示層任務(wù)(如數(shù)據(jù)格式化和迭代或條件內(nèi)容)提供標(biāo)準(zhǔn)實(shí)現(xiàn),JSTL 使 JSP 作者可以專注于特定于應(yīng)用程序的開發(fā)需求,而不是為這些通用操作“另起爐灶”。
當(dāng)然,您可以使用 JSP 腳本編制元素(scriptlet、表達(dá)式和聲明)來實(shí)現(xiàn)此類任務(wù)。例如,可以使用三個(gè) scriptlet 實(shí)現(xiàn)條件內(nèi)容,清單 1 中著重顯示了這三個(gè) scriptlet。但是,因?yàn)槟_本編制元素依賴于在頁面中嵌入程序源代碼(通常是 Java 代碼),所以對(duì)于使用這些腳本編制元素的 JSP 頁面,其軟件維護(hù)任務(wù)的復(fù)雜度大大增加了。例如,清單 1 中的 scriptlet 示例嚴(yán)格地依賴于花括號(hào)的正確匹配。如果不經(jīng)意間引入了一個(gè)語法錯(cuò)誤,則條件內(nèi)容中的嵌套其它 scriptlet 可能會(huì)造成嚴(yán)重破壞,并且在 JSP 容器編譯該頁面時(shí),要使所產(chǎn)生的錯(cuò)誤信息有意義可能會(huì)很困難。
<% if (user.getRole() == "member")) { %> <p>Welcome, member!</p> <% } else { %> <p>Welcome, guest!</p> <% } %> |
修正此類問題通常需要相當(dāng)豐富的編程經(jīng)驗(yàn)。盡管通常會(huì)由十分精通頁面布局和圖形設(shè)計(jì)的設(shè)計(jì)人員來開發(fā)和維護(hù) JSP,但是同一頁面中的腳本編制元素出現(xiàn)問題時(shí),需要程序員的介入。這種狀況將單個(gè)文件中代碼的責(zé)任分擔(dān)給多人,因而使得開發(fā)、調(diào)試和增強(qiáng)此類 JSP 頁面成為很麻煩的任務(wù)。通過將常用功能包裝到定制標(biāo)記庫的標(biāo)準(zhǔn)集合中,JSTL 使 JSP 作者可以減少對(duì)編制腳本元素的需求,甚至可以不需要它們,并避免了相關(guān)的維護(hù)成本。
![]() ![]() |
![]() |
JSTL 1.0 發(fā)布于 2002 年 6 月,由四個(gè)定制標(biāo)記庫( core
、 format
、 xml
和 sql
)和一對(duì)通用標(biāo)記庫驗(yàn)證器( ScriptFreeTLV
和 PermittedTaglibsTLV
)組成。 core
標(biāo)記庫提供了定制操作,通過限制了作用域的變量管理數(shù)據(jù),以及執(zhí)行頁面內(nèi)容的迭代和條件操作。它還提供了用來生成和操作 URL 的標(biāo)記。顧名思義, format
標(biāo)記庫定義了用來格式化數(shù)據(jù)(尤其是數(shù)字和日期)的操作。它還支持使用本地化資源束進(jìn)行 JSP 頁面的國際化。 xml
庫包含一些標(biāo)記,這些標(biāo)記用來操作通過 XML 表示的數(shù)據(jù),而 sql
庫定義了用來查詢關(guān)系數(shù)據(jù)庫的操作。
兩個(gè) JSTL 標(biāo)記庫驗(yàn)證器允許開發(fā)人員在其 JSP 應(yīng)用程序中強(qiáng)制使用編碼標(biāo)準(zhǔn)。可以配置 ScriptFreeTLV
驗(yàn)證器以在 JSP 頁面中禁用各種類型的 JSP 腳本元素 ― scriptlet、表達(dá)式和聲明。類似地, PermittedTaglibsTLV
驗(yàn)證器可以用來限制可能由應(yīng)用程序的 JSP 頁面訪問的定制標(biāo)記庫集(包括 JSTL 標(biāo)記庫)。
盡管 JSTL 最終將會(huì)成為 J2EE 平臺(tái)的必需組件,但目前只有少數(shù)應(yīng)用程序服務(wù)器包括它。JSTL 1.0 的參考實(shí)現(xiàn)可作為 Apache 軟件基金會(huì)(Apache Software Foundation)的 Jakarta Taglibs 項(xiàng)目(請(qǐng)參閱 參考資料)的一部分而獲得。可以將該參考實(shí)現(xiàn)中的定制標(biāo)記庫合并到任何支持 JSP 1.2 和 Servlet 2.3 規(guī)范的服務(wù)器,以添加對(duì) JSTL 的支持。
![]() ![]() |
![]()
|
在 JSP 1.2 中,可以使用靜態(tài)字符串或表達(dá)式(如果允許的話)指定 JSP 操作的屬性。例如,在清單 2 中,對(duì) <jsp:setProperty>
操作的 name
和 property
屬性指定了靜態(tài)值,而用表達(dá)式指定了其 value
屬性。這個(gè)操作的效果是將請(qǐng)求參數(shù)的當(dāng)前值賦予命名的 bean 特性。以這種形式使用的表達(dá)式被稱為 請(qǐng)求時(shí)屬性值(request-time attribute value),這是構(gòu)建到 JSP 規(guī)范中的用于動(dòng)態(tài)指定屬性值的唯一機(jī)制。
<jsp:setProperty name="user" property="timezonePref" value='<%= request.getParameter("timezone") %>'/> |
因?yàn)檎?qǐng)求時(shí)屬性值是用表達(dá)式指定的,所以它們往往有和其它腳本元素一樣的軟件維護(hù)問題。因此,JSTL 定制標(biāo)記支持另一種用于指定動(dòng)態(tài)屬性值的機(jī)制。可以用簡化的 表達(dá)式語言(EL)而不使用完整的 JSP 表達(dá)式來指定 JSTL 操作的屬性值。EL 提供了一些標(biāo)識(shí)符、存取器和運(yùn)算符,用來檢索和操作駐留在 JSP 容器中的數(shù)據(jù)。EL 在某種程度上以 EcmaScript(請(qǐng)參閱 參考資料)和 XML 路徑語言(XML Path Language,XPath)為基礎(chǔ),因此頁面設(shè)計(jì)人員和程序員都應(yīng)該熟悉它的語法。EL 擅長尋找對(duì)象及其特性,然后對(duì)它們執(zhí)行簡單操作;它不是編程語言,甚至不是腳本編制語言。但是,與 JSTL 標(biāo)記一起使用時(shí),它就能使用簡單而又方便的符號(hào)來表示復(fù)雜的行為。EL 表達(dá)式的格式是這樣的:用美元符號(hào)($)定界,內(nèi)容包括在花括號(hào)({})中,如清單 3 所示。
<c:out value="${user.firstName}"/> |
此外,您可以將多個(gè)表達(dá)式與靜態(tài)文本組合在一起以通過字符串并置來構(gòu)造動(dòng)態(tài)屬性值,如清單 4 所示。單獨(dú)的表達(dá)式由標(biāo)識(shí)符、存取器、文字和運(yùn)算符組成。標(biāo)識(shí)符用來引用存儲(chǔ)在數(shù)據(jù)中心中的數(shù)據(jù)對(duì)象。EL 有 11 個(gè)保留標(biāo)識(shí)符,對(duì)應(yīng)于 11 個(gè) EL 隱式對(duì)象。假定所有其它標(biāo)識(shí)符都引用 限制了作用域的變量。存取器用來檢索對(duì)象的特性或集合的元素。文字表示固定的值 ― 數(shù)字、字符、字符串、布爾型或空值。運(yùn)算符允許對(duì)數(shù)據(jù)和文字進(jìn)行組合以及比較。
<c:out value="Hello ${user.firstName} ${user.lastName}"/> |
JSP API 通過 <jsp:useBean>
操作允許從 JSP 容器內(nèi)的四個(gè)不同作用域中存儲(chǔ)和檢索數(shù)據(jù)。JSTL 通過提供用于指定和除去這些作用域中的對(duì)象的附加操作來擴(kuò)展這一能力。此外,EL 提供將這些對(duì)象作為限制了作用域的變量進(jìn)行檢索的內(nèi)置支持。特別地,任何出現(xiàn)在 EL 表達(dá)式中但不對(duì)應(yīng)于任何 EL 隱式對(duì)象的標(biāo)識(shí)符,都被自動(dòng)假定為引用存儲(chǔ)在四個(gè) JSP 作用域的其中某個(gè)中的對(duì)象,這四個(gè)作用域是:
您可能還記得,只有在為特定請(qǐng)求處理頁面期間才能檢索存儲(chǔ)在該頁面作用域中的對(duì)象。如果對(duì)象是存儲(chǔ)在請(qǐng)求作用域中的,可以在處理所有參與處理某請(qǐng)求的頁面期間檢索這些對(duì)象(譬如在對(duì)某個(gè)請(qǐng)求的處理中遇到了一個(gè)或多個(gè) <jsp:include>
或 <jsp:forward>
操作)。如果對(duì)象是存儲(chǔ)在會(huì)話作用域中的,則在與 Web 應(yīng)用程序的交互式會(huì)話期間,可以由用戶訪問的任何頁面檢索它(即,直到與該用戶交互相關(guān)聯(lián)的 HttpSession
對(duì)象無效為止)。可以由任何用戶從任何頁面訪問存儲(chǔ)在應(yīng)用程序作用域中的對(duì)象,直到卸載 Web 應(yīng)用程序本身為止(通常是由于關(guān)閉 JSP 容器所致)。
通過將字符串映射為期望作用域中的對(duì)象來將對(duì)象存儲(chǔ)到該作用域。然后,就可以通過提供相同字符串來從該作用域檢索該對(duì)象。在作用域的映射中查找字符串,并返回被映射的對(duì)象。在 Servlet API 中,將此類對(duì)象稱為相應(yīng)作用域的 屬性。但是,在 EL 的上下文中,也將與屬性相關(guān)聯(lián)的字符串看作變量的名稱,該變量通過屬性映射的方式獲得特定的值。
在 EL 中,與隱式對(duì)象無關(guān)聯(lián)的標(biāo)識(shí)符被認(rèn)為是存儲(chǔ)在四個(gè) JSP 作用域中的名稱對(duì)象。首先對(duì)頁面作用域檢查是否存在這樣的標(biāo)識(shí)符,其次對(duì)請(qǐng)求作用域、然后對(duì)會(huì)話作用域、最后對(duì)應(yīng)用程序作用域依次進(jìn)行這樣的檢查,然后測試該標(biāo)識(shí)符的名稱是否與存儲(chǔ)在該作用域中的某個(gè)對(duì)象的名稱匹配。第一個(gè)這樣的匹配作為 EL 標(biāo)識(shí)符的值被返回。通過這種方法,可以將 EL 標(biāo)識(shí)符看作引用限制了作用域的變量。
從更技術(shù)的方面來說,沒有映射到隱式對(duì)象的標(biāo)識(shí)符是用 PageContext
實(shí)例的 findAttribute()
方法求值的,該實(shí)例表示對(duì)頁面的處理,在該頁面上,當(dāng)前正在處理用于請(qǐng)求的表達(dá)式。標(biāo)識(shí)符的名稱作為參數(shù)傳遞給這個(gè)方法,然后該方法依次在四個(gè)作用域中搜索具有相同名稱的屬性。并將所找到的第一個(gè)匹配項(xiàng)作為 findAttribute()
方法的值返回。如果未在這四個(gè)作用域中找到這樣的屬性,則返回 null
。
最終,限制了作用域的變量是四個(gè) JSP 作用域的屬性,這些屬性具有可以用作 EL 標(biāo)識(shí)符的名稱。只要對(duì)限制了作用域的變量賦予由字母數(shù)字組成的名稱,就可以通過 JSP 中提供的用于設(shè)置屬性的任何機(jī)制來創(chuàng)建它們。這包括內(nèi)置的 <jsp:useBean>
操作,以及由 Servlet API 中的幾個(gè)類定義的 setAttribute()
方法。此外,四個(gè) JSTL 庫中定義的許多定制標(biāo)記本身就能夠設(shè)置作為限制了作用域的變量使用的屬性值。
表 1 中列出了 11 個(gè) EL 隱式對(duì)象的標(biāo)識(shí)符。不要將這些對(duì)象與 JSP 隱式對(duì)象(一共只有九個(gè))混淆,其中只有一個(gè)對(duì)象是它們所共有的。
類別 | 標(biāo)識(shí)符 | 描述 |
JSP |
pageContext
|
PageContext 實(shí)例對(duì)應(yīng)于當(dāng)前頁面的處理 |
作用域 |
pageScope
|
與頁面作用域?qū)傩缘拿Q和值相關(guān)聯(lián)的 Map 類 |
requestScope
|
與請(qǐng)求作用域?qū)傩缘拿Q和值相關(guān)聯(lián)的 Map 類 |
|
sessionScope
|
與會(huì)話作用域?qū)傩缘拿Q和值相關(guān)聯(lián)的 Map 類 |
|
applicationScope
|
與應(yīng)用程序作用域?qū)傩缘拿Q和值相關(guān)聯(lián)的 Map 類 |
|
請(qǐng)求參數(shù) |
param
|
按名稱存儲(chǔ)請(qǐng)求參數(shù)的主要值的 Map 類 |
paramValues
|
將請(qǐng)求參數(shù)的所有值作為 String 數(shù)組存儲(chǔ)的 Map 類 |
|
請(qǐng)求頭 |
header
|
按名稱存儲(chǔ)請(qǐng)求頭主要值的 Map 類 |
headerValues
|
將請(qǐng)求頭的所有值作為 String 數(shù)組存儲(chǔ)的 Map 類 |
|
Cookie |
cookie
|
按名稱存儲(chǔ)請(qǐng)求附帶的 cookie 的 Map 類 |
初始化參數(shù) |
initParam
|
按名稱存儲(chǔ) Web 應(yīng)用程序上下文初始化參數(shù)的 Map 類 |
盡管 JSP 和 EL 隱式對(duì)象中只有一個(gè)公共對(duì)象( pageContext
),但通過 EL 也可以訪問其它 JSP 隱式對(duì)象。原因是 pageContext
擁有訪問所有其它八個(gè) JSP 隱式對(duì)象的特性。實(shí)際上,這是將它包括在 EL 隱式對(duì)象中的主要理由。
其余所有 EL 隱式對(duì)象都是映射,可以用來查找對(duì)應(yīng)于名稱的對(duì)象。前四個(gè)映射表示先前討論的各種屬性作用域。可以用它們來查找特定作用域中的標(biāo)識(shí)符,而不用依賴于 EL 在缺省情況下使用的順序查找過程。
接下來的四個(gè)映射用來獲取請(qǐng)求參數(shù)和請(qǐng)求頭的值。因?yàn)?HTTP 協(xié)議允許請(qǐng)求參數(shù)和請(qǐng)求頭具有多個(gè)值,所以它們各有一對(duì)映射。每對(duì)中的第一個(gè)映射返回請(qǐng)求參數(shù)或頭的主要值,通常是恰巧在實(shí)際請(qǐng)求中首先指定的那個(gè)值。每對(duì)中第二個(gè)映射允許檢索參數(shù)或頭的所有值。這些映射中的鍵是參數(shù)或頭的名稱,但這些值是 String
對(duì)象的數(shù)組,其中的每個(gè)元素都是單一參數(shù)值或頭值。
cookie 隱式對(duì)象提供了對(duì)由請(qǐng)求設(shè)置的 cookie 名稱的訪問。這個(gè)對(duì)象將所有與請(qǐng)求相關(guān)聯(lián)的 cookie 名稱映射到表示那些 cookie 特性的 Cookie
對(duì)象。
最后一個(gè) EL 隱式對(duì)象 initParam
是一個(gè)映射,它儲(chǔ)存與 Web 應(yīng)用程序相關(guān)聯(lián)的所有上下文的初始化參數(shù)的名稱和值。初始化參數(shù)是通過 web.xml
部署描述符文件指定的,該文件位于應(yīng)用程序的 WEB-INF
目錄中。
因?yàn)?EL 標(biāo)識(shí)符是作為隱式對(duì)象或限制了作用域的變量(通過屬性來實(shí)現(xiàn))解析的,因此有必要將它們轉(zhuǎn)換成 Java 對(duì)象。EL 可以自動(dòng)包裝和解包其相應(yīng)的 Java 類中的基本類型(例如,可以在后臺(tái)將 int
強(qiáng)制轉(zhuǎn)換成 Integer
類,反之亦可),但大多數(shù)的標(biāo)識(shí)符將成為指向完整的 Java 對(duì)象的指針。
結(jié)果是,對(duì)這些對(duì)象的特性或(在對(duì)象是數(shù)組和集合的情況下)對(duì)其元素的訪問通常是令人滿意的。就為了實(shí)現(xiàn)這種用途,EL 提供了兩種不同的存取器(點(diǎn)運(yùn)算符( .
)和方括號(hào)運(yùn)算符( []
)),也支持通過 EL 操作特性和元素。
點(diǎn)運(yùn)算符通常用于訪問對(duì)象的特性。例如,在表達(dá)式 ${user.firstName}
中,使用點(diǎn)運(yùn)算符來訪問 user
標(biāo)識(shí)符所引用對(duì)象的名為 firstName
的特性。EL 使用 Java bean 約定訪問對(duì)象特性,因此必須定義這個(gè)特性的 getter 方法(通常是名為 getFirstName()
的方法),以便表達(dá)式正確求值。當(dāng)被訪問的特性本身是對(duì)象時(shí),可以遞歸地應(yīng)用點(diǎn)運(yùn)算符。例如,如果我們虛構(gòu)的 user
對(duì)象有一個(gè)實(shí)現(xiàn)為 Java 對(duì)象的 address
特性,那么也可以用點(diǎn)運(yùn)算符來訪問這個(gè)對(duì)象的特性。例如,表達(dá)式 ${user.address.city}
將會(huì)返回這個(gè)地址對(duì)象嵌套的 city
特性。
方括號(hào)運(yùn)算符用來檢索數(shù)組和集合的元素。在數(shù)組和有序集合(也即,實(shí)現(xiàn)了 java.util.List
接口的集合)的情況下,把要檢索的元素的下標(biāo)放在方括號(hào)中。例如,表達(dá)式 ${urls[3]}
返回 urls
標(biāo)識(shí)符所引用的數(shù)組或集合的第四個(gè)元素(和 Java 語言以及 JavaScript 中一樣,EL 中的下標(biāo)是從零開始的)。
對(duì)于實(shí)現(xiàn) java.util.Map
接口的集合,方括號(hào)運(yùn)算符使用關(guān)聯(lián)的鍵查找存儲(chǔ)在映射中的值。在方括號(hào)中指定鍵,并將相應(yīng)的值作為表達(dá)式的值返回。例如,表達(dá)式 ${commands["dir"]}
返回與 commands
標(biāo)識(shí)符所引用的 Map
中的 "dir"
鍵相關(guān)聯(lián)的值。
對(duì)于上述兩種情況,都可允許表達(dá)式出現(xiàn)在方括號(hào)中。對(duì)嵌套表達(dá)式求值的結(jié)果將被作為下標(biāo)或鍵,用來檢索集合或數(shù)組的適當(dāng)元素。和點(diǎn)運(yùn)算符一樣,方括號(hào)運(yùn)算符也可以遞歸應(yīng)用。這使得 EL 能夠從多維數(shù)組、嵌套集合或兩者的任意組合中檢索元素。此外,點(diǎn)運(yùn)算符和方括號(hào)運(yùn)算符還可以互操作。例如,如果數(shù)組的元素本身是對(duì)象,則可以使用方括號(hào)運(yùn)算符來檢索該數(shù)組的元素,并結(jié)合點(diǎn)運(yùn)算符來檢索該元素的一個(gè)特性(例如 ${urls[3].protocol}
)。
假定 EL 充當(dāng)指定動(dòng)態(tài)屬性值的簡化語言,EL 存取器有一個(gè)有趣的功能(與 Java 語言的存取器不同),那就是它們在應(yīng)用于 null
時(shí)不拋出異常。如果應(yīng)用 EL 存取器的對(duì)象(例如, ${foo.bar}
和 ${foo["bar"]}
中的 foo
標(biāo)識(shí)符)是 null
,那么應(yīng)用存取器的結(jié)果也是 null
。事實(shí)證明,在大多數(shù)情況下,這是一個(gè)相當(dāng)有用的行為,不久您就會(huì)了解這一點(diǎn)。
最后,點(diǎn)運(yùn)算符和方括號(hào)運(yùn)算符可能實(shí)現(xiàn)某種程度的互換。例如,也可以使用 ${user["firstName"]}
來檢索 user
對(duì)象的 firstName
特性,正如可以用 ${commands.dir}
獲取與 commands
映射中的 "dir"
鍵相關(guān)聯(lián)的值一樣。
EL 還可以通過使用標(biāo)識(shí)符和存取器,遍歷包含應(yīng)用程序數(shù)據(jù)(通過限制了作用域的變量公開)或關(guān)于環(huán)境的信息(通過 EL 隱式對(duì)象)的對(duì)象層次結(jié)構(gòu)。但是,只是訪問這些數(shù)據(jù),通常不足以實(shí)現(xiàn)許多 JSP 應(yīng)用程序所需的表示邏輯。
最終,EL 還包括了幾個(gè)用來操作和比較 EL 表達(dá)式所訪問數(shù)據(jù)的運(yùn)算符。表 2 中匯總了這些運(yùn)算符。
類別 | 運(yùn)算符 |
算術(shù)運(yùn)算符 |
+ 、 - 、 * 、 / (或 div )和 % (或 mod ) |
關(guān)系運(yùn)算符 |
== (或 eq )、 != (或 ne )、 < (或 lt )、 > (或 gt )、 <= (或 le )和 >= (或 ge ) |
邏輯運(yùn)算符 |
&& (或 and )、 || (或 or )和 ! (或 not ) |
驗(yàn)證運(yùn)算符 |
empty
|
算術(shù)運(yùn)算符支持?jǐn)?shù)值的加法、減法、乘法和除法。還提供了一個(gè)求余運(yùn)算符。注:除法和求余運(yùn)算符都有替代的、非符號(hào)的名稱(為的是與 XPath 保持一致)。清單 5 中顯示了一個(gè)演示算術(shù)運(yùn)算符用法的示例表達(dá)式。對(duì)幾個(gè) EL 表達(dá)式應(yīng)用算術(shù)運(yùn)算符的結(jié)果是將該算術(shù)運(yùn)算符應(yīng)用于這些表達(dá)式返回的數(shù)值所得的結(jié)果。
${item.price * (1 + taxRate[user.address.zipcode])} |
關(guān)系運(yùn)算符允許比較數(shù)字或文本數(shù)據(jù)。比較的結(jié)果作為布爾值返回。邏輯運(yùn)算符允許合并布爾值,返回新的布爾值。因此,可以將 EL 邏輯運(yùn)算符應(yīng)用于嵌套的關(guān)系或邏輯運(yùn)算符的結(jié)果,如清單 6 所示。
${(x >= min) && (x <= max)} |
最后一種 EL 運(yùn)算符是 empty
,它對(duì)于驗(yàn)證數(shù)據(jù)特別有用。 empty
運(yùn)算符采用單個(gè)表達(dá)式作為其變量(也即, ${empty input}
),并返回一個(gè)布爾值,該布爾值表示對(duì)表達(dá)式求值的結(jié)果是不是“空”值。求值結(jié)果為 null
的表達(dá)式被認(rèn)為是空,即無元素的集合或數(shù)組。如果參數(shù)是對(duì)長度為零的 String
求值所得的結(jié)果,則 empty
運(yùn)算符也將返回 true
。
表 3 顯示了 EL 運(yùn)算符的優(yōu)先級(jí)。正如清單 5 和 6 所示,可以用圓括號(hào)對(duì)表達(dá)式分組,高于普通的優(yōu)先級(jí)規(guī)則。
表 3. EL 運(yùn)算符優(yōu)先級(jí)(自頂?shù)降祝瑥淖蟮接遥?/font>
[] , . |
()
|
unary - 、 not 、 ! 、 empty |
* 、 / 、 div 、 % 、 mod |
+ 、binary - |
() <</code> 、 > 、 <= 、 >= 、 lt 、 gt 、 le 、 ge |
== 、 != 、 eq 、 ne |
&& 、 and |
|| 、 or |
在 EL 表達(dá)式中,數(shù)字、字符串、布爾值和 null
都可以被指定為文字值。字符串可以用單引號(hào)或雙引號(hào)定界。布爾值被指定為 true
和 false
。
正如我們先前討論的,JSTL 1.0 包括四個(gè)定制標(biāo)記庫。為了演示 JSTL 標(biāo)記和表達(dá)式語言的交互,我們將研究幾個(gè)來自 JSTL core
庫的標(biāo)記。和使用任何 JSP 定制標(biāo)記庫一樣,必須在您想要使用這個(gè)庫標(biāo)記的任何頁面中包括 taglib
偽指令。清單 7 顯示了用于這個(gè)特定庫的偽指令。
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> |
實(shí)際上,對(duì)應(yīng)于 JSTL core
庫的 taglib
偽指令有兩種,因?yàn)樵?JSTL 1.0 中,EL 是可選的。所有四個(gè) JSTL 1.0 定制標(biāo)記庫都有使用 JSP 表達(dá)式(而不是 EL)指定動(dòng)態(tài)屬性值的備用版本。因?yàn)檫@些備用庫依賴于 JSP 的更傳統(tǒng)的請(qǐng)求時(shí)屬性值,所以它們被稱為 RT庫,而那些使用表達(dá)式語言的則被稱為 EL 庫。開發(fā)人員用不同的 taglib
偽指令來區(qū)分每個(gè)庫的這兩個(gè)版本。清單 8 顯示了使用 core 庫的 RT 版本的偽指令。但是,由于現(xiàn)在我們討論的重點(diǎn)是 EL,所以首先需要這些偽指令。
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c_rt" %> |
我們首先要考慮的 JSTL 定制標(biāo)記是 <c:set>
操作。正如已經(jīng)說明的,限制了作用域的變量在 JSTL 中起關(guān)鍵作用, <c:set>
操作提供基于標(biāo)記的機(jī)制來創(chuàng)建和設(shè)置限制了作用域的變量。清單 9 中顯示了該操作的語法,其中 var
屬性指定了限制了作用域的變量的名稱, scope
屬性表明了該變量駐留在哪個(gè)作用域中, value
屬性指定了分配給該變量的值。如果指定變量已經(jīng)存在,則簡單地將所指明的值賦給它。如果不存在,則創(chuàng)建新的限制了作用域的變量,并用該值初始化這個(gè)變量。
<c:set var=" name" scope=" scope" value=" expression"/> |
scope
屬性是可選的,其缺省值是 page
。
清單 10 中顯示了 <c:set>
的兩個(gè)示例。在第一個(gè)示例中,將會(huì)話作用域變量設(shè)置成 String
值。在第二個(gè)示例中,用表達(dá)式來設(shè)置數(shù)值:將頁面作用域內(nèi)名為 square
的變量賦值為名為 x
的請(qǐng)求參數(shù)的值的平方。
<c:set var="timezone" scope="session" value="CST"/> <c:set var="square" value="${param['x'] * param['x']}"/> |
您還可以將限制了作用域的變量的值指定為 <c:set>
操作的主體內(nèi)容,而不是使用屬性。使用這種方法,您可以重新編寫清單 10 中的第一個(gè)示例,如清單 11 所示。此外,正如我們馬上可以看到的, <c:set>
標(biāo)記的主體內(nèi)容本身也可以使用定制標(biāo)記。 <c:set>
主體內(nèi)生成的所有內(nèi)容都將作為一個(gè) String
值賦給指定變量。
<c:set var="timezone" scope="session">CST</c:set> |
JSTL core 庫包含第二個(gè)用于管理限制了作用域的變量的標(biāo)記 ― <c:remove>
。顧名思義, <c:remove>
操作是用來刪除限制了作用域的變量的,它獲取兩個(gè)屬性。 var
屬性指定待刪除變量的名稱, scope
屬性是可選的,它表示待刪除變量來自哪個(gè)作用域,缺省為 page
,如清單 12 所示。
<c:remove var="timezone" scope="session"/> |
盡管 <c:set>
操作允許將表達(dá)式結(jié)果賦給限制了作用域的變量,但開發(fā)人員通常會(huì)希望只顯示表達(dá)式的值,而不存儲(chǔ)它。JSTL <c:out>
定制標(biāo)記承擔(dān)這一任務(wù),其語法如清單 13 所示。該標(biāo)記對(duì)由其 value
屬性指定的表達(dá)式進(jìn)行求值,然后打印結(jié)果。如果指定了可選屬性 default
,那么,在對(duì) value
屬性的表達(dá)式求值所得結(jié)果為 null
或空 String
的情況下, <c:out>
將打印其值。
<c:out value=" expression" default=" expression" escapeXml=" boolean"/> |
escapeXml
屬性也是可選的。它控制當(dāng)用 <c:out>
標(biāo)記輸出諸如“<”、“>”和“&”之類的字符(在 HTML 和 XML 中具有特殊意義)時(shí)是否應(yīng)該進(jìn)行轉(zhuǎn)義。如果將 escapeXml
設(shè)置為 true,則會(huì)自動(dòng)將這些字符轉(zhuǎn)換成相應(yīng)的 XML 實(shí)體(此處提到的字符分別轉(zhuǎn)換成 <
、 >
和 &
)。
例如,假定有一個(gè)名為 user
的會(huì)話作用域變量,它是一個(gè)類的實(shí)例,該類為用戶定義了兩個(gè)特性: username
和 company
。每當(dāng)用戶訪問站點(diǎn)時(shí),這個(gè)對(duì)象被自動(dòng)分配給會(huì)話,但直到用戶實(shí)際登錄后,才會(huì)設(shè)置這兩個(gè)特性。假定是這種方案,請(qǐng)考慮清單 14 中的 JSP 片段。在用戶登錄之后,這個(gè)片段將顯示單詞“Hello”,其后是他/她的用戶名和一個(gè)驚嘆號(hào)。但是,在用戶登錄之前,由這個(gè)片段生成的內(nèi)容則是短語“Hello Guest!”。在這種情況下,因?yàn)?username
特性還有待初始化,所以 <c:out>
標(biāo)記將轉(zhuǎn)而打印出 default
屬性的值(即字符串“Guest”)。
Hello <c:out value="${user.username}" default=="Guest"/>! |
接下來,考慮清單 15,它使用了 <c:out>
標(biāo)記的 escapeXml
屬性。如果在這種情況下已經(jīng)將 company
特性設(shè)置成 Java String
值 "Flynn & Sons"
,那么,實(shí)際上該操作生成的內(nèi)容將是 Flynn & Sons
。如果這個(gè)操作是生成 HTML 或 XML 內(nèi)容的 JSP 頁面的一部分,那么,這個(gè)字符串中間的“&”符號(hào)最終可能被解釋為 HTML 或 XML 控制字符,從而妨礙了對(duì)該內(nèi)容的顯示或解析。但是,如果將 escapeXml
屬性值設(shè)置成 true
,則所生成的內(nèi)容將是 Flynn & Sons
。瀏覽器或解析器不會(huì)因在解釋時(shí)遇到這種內(nèi)容而出問題。假定 HTML 和 XML 是 JSP 應(yīng)用程序中最常見的內(nèi)容類型,所以 escapeXml
屬性的缺省值是 true
就不足為奇了。
<c:out value="${user.company}" escapeXml=="false"/> |
除了簡化動(dòng)態(tài)數(shù)據(jù)的顯示之外,當(dāng)通過 <c:set>
設(shè)置變量值時(shí), <c:out>
指定缺省值的能力也很有用。正如 清單 11 所示,用來賦給限制了作用域的變量的值可以指定為 <c:set>
標(biāo)記的主體內(nèi)容,也可以通過其值屬性來指定。通過將 <c:out>
操作嵌套在 <c:set>
標(biāo)記的主體內(nèi)容中,變量賦值就可以利用其缺省值能力。
清單 16 中說明了這種方法。外部 <c:set>
標(biāo)記的行為非常簡單:它根據(jù)其主體內(nèi)容設(shè)置會(huì)話作用域 timezone
變量的值。但是,在這種情況下,主體內(nèi)容是通過 <c:out>
操作生成的。這個(gè)嵌套操作的值屬性是表達(dá)式 ${cookie['tzPref'].value}
,它嘗試通過 cookie
隱式對(duì)象返回名為 tzPref
的 cookie 值。( cookie
隱式對(duì)象將 cookie 名稱映射到相應(yīng)的 Cookie
實(shí)例,這意味著必須通過對(duì)象的 value
特性使用點(diǎn)運(yùn)算符來檢索儲(chǔ)存在 cookie 中的實(shí)際數(shù)據(jù)。)
<c:set var="timezone" scope=="session"> <c:out value="${cookie['tzPref'].value}" default=="CST"/> </c:set> |
但是,請(qǐng)考慮以下情況,用戶是第一次嘗試使用這段代碼的 Web 應(yīng)用程序。結(jié)果是,請(qǐng)求中沒有提供名為 tzPref
的 cookie。這意味著使用隱式對(duì)象的查找將返回 null
,在這種情況下整個(gè)表達(dá)式將返回 null
。因?yàn)閷?duì) <c:out>
標(biāo)記的 value
屬性求值的結(jié)果是 null
,所以 <c:out>
標(biāo)記會(huì)轉(zhuǎn)而輸出對(duì)其 default
屬性求值的結(jié)果。在這里是字符串 CST
。因此,實(shí)際的結(jié)果是將 timezone
限制了作用域的變量設(shè)置成用戶的 tzPref
cookie 中存儲(chǔ)的時(shí)區(qū),或者,如果沒有,則使用缺省時(shí)區(qū) CST
。
![]() |
|
EL(與四個(gè) JSTL 定制標(biāo)記庫提供的操作結(jié)合起來)允許頁面作者不使用腳本元素即可實(shí)現(xiàn)表示層邏輯。例如,對(duì)比本文開頭 清單 1 中的 JSP 代碼和清單 17 中顯示的通過 JSTL 實(shí)現(xiàn)的同樣功能。(JSTL core
庫中其余的標(biāo)記,包括 <c:choose>
及其子標(biāo)記,將在本系列的下一篇文章中討論。)盡管顯然執(zhí)行了條件邏輯,但是 JSTL 版本中沒有 Java 語言源代碼,并且標(biāo)記之間的關(guān)系(尤其是關(guān)于嵌套需求)對(duì)于任何精通 HTML 語法的人都應(yīng)該是熟悉的。
<c:choose><c:when test="${user.role == 'member'}"> <p>Welcome, member!</p> </c:when><c:otherwise> <p>Welcome, guest!</p> </c:otherwise></c:choose> |
通過提供大多數(shù) Web 應(yīng)用程序常用功能的標(biāo)準(zhǔn)實(shí)現(xiàn),JSTL 有助于加速開發(fā)周期。與 EL 結(jié)合起來,JSTL 可以不需要對(duì)表示層程序編寫代碼,這極大地簡化了 JSP 應(yīng)用程序的維護(hù)。
![]() |
||
|
![]() |
Mark Kolb 是一名在德克薩斯州奧斯汀工作的軟件工程師。他經(jīng)常就服務(wù)器端 Java 主題在業(yè)界發(fā)表演講,并且與人合著了 Web Development with JavaServer Pages,第二版一書。可通過 mak@taglib.com與 Mark 聯(lián)系。 |
posted on 2006-12-07 14:42 stme 閱讀(490) 評(píng)論(7) ?編輯?收藏引用收藏至365Key
不錯(cuò), 必須在頭部加入下列聲明:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="GBK"%>
要不然你就得用編輯器另存為的時(shí)候(例如記事本就有這個(gè)功能, 但是貌似有問題)轉(zhuǎn)換編碼為 UTF-8.
服務(wù)器看到 contentType="text/html; charset=UTF-8" 的頁面聲明的時(shí)候, 就認(rèn)為下面的內(nèi)容都是 UTF-8, 如果這時(shí)候不加上 pageEncoding, 出來的內(nèi)容自然就是亂碼.
因此要么都用 GBK, 要么都用 UTF-8. 可以在 Eclipse 里進(jìn)行設(shè)置讓所有的源文件的默認(rèn)字符集都是 UTF-8. 如果要做開源項(xiàng)目, 強(qiáng)烈建議的是不要用 GBK 格式的編碼, 用 UTF-8 是上上策. 還有就是鼓勵(lì)英文注釋, 網(wǎng)頁內(nèi)容國際化, 呵呵.??回復(fù)??
1、首先我們用編輯器編輯jsp頁面代碼保存;
2、web服務(wù)器對(duì)其進(jìn)行編譯,將jsp頁面編譯成為一個(gè)java的class文件;
3、web服務(wù)器將其class文件用傳輸格式在網(wǎng)絡(luò)上傳輸;
4、客戶端瀏覽器解析代碼生成頁面。
非applet的情況下,服務(wù)器怎么可能把class傳輸?shù)骄W(wǎng)絡(luò)上去,瀏覽器又怎么可能解析class?服務(wù)器傳輸?shù)氖莌tml,class生成html的過程早在服務(wù)器端就已經(jīng)完成。
亂碼的直接原因就在于服務(wù)器在頭里告訴瀏覽器的編碼 charset=UTF-8 和事實(shí)上生成html的編碼是不一致的??回復(fù)??
呵呵, 這段話的確是有點(diǎn)問題...
應(yīng)該是:
1. 我們用代碼編輯器編輯了一個(gè)頁面(encoding=GBK)
2. Web 服務(wù)器調(diào)用編譯器將其編譯為 servlet(編譯器也會(huì)有個(gè) encoding 選項(xiàng), 一般都是跟著系統(tǒng)的 encoding 走, 頁面有 charset 的話就跟頁面的 charset 或者 pageEncoding 一致, 所以有時(shí)候不指定JSP編譯默認(rèn)編碼, 不同的服務(wù)器出來的結(jié)果就不一樣), (encoding=GBK);
3. 生成 HTML, 這沒啥, 直接 write string;
4. 瀏覽器根據(jù) head 里的 contentType (UTF-8)來判斷編碼, 或者根據(jù)頁面里的 meta 來判斷編碼
<meta http-equiv="content-type" content="text/html; charset=UTF-8">, 什么都沒的時(shí)候就當(dāng)成西歐字符集, 具體哪個(gè)優(yōu)先? 印象中是頁面里的 meta 優(yōu)先, 這時(shí)候客戶需要手工選一個(gè)編碼才能看到正確的網(wǎng)頁.
所以只有這些條件都一致的時(shí)候, 才不會(huì)亂碼, 否則都會(huì)亂碼. 一般推薦全用 UTF-8(英文服務(wù)器環(huán)境) 或者 GBK(中文服務(wù)器).??回復(fù)??
上次看你另一篇文章,對(duì)編碼分析得很詳細(xì),很有幫助。再接再厲!??回復(fù)??
謝謝大家的點(diǎn)評(píng),大家一起進(jìn)步吧!??回復(fù)??
>>utf-8只是用于在數(shù)據(jù)傳輸時(shí)將字符串分割成字節(jié)傳輸出去,它對(duì)于unicode編碼有著嚴(yán)格的一一對(duì)應(yīng)關(guān)系,而對(duì)于gb2312、gbk、gb18030之類的中文編碼是沒有對(duì)應(yīng)關(guān)系的。gb2312、gbk、gb18030是在ascii編碼之上進(jìn)行的中文編碼開發(fā),所以它們是與ascii相兼容的
gb18030也和unicode有著嚴(yán)格的一一對(duì)應(yīng)關(guān)系,gb2312、gbk和unicode的子集有著嚴(yán)格的一一對(duì)應(yīng)關(guān)系
UTF-8和gb18030都是所謂的外碼標(biāo)準(zhǔn)
“gb2312、gbk、gb18030是在ascii編碼之上進(jìn)行的中文編碼開發(fā),所以它們是與ascii相兼容的”是錯(cuò)誤的,只能說UTF-8以及國標(biāo)編碼的單字節(jié)編碼區(qū)和ascii的0~7F區(qū)的編碼是一致的。
Notepad++和UltraEdit的ascii其實(shí)并不是ascii,而是指Windows平臺(tái)的本地多字節(jié)字符集,一般咱們用的中文Windows上就是gbk??回復(fù)??
”gb18030也和unicode有著嚴(yán)格的一一對(duì)應(yīng)關(guān)系,gb2312、gbk和unicode的子集有著嚴(yán)格的一一對(duì)應(yīng)關(guān)系“
這個(gè)是對(duì)的嗎?本人好像沒有看到這樣的資料,gb18030只是一部分與unicode對(duì)應(yīng),不會(huì)是全部一一對(duì)應(yīng)吧??回復(fù)??
MySQL2JSP是一個(gè)快速開發(fā)工具,可以讓你從Mysql中直接生成JSP、servlets,以及JavaBeans。并且會(huì)生成增加、刪除、修改、查看記錄等JSP頁面。使用JDBC。某種程度上,有點(diǎn)像是簡化的RAILS。
http://sourceforge.net/projects/db2jspgen/
//留言bean
package userinfobean;
/**
?* <p>Title: </p>
?* <p>Description: </p>
?* <p>Copyright: Copyright (c) 2004</p>
?* <p>Company: </p>
?* @author not attributable
?* @version 1.0
?*/
public class memoBean {
? private String id;//1.用戶名
? private String email;//2.密碼
? private String content;//3.留言?
? public memoBean() {
? }
? //1.用戶名
? public void setId(String s){
??? this.id=s;
? }
? //2.密碼
? public void setEmail(String s){
??? this.email=s;
? }
? //3.留言
?? public void setContent(String s){
??? this.content=s;
? }
?
? //1.用戶名
?? public String getId( ){
???? return this.id;
?? }
?? //2.密碼
?? public String getEmail(){
???? return this.email;
?? }
?? //3.留言?
?? public String getContent(){
???? return this.content;
?? }
}
//// 用于數(shù)據(jù)庫操作的bean??????????
package userinfobean;
import userinfobean.*;
import java.io.*;
import java.util.*;
import java.sql.*;
public class databaseBean{
? private String dbName;
? private String dbUser;
? private String dbPass;
???private Vector memoVector;
?? Connection connection;
? public databaseBean(){
??? dbName=new String("×××××××");
??? dbUser=new String("××××××");
??? dbPass=new String("×××××××");
??? String connectionUrl="jdbc:mysql://localhost/"+dbName;
??? try{
????? Class.forName("org.gjt.mm.mysql.Driver");
????? connection=DriverManager.getConnection(connectionUrl,dbUser,dbPass);
??? }
??? catch(Exception e){
????? System.out.println(e.toString());
????? }
? }
? public void dbQueryMemos(){
??? try{
?????? memoVector=new Vector();
????? Statement stmt=connection.createStatement();
????? ResultSet rs=stmt.executeQuery("select * from memo;");
????? while(rs.next()){
??????? memoBean temp=new memoBean();
??????? temp.setId(rs.getString(2));
??????? temp.setEmail(rs.getString(3));
??????? temp.setContent(rs.getString(4));
??????? memoVector.add(temp);
????? }
?? }
?? catch(SQLException e){
???? System.out.println(e.toString());
?? }
?
? }
??? public void setDbName(String s){
??? this.dbName=s;
? }
? public void setDbUser(String s){
??? this.dbUser=s;
? }
? public void setDbPass(String s){
??? this.dbPass=s;
? }
? public String getDbName(){
??? return this.dbName;
? }
? public String getDbUser(){
??? return this.dbUser;
? }
? public String getDbPass(){
??? return this.dbPass;
? }
??? public Vector getMemoVector(){
??? return this.memoVector;
? }
}
///以下是網(wǎng)頁源碼
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page language="java" import="java.util.*" %>
<%@ page? import="java.text.*" %>
<%@ page? import="userinfobean.*" %>
<jsp:useBean id="memoInfo" scope="page" class="userinfobean.memoBean"/>
<jsp:useBean id="memoQuery" scope="page" class="userinfobean.databaseBean"/>
<%!
int totalPages;
int countPerPage=3;
int totalCount;
int currentPage=0;
int currentStart;
%>
<%
memoQuery.dbQueryMemos();
Vector vt=memoQuery.getMemoVector();
totalCount=vt.size();
totalPages=totalCount/countPerPage;
if(totalCount%countPerPage>0)totalPages=totalPages+1;
if(request.getParameter("page")==null)
{
currentPage=1;
}
else
{
currentPage=Integer.parseInt(request.getParameter("page"));
if(currentPage>totalPages)currentPage=totalPages;
if(currentPage<1)currentPage=1;
}
currentStart=totalCount-1-countPerPage * (currentPage-1);
%>
<html>
<head>
<title>NetGreen</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
? <link rel="stylesheet" href="main.css">????????????????????????????
</head>
<script language="JavaScript" >
function page_check()
{
if(document.pageForm.page.value=="")
{alert("請(qǐng)輸入頁數(shù)");
document.pageForm.page.focus();
return false;
}
return true;
}</script>
<body bgcolor="ffffff"? >
<center>
? <table width="800" border="0" height="622">
??? <tr>
????? <td height="71" align="center" valign="middle"> <table width="100%" border="1" cellpadding="0" cellspacing="0" bordercolor="#0099CC">
????????? <tr>
??????????? <td width="19%" height="60" align="left" valign="bottom" bgcolor="#FFFFFF"><b><font size="4" color="#00cc66" ><img src="image/logo.gif" width="156" height="60"></font></b></td>
??????????? <td width="57%" align="left" valign="bottom" bgcolor="#FFFFFF"><img src="image/banner.gif" width="100%" height="60"></td>
??????????? <td width="24%" align="left" valign="bottom"> <table width="102%" height="60" border="1" cellpadding="0" cellspacing="0" bordercolor="#0099CC" bgcolor="#FFFFFF">
??????????????? <tr>
????????????????? <td width="50%" height="27" align="center">上 傳</td>
????????????????? <td width="50%" align="center">收藏本頁</td>
??????????????? </tr>
??????????????? <tr>
????????????????? <td height="21" align="center" bgcolor="#FFFFFF" >退 出 </td>
????????????????? <td align="center"><a href="memoForm.htm" target="_self">我要留言</a></td>
??????????????? </tr>
????????????? </table></td>
????????? </tr>
??????? </table></td>
??? </tr>
??? <tr>
????? <td height="31"><table width="100%" border="1" bordercolor="#0099CC">
????????? <tr bgcolor="#00CC66">
??????????? <td width="12%" height="23" align="center" bgcolor="#CCFFFF"><a href="index.htm" >首頁</a></td>
??????????? <td width="12%" align="center" bgcolor="#CCFFFF"><a href="loginForm.htm" >登陸</a></td>
??????????? <td width="12%" align="center" bgcolor="#CCFFFF"> </td>
??????????? <td width="12%" align="center" bgcolor="#CCFFFF"> </td>
??????????? <td width="12%" align="center" bgcolor="#CCFFFF" > </td>
??????????? <td width="12%" align="center" bgcolor="#CCFFFF"> </td>
??????????? <td width="12%" align="center" bgcolor="#CCFFFF"><a href="memoDisplay.jsp" >留言板</a></td>
??????????? <td width="12%" align="center"? bgcolor="#CCFFFF"><a href="registForm.htm">注冊</a></td>
????????? </tr>
??????? </table></td>
??? </tr>
??? <tr>
????? <td height="435" align="center" valign="top" nowrap>
??????? <table width="100%"? border="1" cellpadding="0" cellspacing="0" bordercolor="#0099CC">
????????? <tr>
??????????? <td width="18%" height="431" align="center" valign="middle" bgcolor="#CCFFFF">
??????????? </td>
??????????? <td width="83%" align="center" valign="top" bgcolor="#FFFFFF"><table width="100%" border="1"><form name="pageForm" method="post"? onSubmit="return page_check();"action="memoDisplay.jsp">
??????????????? <tr>
????????????????? <td width="36%">共有留言<%out.print(totalPages);%> 頁,現(xiàn)在是第<%out.print(currentPage);%>? 頁</td>
??????????????????? <td width="64%">
?????<a href="memoDisplay.jsp?page=<%=currentPage-1%>" >上一頁 </a>
?????<a href="memoDisplay.jsp?page=<%=currentPage+1%>" >下一頁? </a>
?????<a href="memoDisplay.jsp?page=1" >首頁 </a>
????? <a href="memoDisplay.jsp?page=<%=totalPages%>" >尾頁? </a>
????? <input type="submit" name="Submit" value="G0">
????????????????????? <input name="page" type="text" size="10">
????????????????????? 頁</td>
??????????????? </tr>
????????????? </form></table>
????????????? <%
????
????for(int i=0;i<countPerPage&¤tStart-i>=0;i++)
????{
?????memoInfo.setId(((memoBean)vt.get(currentStart-i)).getId());
?????memoInfo.setEmail(((memoBean)vt.get(currentStart-i)).getEmail());
?????memoInfo.setContent(((memoBean)vt.get(currentStart-i)).getContent());
?????
?????
?????
???out.print("<table width='100%' border='1' ><tr><td width='19%'>");
???out.print(memoInfo.getId());
???out.print("</td><td width='81%'>");
???out.print(memoInfo.getEmail());
???out.print("</td></tr><tr><td height='44' colspan='2'>");
???out.print(memoInfo.getContent());
???out.print("</td></tr></table> ");
???out.print("<br>");
?????
????}
??
???%>
???</td>
????????? </tr>
??????? </table>
????? </td>
??? </tr>
??? <tr>
????? <td height="73" align="center" valign="top" nowrap>
??????? <table width="100%" border="0">
????????? <tr>
??????????? <td height="21" align="center" bgcolor="#FFFFFF"><hr width="85%" noshade? color="#00CC66"></td>
????????? </tr>
????????? <tr>
??????????? <td height="12" align="center">Copyright @ HomeLee. All rights reserved.
??????????? </td>
????????? </tr>
????????? <tr>
??????????? <td height="12" align="center" bgcolor="#FFFFFF"> </td>
????????? </tr>
??????? </table></td>
??? </tr>
? </table>
? </center></body>
</html>
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=601253
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>目錄的建立/檢查與刪除</title>
</head>
<body>
<%
String path=request.getRealPath("");
path=path + "\\Sub";//將要建立的目錄路徑
File d=new File(path);//建立代表Sub目錄的File對(duì)象,并得到它的一個(gè)引用
if(d.exists()){//檢查Sub目錄是否存在
d.delete();
out.println("Sub目錄存在,已刪除");
}else{
d.mkdir();//建立Sub目錄
out.println("Sub目錄不存在,已建立");
}
%>
</body>
</html>
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>JSP中如何處理虛擬目錄</title>
</head>
<body>
取得虛擬目錄對(duì)應(yīng)的磁盤路徑<br>
Web站點(diǎn)主目錄的位置為<font color=#ff0000><%=request.getRealPath("/")%></font><br>
JSP網(wǎng)頁所在的目錄位置<font color=#ff0000><%=request.getRealPath("./")%></font><br>
JSP網(wǎng)頁所在目錄上一層目錄的位置<font color=#ff0000><%=request.getRealPath("../")%></font><br>
</body>
</html>
文件屬性的取得
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.util.Date,java.io.*"%>
<html>
<head>
<title>文件屬性的取得</title>
</head>
<body>
<%
String path=request.getRealPath("/");
File f=new File(path,"ReadData.txt");
if(f.exists()){
%>
<%=f.getName()%>的屬性如下:<br><br>
文件長度為:<%=f.length()%>
<%=f.isFile()?"是文件":"不是文件"%><br>
<%=f.isDirectory()?"是目錄":"不是目錄"%><br>
<%=f.canRead()?"可讀取":"不可讀取"%><br>
<%=f.canWrite()?"可寫入":"不可寫入"%><br>
<%=f.isHidden()?"是隱藏文件":"不是隱藏文件"%><br>
文件的最后修改日期為:<%=new Date(f.lastModified())%><br>
<%
}else{
f.createNewFile();//在當(dāng)前目錄下建立一個(gè)名為ReaData.txt的文件
%>
<%=f.getName()%>的屬性如下:<br><br>
文件長度為:<%=f.length()%>
<%=f.isFile()?"是文件":"不是文件"%><br>
<%=f.isDirectory()?"是目錄":"不是目錄"%><br>
<%=f.canRead()?"可讀取":"不可讀取"%><br>
<%=f.canWrite()?"可寫入":"不可寫入"%><br>
<%=f.isHidden()?"是隱藏文件":"不是隱藏文件"%><br>
文件的最后修改日期為:<%=new Date(f.lastModified())%><br>
<%
}
%>
</body>
</html>
取出目錄中文件的方法
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>取出目錄中文件的方法--列出目錄中的文件</title>
</head>
<body>
<%
String path=request.getRealPath("/");
File d=new File(path);//建立當(dāng)前目錄中文件的File對(duì)象
File list[]=d.listFiles();//取得代表目錄中所有文件的File對(duì)象數(shù)組
out.println("<font color=#ff0000>" + path + "目錄下的文件:</font><br>");
for(int i=0;i<list.length;i++){
if(list<I>.isFile()){
out.println(list<I>.getName() + "<br>");
}
}
out.println("<br><font color=#ff0000>" + path + "目錄下的目錄:</font><br>");
for(int i=0;i<list.length;i++){
if(list<I>.isDirectory()){
out.println(list<I>.getName() + "<br>");
}
}
%>
</body>
</html>
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>判斷是否為空白文件</title>
</head>
<body>
<%
String path=request.getRealPath("/");
out.println(path);
FileReader fr=new FileReader(path + "\\AtEnd.txt");//建立FileReader對(duì)象,并實(shí)例化為fr
//對(duì)FileReader類生成的對(duì)象使用read()方法,可以從字符流中讀取下一個(gè)字符。
if(fr.read()==-1)//判斷是否已讀到文件的結(jié)尾
{
out.print("AtEnd.txt文件中沒有數(shù)據(jù)<br>");
}else{
out.println("AtEnd.txt文件中有數(shù)據(jù)");
}
fr.close();
%>
</body>
</html>
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*,java.lang.*"%>
<html>
<head>
<title>讀取所有的文件數(shù)據(jù)</title>
</head>
<body>
<%
String path=request.getRealPath(".");
FileReader fr=new FileReader(path + "\\ReadData.txt");
//關(guān)鍵在于讀取過程中,要判斷所讀取的字符是否已經(jīng)到了文件的末尾,并且這個(gè)字符是不是文件中的斷行符,即判斷該字符值是否為13。
int c=fr.read();//從文件中讀取一個(gè)字符
//判斷是否已讀到文件結(jié)尾
while(c!=-1){
out.print((char)c);//輸出讀到的數(shù)據(jù)
c=fr.read();//從文件中繼續(xù)讀取數(shù)據(jù)
if(c==13){//判斷是否為斷行字符
out.print("<br>");//輸出分行標(biāo)簽
fr.skip(1);//略過一個(gè)字符
//c=fr.read();//讀取一個(gè)字符
}
}
fr.close();
%>
</body>
</html> 一行一行讀取數(shù)據(jù)
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>文件讀取</title>
</head>
<body>
<%
String path=request.getRealPath("");//取得當(dāng)前目錄的路徑
FileReader fr=new FileReader(path + "\\file\\inc\\t.txt");//建立FileReader對(duì)象,并實(shí)例化為fr
BufferedReader br=new BufferedReader(fr);//建立BufferedReader對(duì)象,并實(shí)例化為br
String Line=br.readLine();//從文件讀取一行字符串
//判斷讀取到的字符串是否不為空
while(Line!=null){
out.println(Line + "<br>");//輸出從文件中讀取的數(shù)據(jù)
Line=br.readLine();//從文件中繼續(xù)讀取一行數(shù)據(jù)
}
br.close();//關(guān)閉BufferedReader對(duì)象
fr.close();//關(guān)閉文件
%>
</body>
</html>
略過文件中的字符不讀取
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>略過字節(jié)不讀取</title>
</head>
<body>
<%
String path=request.getRealPath(".");
FileReader fr=new FileReader(path + "\\ReadData.txt");
fr.skip(2);//跳過2個(gè)字節(jié)
int c=fr.read();//讀取一個(gè)字節(jié)
while(c!=-1){
out.print((char)c);
c=fr.read();
}
fr.close();
%>
</body>
</html>
將數(shù)據(jù)寫入文件
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>將數(shù)據(jù)寫入文件</title>
</head>
<body>
<%
String path=request.getRealPath(".");
FileWriter fw=new FileWriter(path + "\\WriteData.txt");//建立FileWriter對(duì)象,并實(shí)例化fw
//將字符串寫入文件
fw.write("大家好!");
fw.write("本書是《JSP編程技巧》");
fw.write("請(qǐng)多多指教!");
fw.write("email:stride@sina.com");
fw.close();
FileReader fr=new FileReader(path + "\\WriteData.txt");
BufferedReader br=new BufferedReader(fr);//建立BufferedReader對(duì)象,并實(shí)例化為br
String Line=br.readLine();
//讀取一行數(shù)據(jù)
out.println(Line + "<br>");
br.close();//關(guān)閉BufferedReader對(duì)象
fr.close();
%>
</body>
</html>
將寫入文件的數(shù)據(jù)分行
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>將寫入文件的數(shù)據(jù)分行</title>
</head>
<body>
<%
String path=request.getRealPath(".");
FileWriter fw=new FileWriter(path + "\\WriteData.txt");
BufferedWriter bw=new BufferedWriter(fw);
bw.write("大家好!");
bw.write("本書是《JSP編程技巧》。");
bw.newLine();//斷行
bw.write("請(qǐng)多多指教!");
bw.newLine();//斷行
bw.write("email: stride@sina.com");
bw.flush();//將數(shù)據(jù)更新至文件
fw.close();//關(guān)閉文件流
out.println("寫入文件內(nèi)容為:<br>");
FileReader fr=new FileReader(path + "\\WriteData.txt");
BufferedReader br=new BufferedReader(fr);
String Line=br.readLine();//讀取一行數(shù)據(jù)
while(Line!=null){
out.println(Line + "<br>");
Line=br.readLine();
}
fr.close();
%>
</body>
</html>
如何將數(shù)據(jù)追加寫入到文件
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>將寫入文件的數(shù)據(jù)分行</title>
</head>
<body>
<%
String path=request.getRealPath(".");
RandomAccessFile rf=new RandomAccessFile(path + "\\WriteData.txt","rw");//定義一個(gè)類RandomAccessFile的對(duì)象,并實(shí)例化
rf.seek(rf.length());//將指針移動(dòng)到文件末尾
rf.writeBytes("\nAppend a line to the file!");
rf.close();//關(guān)閉文件流
out.println("寫入文件內(nèi)容為:<br>");
FileReader fr=new FileReader(path + "\\WriteData.txt");
BufferedReader br=new BufferedReader(fr);//讀取文件的BufferedRead對(duì)象
String Line=br.readLine();
while(Line!=null){
out.println(Line + "<br>");
Line=br.readLine();
}
fr.close();//關(guān)閉文件
%>
</body>
</html></I></I></I></I>
方法:
1. void clear() ;
清除輸出緩沖區(qū)的內(nèi)容,但是不輸出到客戶端。
2. void clearBuffer() ;
清除輸出緩沖區(qū)的內(nèi)容,并輸出到客戶端。
3. void close() ;
關(guān)閉輸出流,清除所有內(nèi)容。
4. void flush() ;
輸出緩沖區(qū)里面的數(shù)據(jù)。
5. int getBufferSize() ;
獲取以kb為單位的目前緩沖區(qū)大小。
6. int getRemaining() ;
獲取以kb為單位的緩沖區(qū)中未被占用的空間大小。
7. boolean isAutoFlush() ;
是否自動(dòng)刷新緩沖區(qū)。
8. void newLine() ;
輸出一個(gè)換行字符。
9. void print( boolean b ) ;
void print( char c ) ;
void print( char[] s ) ;
void print( double d ) ;
void print( float f ) ;
void print( int i ) ;
void print( long l ) ;
void print( Object obj ) ;
void print( String s ) ;
將指定類型的數(shù)據(jù)輸出到Http流,不換行。
10. void println( boolean b ) ;
void println( char c ) ;
void println( char[] s ) ;
void println( double d ) ;
void println( float f ) ;
void println( int i ) ;
void println( long l ) ;
void println( Object obj ) ;
void println( String s ) ;
將指定類型的數(shù)據(jù)輸出到Http流,并輸出一個(gè)換行符。
11. Appendable append( char c ) ;
Appendable append( CharSequence cxq, int start, int end ) ;
Appendable append( CharSequence cxq ) ;
將一個(gè)字符或者實(shí)現(xiàn)了CharSequence接口的對(duì)象添加到輸出流的后面。
成員:
int DEFAULT_BUFFER = 0 - 缺省緩沖區(qū)大小
int NO_BUFFER = -1 - writer是否處于緩沖輸出狀態(tài)
int UNBOUNDED_BUFFER = -2 - 是否限制緩沖區(qū)大小
② request - javax.servlet.http.HttpServletRequest
request對(duì)象包含所有請(qǐng)求的信息,如請(qǐng)求的來源、標(biāo)頭、cookies和請(qǐng)求相關(guān)的參數(shù)值等。
方法:
1. Object getAttribute( String name ) ;
返回由name指定的屬性值,該屬性不存在時(shí)返回null。
2. Enumeration getAttributeNames() ;
返回request對(duì)象的所有屬性名稱的集合。
3. String getAuthType() ;
返回用來保護(hù)servlet的認(rèn)證方法的名稱,未受保護(hù)時(shí)返回null。
4. String getCharacterEncoding() ;
返回請(qǐng)求中的字符編碼方法,可以在response對(duì)象中設(shè)置。
5. int getContentLength() ;
返回請(qǐng)求的BODY的長度,不能確定長度時(shí)返回-1。可以在response中設(shè)置。
6. String getContentType() ;
返回在response中定義的內(nèi)容類型。
7. String getContentPath() ;
返回請(qǐng)求的路徑。
8. Cookie[] getCookies() ;
返回客戶端所有的Cookie的數(shù)組。
9. Enumeration getHeaderNames() ;
返回所有HTTP頭的名稱的集合。
10. Enumeration getHeaders( String name ) ;
返回指定HTTP頭的所有值的集合。
11. String getHeader( String name ) ;
返回指定名稱的HTTP頭的信息。
12. long getDateHeader( String name ) ;
返回指定名稱的Data類型的HTTP頭的信息。
13. int getIntHeader( String name ) ;
返回指定名稱的Int類型的HTTP頭的信息。
14. ServletInputStream getInputStream() ;
返回請(qǐng)求的輸入流。
15. Locale getLocale() ;
返回當(dāng)前頁的Locale對(duì)象,可以在response中設(shè)定。
16. Enumeration getLocales() ;
返回請(qǐng)求中所有的Locale對(duì)象的集合。
17. String getLocalName() ;
獲取響應(yīng)請(qǐng)求的服務(wù)器端主機(jī)名。
18. String getLocalAddr() ;
獲取響應(yīng)請(qǐng)求的服務(wù)器端地址。
19. int getLocalPort() ;
獲取響應(yīng)請(qǐng)求的服務(wù)器端端口
20. String getMethod() ;
獲取客戶端向服務(wù)器端發(fā)送請(qǐng)求的方法(GET、POST)。
21. String getParameter( String name ) ;
獲取客戶端發(fā)送給服務(wù)器端的參數(shù)值。
22. Map getParameterMap() ;
該方法返回包含請(qǐng)求中所有參數(shù)的一個(gè)Map對(duì)象。
23. Enumeration getParameterNames() ;
返回請(qǐng)求中所有參數(shù)的集合。
24. String[] getParameterValues( String name ) ;
獲得請(qǐng)求中指定參數(shù)的所有值。
25. String getQueryString() ;
返回get方法傳遞的參數(shù)字符串,該方法不分解出單獨(dú)的參數(shù)。
26. String getPathInfo() ;
取出請(qǐng)求中處于ServletPath和QueryString之間的額外信息。
27. String getPathTranslated() ;
返回用getPathInfo()方法取得的路徑信息的實(shí)際路徑。
28. String getProtocol() ;
返回請(qǐng)求使用的協(xié)議。可以是HTTP1.1或者HTTP1.0。
29. BufferedReader getReader() ;
返回請(qǐng)求的輸入流對(duì)應(yīng)的Reader對(duì)象,該方法和getInputStream()方法在一個(gè)頁面中只能調(diào)用一個(gè)。
30. String getRemoteAddr() ;
獲取發(fā)出請(qǐng)求的客戶端IP地址。
31. String getRemoteHost() ;
獲取發(fā)出請(qǐng)求的客戶端主機(jī)名
32. String getRemoteUser() ;
返回經(jīng)過客戶端驗(yàn)證的用戶名,未經(jīng)驗(yàn)證返回null。
33. int getRemotePort() ;
返回發(fā)出請(qǐng)求的客戶端主機(jī)端口。
34. String getRealPath( String path ) ;
返回給定虛擬路徑的物理路徑。
35. RequestDispatcher getRequestDispatcher( String path ) ;
按給定的路徑生成資源轉(zhuǎn)向處理適配器對(duì)象。
36. String getRequestedSessionId() ;
返回請(qǐng)求的session的標(biāo)識(shí)。
37. String RequestURI() ;
返回發(fā)出請(qǐng)求的客戶端地址,但是不包括請(qǐng)求的參數(shù)字符串。
38. StringBuffer getRequestURI() ;
返回響應(yīng)請(qǐng)求的服務(wù)器端地址
39. String getScheme() ;
獲取協(xié)議名稱,缺省值為HTTP協(xié)議。
40. String getServerName() ;
返回響應(yīng)請(qǐng)求的服務(wù)器名稱。
41. String getServletPath() ;
獲取客戶端所請(qǐng)求的腳本文件的文件路徑。
42. int getServerPort() ;
獲取響應(yīng)請(qǐng)求的服務(wù)器端主機(jī)端口號(hào)。
43. void removeAttribute( String name ) ;
在屬性列表中刪除指定名稱的屬性。
44. void setAttribute( String name, Object value ) ;
在屬性列表中添加/刪除指定的屬性。
45. void setCharacterEncoding( String name ) ;
設(shè)置請(qǐng)求的字符編碼格式。
46. HttpSession getSession() ;
HttpSession getSession( boolean create ) ;
獲取session,如果create為true,在無session的情況下創(chuàng)建一個(gè)。
47. boolean isRequestedSessionIdFromCookie() ;
檢查請(qǐng)求的會(huì)話ID是否為通過Cookie傳入。
48. boolean isRequestedSessionIdFromURL() ;
檢查請(qǐng)求的會(huì)話ID是否為通過URL傳入。
49. boolean isRequestedSessionIdValid() ;
檢查請(qǐng)求的會(huì)話ID是否仍然有效。
50. boolean isSecure() ;
檢查請(qǐng)求是否使用安全鏈接,如果HTTPS等。
51. boolean isUserInRole( String role ) ;
檢查已經(jīng)通過驗(yàn)證的用戶是否在是role所指定的角色。
52. Principal getUserPrincipal() ;
返回包含用戶登陸名的一個(gè)java.security.Principal對(duì)象。
成員:
String BASIC_AUTH = "BASIC" -
String CLIENT_CERT_AUTH = "CLIENT_CERT" -
String DIGEST_AUTH = "DIGEST" -
String FORM_AUTH = "FORM" -
③ response - javax.servlet.http.HttpServletResponse
response對(duì)象主要將JSP容器處理后的結(jié)果傳回到客戶端。
方法:
1. void addCookie( Cookie cookie ) ;
添加一個(gè)Cookie對(duì)象,保存客戶端信息。
2. void addDateHeader( String name, long value ) ;
添加一個(gè)日期類型的HTTP頭信息,覆蓋同名的HTTP頭信息。
3. void addHeader( String name, String value ) ;
添加一個(gè)HTTP頭,覆蓋同名的舊HTTP頭。
4. void addIntHeader( String name, int value ) ;
添加一個(gè)整型的HTTP頭,覆蓋同名的舊HTTP頭。
5. boolean containsHeader( String name ) ;
判斷指定的HTTP頭是否存在。
6. String encodeRedirectURL( String url ) ;
對(duì)sendRedirect()方法使用的URL進(jìn)行編碼。
7. String encodeURL( String url ) ;
將URL予以編碼,回傳包含session ID的URL。
8. void flushBuffer() ;
強(qiáng)制把當(dāng)前緩沖區(qū)的內(nèi)容發(fā)送到客戶端。
9. int getBufferSize() ;
取得以kb為單位的緩沖區(qū)大小。
10. String getCharacterEncoding() ;
獲取響應(yīng)的字符編碼格式。
11. String getContentType() ;
獲取響應(yīng)的類型。
12. Locale getLocale() ;
獲取響應(yīng)的Locale對(duì)象。
13. ServletOutputStream getOutputStream() ;
返回客戶端的輸出流對(duì)象。
14. PrintWriter getWriter() ;
獲取輸出流對(duì)應(yīng)的writer對(duì)象。
15. boolean isCommitted() ;
判斷服務(wù)器端是否已經(jīng)將數(shù)據(jù)輸出到客戶端。
16. void reset() ;
清空buffer中的所有內(nèi)容。
17. void resetBuffer() ;
情況buffer中所有的內(nèi)容,但是保留HTTP頭和狀態(tài)信息。
18. void sendError( int xc, String msg ) ;
void sendError( int xc ) ;
發(fā)送錯(cuò)誤,包括狀態(tài)碼和錯(cuò)誤信息。
19. void sendRedirect( String locationg ) ;
把響應(yīng)發(fā)送到另外一個(gè)位置進(jìn)行處理。
20. void setBufferSize( int size ) ;
設(shè)置以kb為單位的緩沖區(qū)大小。
21. void setCharacterEncoding( String charset ) ;
設(shè)置響應(yīng)使用的字符編碼格式。
22. void setContentLength( int length ) ;
設(shè)置響應(yīng)的BODY長度。
23. void setContentType( String type ) ;
設(shè)置響應(yīng)的類型。
24. void setDateHeader( String name, long value ) ;
設(shè)置指定名稱的Data類型的HTTP頭的值。
25. void setHeader( String name, String value ) ;
設(shè)置指定名稱的HTTP頭的值。
26. void setIntHeader( String name, int value ) ;
設(shè)置指定名稱的int類型的HTTP頭的值。
27. void setStatus( int xc ) ;
設(shè)置響應(yīng)狀態(tài)碼,新值會(huì)覆蓋當(dāng)前值。
成員(HTTP狀態(tài)碼):
int SC_CONTINUE = 100 int SC_SWITCHING_PROTOCOLS = 101
int SC_OK = 200 int SC_NON_AUTHORITATIVE_INFORMATION = 203
int SC_ACCEPTED = 202 int SC_CREATED = 201
int SC_NO_CONTENT = 204 int SC_RESET_CONTENT = 205
int SC_PARTIAL_CONTENT = 206 int SC_MULTIPLE_CHOICES = 300
int SC_MOVED_PERMANENTLY = 301 int SC_MOVED_TEMPORARILY = 302
int SC_FOUND = 302 int SC_SEE_OTHER = 303
int SC_NOT_MODIFIED = 304 int SC_USE_PROXY = 305
int SC_TEMPORARY_REDIRECT = 307 int SC_BAD_REQUEST = 400
int SC_UNAUTHORIZED = 401 int SC_PAYMENT_REQUIRED = 402
int SC_FORBIDDEN = 403 int SC_NOT_FOUND = 404
int SC_METHOD_NOT_ALLOWED = 405 int SC_NOT_ACCEPTABLE = 406
int SC_PROXY_AUTHENTICATION_REQUIRED = 407 int SC_REQUEST_TIMEOUT = 408
int SC_CONFLICT = 409 int SC_GONE = 410
int SC_LENGTH_REQUIRED = 411 int SC_PRECONDITION_FAILED = 412
int SC_REQUEST_ENTITY_TOO_LARGE = 413 int SC_REQUEST_URI_TOO_LONG = 414
int SC_UNSUPPORTED_MEDIA_TYPE = 415 int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416
int SC_EXPECTATION_FAILED = 417 int SC_INTERNAL_SERVER_ERROR = 500
int SC_NOT_IMPLEMENTED = 501 int SC_BAD_GATEWAY = 502
int SC_SERVICE_UNAVAILABLE = 503 int SC_GATEWAY_TIMEOUT = 504
int SC_HTTP_VERSION_NOT_SUPPORTED = 505
④ session - javax.servlet.http.HttpSession
session對(duì)象表示目前個(gè)別用戶的會(huì)話狀態(tài),用來識(shí)別每個(gè)用戶。
方法:
1. Object getAttribute( String name ) ;
獲取與指定名字相關(guān)聯(lián)的session屬性值。
2. Enumeration getAttributeNames() ;
取得session內(nèi)所有屬性的集合。
3. long getCreationTime() ;
返回session的創(chuàng)建時(shí)間,最小單位千分之一秒。
4. String getId() ;
取得session標(biāo)識(shí)。
5. long getLastAccessedTime() ;
返回與當(dāng)前session相關(guān)的客戶端最后一次訪問的時(shí)間,由1970-01-01算起,單位毫秒。
6. int getMaxInactiveInterval( int interval ) ;
返回總時(shí)間,以秒為單位,表示session的有效時(shí)間(session不活動(dòng)時(shí)間)。-1為永不過期。
7. ServletContext getServletContext() ;
返回一個(gè)該JSP頁面對(duì)應(yīng)的ServletContext對(duì)象實(shí)例。
8. HttpSessionContext getSessionContext() ;
9. Object getValue( String name ) ;
取得指定名稱的session變量值,不推薦使用。
10. String[] getValueNames() ;
取得所有session變量的名稱的集合,不推薦使用。
11. void invalidate() ;
銷毀這個(gè)session對(duì)象。
12. boolean isNew() ;
判斷一個(gè)session是否由服務(wù)器產(chǎn)生,但是客戶端并沒有使用。
13. void pubValue( String name, Object value ) ;
添加一個(gè)session變量,不推薦使用。
14. void removeValue( String name ) ;
移除一個(gè)session變量的值,不推薦使用。
15. void setAttribute( String name, String value ) ;
設(shè)置指定名稱的session屬性值。
16. void setMaxInactiveInterval( int interval ) ;
設(shè)置session的有效期。
17. void removeAttribute( String name ) ;
移除指定名稱的session屬性。
⑤ pageContext - javax.servlet.jsp.PageContext
pageContext對(duì)象存儲(chǔ)本JSP頁面相關(guān)信息,如屬性、內(nèi)建對(duì)象等。
方法:
1. void setAttribute( String name, Object value, int scope ) ;
void setAttribute( String name, Object value ) ;
在指定的共享范圍內(nèi)設(shè)置屬性。
2. Object getAttribute( String name, int scope ) ;
Object getAttribute( String name ) ;
取得指定共享范圍內(nèi)以name為名字的屬性值。
3. Object findAttribute( String name ) ;
按頁面、請(qǐng)求、會(huì)話和應(yīng)用程序共享范圍搜索已命名的屬性。
4. void removeAttribute( String name, int scope ) ;
void removeAttribute( String name ) ;
移除指定名稱和共享范圍的屬性。
5. void forward( String url ) ;
將頁面導(dǎo)航到指定的URL。
6. Enumeration getAttributeNamesScope( int scope ) ;
取得指定共享范圍內(nèi)的所有屬性名稱的集合。
7. int getAttributeScope( String name ) ;
取得指定屬性的共享范圍。
8. ErrorData getErrorDate() ;
取得頁面的errorData對(duì)象。
9. Exception getException() ;
取得頁面的exception對(duì)象。
10. ExpressionEvaluator getExpressionEvaluator() ;
取得頁面的expressionEvaluator對(duì)象。
11. JspWriter getOut() ;
取得頁面的out對(duì)象。
12. Object getPage() ;
取得頁面的page對(duì)象。
13. ServletRequest getRequest() ;
取得頁面的request對(duì)象。
14. ServletResponse getResponse() ;
取得頁面的response對(duì)象。
15. ServletConfig getConfig() ;
取得頁面的config對(duì)象。
16. ServletContext getServletContext() ;
取得頁面的servletContext對(duì)象。
17. HttpSession getSession() ;
取得頁面的session對(duì)象。
18. VariableResolver getVariableResolver() ;
取得頁面的variableResolver對(duì)象。
19. void include( String url, boolean flush ) ;
void include( String url ) ;
包含其他的資源,并指定是否自動(dòng)刷新。
20. void release() ;
重置pageContext內(nèi)部狀態(tài),釋放所有內(nèi)部引用。
21. void initialize( Servlet servlet, ServletRequest request, ServletResponse response,
String errorPageURL, boolean needSession, int bufferSize, boolean autoFlush ) ;
初始化未經(jīng)初始化的pageContext對(duì)象。
22. BodyContext pushBody() ;
BodyContext pushBody( Writer writer ) ;
保存當(dāng)前的out對(duì)象,并更新pageContext中page范圍內(nèi)的out對(duì)象。
23. JspWrite popBody() ;
取出由pushBody()方法保存的out對(duì)象。
24. void handlePageException( Exception e ) ;
void handlePageException( Thrwoable t ) ;
成員:
int PAGE_SCOPE = 1 - 頁面共享范圍
int REQUEST_SCOPE = 2 - 請(qǐng)求共享范圍
int SESSION_SCOPE = 3 - 會(huì)話共享范圍
int APPLICATION_SCOPE = 4 - 應(yīng)用程序共享范圍
String PAGE = "javax.servlet.jsp.jspPage"
String PAGECONTEXT = "javax.servlet.jsp.jspPageContext"
String REQUEST = "javax.servlet.jsp.jspRequest"
String RESPONSE = "javax.servlet.jsp.jspResponse"
String CONFIG = "javax.servlet.jsp.jspConfig"
String SESSION = "javax.servlet.jsp.jspSession"
String OUT = "javax.servlet.jsp.jspOut"
String APPLICATION = "javax.servlet.jsp.jspApplication"
String EXCEPTION = "javax.servlet.jsp.jspException"
⑥ application - javax.servlet.ServletContext
application主要功用在于取得或更改Servlet的設(shè)定。
方法:
1. Object getAttribute( String name ) ;
返回由name指定的application屬性。
2. Enumeration getAttributes() ;
返回所有的application屬性。
3. ServletContext getContext( String uripath ) ;
取得當(dāng)前應(yīng)用的ServletContext對(duì)象。
4. String getInitParameter( String name ) ;
返回由name指定的application屬性的初始值。
5. Enumeration getInitParameters() ;
返回所有的application屬性的初始值的集合。
6. int getMajorVersion() ;
返回servlet容器支持的Servlet API的版本號(hào)。
7. String getMimeType( String file ) ;
返回指定文件的類型,未知類型返回null。一般為"text/html"和"image/gif"。
8. int getMinorVersion() ;
返回servlet容器支持的Servlet API的副版本號(hào)。
9. String getRealPath( String path ) ;
返回給定虛擬路徑所對(duì)應(yīng)物理路徑。
10. RequestDispatcher getNamedDispatcher( String name ) ;
為指定名字的Servlet對(duì)象返回一個(gè)RequestDispatcher對(duì)象的實(shí)例。
11. RequestDispatcher getRequestDispatcher( String path ) ;
返回一個(gè)RequestDispatcher對(duì)象的實(shí)例。
12. URL getResource( String path ) ;
返回指定的資源路徑對(duì)應(yīng)的一個(gè)URL對(duì)象實(shí)例,參數(shù)要以"/"開頭。
13. InputStream getResourceAsStream( String path ) ;
返回一個(gè)由path指定位置的資源的InputStream對(duì)象實(shí)例。
14. Set getResourcePaths( String path ) ;
返回存儲(chǔ)在web-app中所有資源路徑的集合。
15. String getServerInfo() ;
取得應(yīng)用服務(wù)器版本信息。
16. Servlet getServlet( String name ) ;
在ServletContext中檢索指定名稱的servlet。
17. Enumeration getServlets() ;
返回ServletContext中所有servlet的集合。
18. String getServletContextName() ;
返回本web應(yīng)用的名稱。
19. Enumeration getServletContextNames() ;
返回ServletContext中所有servlet的名稱集合。
20. void log( Exception ex, String msg ) ;
void log( String msg, Throwable t ) ;
void log( String msg ) ;
把指定的信息寫入servlet log文件。
21. void removeAttribute( String name ) ;
移除指定名稱的application屬性。
22. void setAttribute( String name, Object value ) ;
設(shè)定指定的application屬性的值。
⑦ config - javax.servlet.ServletConfig
config對(duì)象用來存放Servlet初始的數(shù)據(jù)結(jié)構(gòu)。
方法:
1. String getInitParameter( String name ) ;
返回名稱為name的促使參數(shù)的值。
2. Enumeration getInitParameters() ;
返回這個(gè)JSP所有的促使參數(shù)的名稱集合。
3. ServletContext getContext() ;
返回執(zhí)行者的servlet上下文。
4. String getServletName() ;
返回servlet的名稱。
⑧ exception - java.lang.Throwable
錯(cuò)誤對(duì)象,只有在JSP頁面的page指令中指定isErrorPage="true"后,才可以在本頁面使用exception對(duì)象。
方法:
1. Throwable fillInStackTrace() ;
將當(dāng)前stack信息記錄到exception對(duì)象中。
2. String getLocalizedMessage() ;
取得本地語系的錯(cuò)誤提示信息。
3. String getMessage()
取得錯(cuò)誤提示信息。
4. StackTrackElement[] getStackTrace() ;
返回對(duì)象中記錄的call stack track信息。
5. Throwable initCause( Throwable cause ) ;
將另外一個(gè)異常對(duì)象嵌套進(jìn)當(dāng)前異常對(duì)象中。
6. Throwable getCause() ;
取出嵌套在當(dāng)前異常對(duì)象中的異常。
7. void printStackTrace() ;
void printStackTrace( printStream s ) ;
void printStackTrace( printWriter s ) ;
打印出Throwable及其call stack trace信息。
8. void setStackTrace( StackTraceElement[] stackTrace )
設(shè)置對(duì)象的call stack trace信息。
⑨ page - javax.servlet.jsp.HttpJspPage
page對(duì)象代表JSP對(duì)象本身,或者說代表編譯后的servlet對(duì)象,
可以用( (javax.servlet.jsp.HttpJspPage)page )來取用它的方法和屬性。