JSP內(nèi)置對象、指令和動作

JSP內(nèi)置對象、指令和動作

一、內(nèi)置對象

在 JSP 的 Java 代碼塊、表達(dá)式塊等中可以直接使用的引用,稱為 JSP 的內(nèi)置對象。常用的內(nèi)置對象有九個,分別是:

1.jpg

這九個對象在 JSP 的 Java 代碼塊、表達(dá)式塊中可以直接使用。之所以可以直接使用,是因?yàn)?Java 代碼塊與表達(dá)式塊被 JSP 引擎翻譯后均出現(xiàn)在了 Servlet 的_jspService()方法中。而這九個對象,就_jspService()方法中的局部變量。在 JSP 的 Java 代碼塊、表達(dá)式塊中的代碼就是_jspService()方法中的代碼,所以在其中可以直接使用。

2.jpg

1.1 pageContext

pageContext,頁面上下文,其具有一個只在當(dāng)前頁面范圍的域?qū)傩钥臻g,即其具有setAttribute()方法與 getAttribute()方法。但,由于在當(dāng)前頁面范圍,數(shù)據(jù)不存放到域?qū)傩钥臻g也可直接使用,將數(shù)據(jù)存放到域?qū)傩钥臻g反而感覺“多此一舉”,所以這些方法并不常用。不過,在同一頁面中,為了使用 EL 表達(dá)式(后面學(xué)習(xí))來訪問某變量的值,此時一般使用
pageContext。pageContext 具有一些 get 方法,可以獲取到 Request、Response、Session、ServletContext、ServletConfig、page(即當(dāng)前 Servlet)、exception、out 等另外八個內(nèi)置對象。

3.jpg

但由于這些對象本身就是內(nèi)置對象,在 JSP 頁面中可以直接使用,所以這些方法也并不常用。不過 EL 表達(dá)式中,將會經(jīng)常使用 pageContext 的這些方法。

1.2 application

application,即 ServletContext。所以 ServletContext 所具有的方法,application 都具有。
常用的方法例如,

  • String getInitParameter ():
    獲取 web.xml文件的<context-param/>中指定名稱的上下文參數(shù)值。例 如getInitParameter(“myDBDriver”);會返回字符串“com.mysql.jdbc.Driver”。

  • Enumeration getInitParameterNames():獲取 web.xml 文件的<context-param/>中的所有的上下文參數(shù)名稱。其返回值為枚舉類
    型 Enumeration<String>。

  • void setAttribute(String name, Object object):
    在 ServletContext 的公共數(shù)據(jù)空間中,也稱為域?qū)傩钥臻g,放入數(shù)據(jù)。這些數(shù)據(jù)對于 Web應(yīng)用來說,是全局性的,與整個應(yīng)用的生命周期相同。當(dāng)然,放入其中的數(shù)據(jù)是有名稱的,通過名稱來訪問該數(shù)據(jù)。

  • Object getAttribute(String name):
    從 ServletContext 的域?qū)傩钥臻g中獲取指定名稱的數(shù)據(jù)。

  • void removeAttribute(String name):
    從 ServletContext 的域?qū)傩钥臻g中刪除指定名稱的數(shù)據(jù)。

  • String getRealPath(String path):
    獲取當(dāng)前 Web 應(yīng)用中指定文件或目錄在本地文件系統(tǒng)中的路徑,是基于盤符的路徑。

  • String getContextPath():
    獲取當(dāng)前應(yīng)用在 Web 容器中的名稱。

1.3 out

out,類型為 javax.servlet.jsp.JspWriter。查看 JavaEE 文檔,發(fā)現(xiàn) JspWriter 類繼承自 IO流的 Writer 類。即 out 就是一個輸出流對象。

4.jpg

1.4 page

查看 JSP 翻譯為的 Servlet,可以看到 page 對象即 Servlet 對象本身。這個對象在實(shí)際應(yīng)用中并不常用。

5.jpg

1.5 exception

在普通的 JSP 頁面中是不能使用 exception 內(nèi)置對象的。因?yàn)榇蜷_ JSP 翻譯為的 Servlet,發(fā)現(xiàn)其中并沒有 exception 對象。若要在頁面中直接使用 exception 對象,則需要配合著 page指令使用。

1.6 其它對象

其它對象,還有 request、response、session,及 config。它們的用法與Servlet的用法相同。只不過是直接使用在了 JSP 頁面中了。

二、JSP指令

SP 指令的作用是為當(dāng)前頁面做一些基本的屬性設(shè)置,為當(dāng)前的頁面的運(yùn)行提供基本的環(huán)境。

根據(jù)功能的不同,JSP 中包含三類指令:page 指令,即頁面指令;include 指令,即包含指令;及 taglib 指令,即標(biāo)簽庫指令。無論哪種指令,其使用的語法格式均為如下形式:

<%@ 指令名稱 屬性名=屬性值 屬性名=屬性值 ... %>

2.1 page指令

page 指令用于設(shè)置當(dāng)前 JSP 頁面的相關(guān)信息。一個 JSP 文件中可以包含多個 page 指令。常用的 page 指令的屬性意義及用法如下:

(1)pageEncoding屬性

pageEncoding 屬性用于設(shè)置當(dāng)前 JSP 頁面所使用的字符編碼格式。即,用戶在瀏覽器中通過右擊查看編碼所看到的編碼格式。

<%@ page pageEncoding="utf-8" %>

其被 JSP 翻譯引擎翻譯到 Servlet 中的語句,是_jspService()方法中的 setContentType()。

(2)contentType屬性

contentType 屬性用于設(shè)置當(dāng)前 JSP 頁面呈現(xiàn)于用戶瀏覽器中的內(nèi)容類型,通常為”text/html”類型,即 html 格式的文本。若在 JSP 頁面中設(shè)置如下:

<%@ page contentType="text/html" %>

注:當(dāng)內(nèi)容類型為”text/html”時,使用 pageEncoding 屬性與contentType 屬性效果是相同的。只有當(dāng)內(nèi)容類型不為”text/html”時,才專門使用 contentType 屬性指定。在指定字符編碼時,這兩個屬性一般不同時使用。

(3)import屬性

import 屬性,用于完成在 JSP 頁面中導(dǎo)入指定的類。其被 JSP 引擎翻譯為 Servlet 中的import 語句。例如,

<%@ page import="java.util.Date" %>

若要導(dǎo)入多個類,則在 import 屬性值中可使用逗號將這些類分隔。

<%@ page import="java.util.Date,java.sql.*"%>

(4)errorPage屬性

errorPage 屬性用于指定,當(dāng)前頁面運(yùn)行過程中發(fā)生異常時所要跳轉(zhuǎn)到的頁面。

<%@ page errorPage="/error.jsp"%>

<%
    int i = 3/0;
%>

注意,該屬性會被翻譯到 Servlet 的_jspService()方法中,即這里出現(xiàn)的路徑是一個后臺路徑,而非前臺路徑。所以這里指定的發(fā)生異常后所要跳轉(zhuǎn)的頁面,需要使用以斜杠開頭的后臺路徑。

(5)isErrorPage屬性

若一個頁面中指定了發(fā)生異常后所要跳轉(zhuǎn)的頁面,將會出現(xiàn)一個問題:異常信息被隱藏了。在控制臺看不到異常信息,在所跳轉(zhuǎn)的頁面中也看不到異常信息。這對于程序員來說,不是件好事,沒有足夠的信息提示。

此時,一般是希望當(dāng)異常發(fā)生后,在所要跳轉(zhuǎn)的頁面中能夠給出相應(yīng)的異常信息。而異常信息是封裝在異常對象 exception 中的。也就是說,我們需要在所要跳轉(zhuǎn)的頁面中能夠獲取到異常對象。此時,就需要將這個所要跳轉(zhuǎn)的頁面指定為“錯誤處理頁面”。

當(dāng)一個頁面的 page 指令中設(shè)置 isErrorPage 的值為 true 時,表明當(dāng)前頁面為一個“錯誤處理頁面”。默認(rèn) isErrorPage 的值為 false。

<%@ page isErrorPage="true" pageEncoding="utf-8"%>

error page

<%
    //在控制臺輸出異常的堆內(nèi)存跟蹤信息
    exception.printStackTrace();
%>

一旦一個頁面 page 指令的 isErrorPage 屬性被指定為了 true,查看 JSP 頁面所翻譯為的Servlet 則會發(fā)現(xiàn),在_jspService()方法中,多出了一個變量 exception。這就是內(nèi)置對象exception,可以在 JSP 的 Java 代碼塊、表達(dá)式塊中直接使用的內(nèi)置對象。

(6)session屬性

session 屬性用于指定當(dāng)前頁面中是否可以直接使用內(nèi)置對象 session。默認(rèn)為 true,可以使用。查看JSP翻譯為的Servlet,可以看到session的創(chuàng)建,使用的是無參方法getSession()。該方法的功能是,若當(dāng)前具有 session,則使用當(dāng)前的 session;若當(dāng)前沒有 session,則會新建一個 session。即 session 對象肯定不為 null。

但,有些情況下,我們希望的僅僅是獲取到之前已經(jīng)存在的 session,若之前沒有 session,則并不需要創(chuàng)建 session,即讓 session 為 null。顯示使用默認(rèn)的 session 屬性為 true 已經(jīng)無法滿足需求了。此時,就需要將 session 屬性設(shè)置為 false,即不使用內(nèi)置對象session,而是在JSP 頁面的代碼塊中使用 request 的帶參getSession()方法。

HttpSession session = request.getSession(false);

若設(shè)置 session 屬性的值為 false,查看生成的 Servlet 代碼,會發(fā)現(xiàn)根本就沒有出現(xiàn)內(nèi)置對象 session。

2.2 include指令

include 指令,即包含指令,用于將指定的文件包含到當(dāng)前的 JSP 文件中。該指令只有一個屬性 file,用于指定要包含的文件。

(1)用法:被 include 指定包含的文件,可以是 JSP 動態(tài)頁面文件,也可以是 HTML 靜態(tài)頁面文件。這里定義一個名為 left.jsp 的動態(tài)文件。其中定義了一個變量 sum。

left jsp page
<%
    int sum=100;
%>

再定義一個 index.jsp,不僅將 left.jsp 文件包含了進(jìn)來,還訪問了變量 sum。

index jsp page
<br>
<%@ include file="/left.jsp" %>
<br>
<%=sum %>

運(yùn)行結(jié)果:

index jsp page
left jsp page
100

(2)靜態(tài)聯(lián)編

查看 Tomcat 的 work 目錄中相關(guān)子目錄,發(fā)現(xiàn)只生成了一個 index_jsp.java 的 Servlet 源文件,并沒有生成 left_jsp.java 文件。那是因?yàn)?JSP 翻譯引擎在翻譯時,會將 include 指令所指定的文件內(nèi)容直接翻譯到當(dāng)前 JSP 對應(yīng)的 Servlet 中,形成一個.java 文件。這就說明一個問題:這個包含操作是在編譯之前完成的,是在編譯之前由 JSP 翻譯引擎完成的,不是在程序運(yùn)行期完成的。這種包含是一種靜態(tài)包含,稱為靜態(tài)聯(lián)編。

由于在編譯期就將這些文件合并為了一個 Servlet 文件,所以,整個過程就一個_jspService()方法。也就是說,這些文件之間是可以相互訪問局部變量的。只要滿足變量聲明與使用的先后順序即可。

6.jpg

(3)為什么使用include指令

對于一個包含很多頁面的系統(tǒng)或站點(diǎn),很多頁面的頭部、底部,或者左側(cè)部分都是相同的。為了減少頁面定義的重復(fù)性工作,為了便于對這些相同部分的修改,我們將這些相同的部分,分別定義為了多個頁面。然后,讓其它需要使用這些部分的頁面,使用 include 指令將這些部分包含進(jìn)來。這樣的話,不僅大大減少了工作量,還做到了對于頁面修改的“一改全改”效果。

三、JSP動作(Action)

在 JSP 頁面中大量使用 Java 代碼塊、表達(dá)式塊等內(nèi)容,會使 JSP 頁面看起來“雜亂無章”。為了使 JSP 頁面看得簡潔明了,為了簡化 Java 代碼,一般情況下,我們會盡量少的使用 Java代碼塊與表達(dá)式塊。取而代之的則是使用 EL 表達(dá)式、JSTL 標(biāo)簽,及 JSP 動作。

JSP 動作是指,使用系統(tǒng)定義好的標(biāo)簽來完成本應(yīng)由 Java 代碼來完成的功能。

JSP 動作的語法格式為:

<jsp:動作名稱 屬性名=屬性值 屬性名=屬性值 ....></jsp:動作名稱>

<jsp:動作名稱 屬性名=屬性值 屬性名=屬性值 .... />

JSP 動作很多,但在實(shí)際開發(fā)時常用的就兩個:轉(zhuǎn)發(fā)動作與包含動作。
這兩份個動作的完成,底層使用的是 RequestDispatcher 的 forward()與 include()方法實(shí)現(xiàn)的。而這兩份種請求轉(zhuǎn)發(fā)方式的本質(zhì)區(qū)別是,標(biāo)準(zhǔn)輸出流的開啟時間不同。forward()方式的標(biāo)準(zhǔn)輸出流是在目標(biāo)資源中開啟的標(biāo)準(zhǔn)輸出流,而 include()方式的標(biāo)準(zhǔn)輸出流則是在當(dāng)前發(fā)出包含運(yùn)作的頁面中開啟的。所以,forward()動作的發(fā)起頁面中是無法向標(biāo)準(zhǔn)輸出流中寫入數(shù)據(jù)的;而 include()動作的發(fā)起頁面及目標(biāo)頁面中均可向標(biāo)準(zhǔn)輸出流中寫入數(shù)據(jù)。這兩份個動作都具有一個 page 屬性,用于指定要轉(zhuǎn)向的頁面。

3.1 forward動作

頁面中一旦具有了forward動作,那么當(dāng)前頁面中的所有顯示的內(nèi)容都將無法顯示。因?yàn)轫撁嬷苯愚D(zhuǎn)發(fā)到了下一個頁面。

7.jpg

(1)定義index.jsp頁面

<%@ page contentType="text/html; charset=utf-8" %>

頁面中只要具有了forward動作,當(dāng)前頁面中的所有要顯示的內(nèi)容都將無法顯示。因?yàn)轫撁嬷苯愚D(zhuǎn)發(fā)到了下一個頁面。

<%
    request.setAttribute("user","beijing");
%>
<jsp:forward page="/next.jsp"/>

(2)定義next.jsp頁面

next page
<br>
<%=request.getAttribute("user") %>

打開 JSP 頁面翻譯為的 Servlet,可以看到要跳轉(zhuǎn)的路徑出現(xiàn)在了 Servlet 代碼中,即可以使用后臺路徑。

8.jpg

注意,在 JSP 動作中,沒有用于完成重定向的動作。

3.2 include動作

include 動作用于完成將指定頁面包含到當(dāng)前頁面中的功能。

9.jpg

(1)用法

定義index.jsp頁面

index page
<%
    int sum=50;
%>
<br>

<jsp:include page="/left.jsp"/>
<br>
index page sum = <%=sum %>

定義left.jsp頁面

left page
<%
    int sum = 100;
%>
<br>
left page sum = <%=sum %>

運(yùn)行結(jié)果:

index page
left jsp page
left page sum = 100
index page sum = 50

(2)動態(tài)聯(lián)編

打開 Tomcat 的 work 目錄的相關(guān)子目錄,可以看到有兩個.java 文件:index_jsp.java 與left_jsp.java。也就是說,包含動作的包含,是在運(yùn)行期完成的,而非在編譯期。這個包含動作,是在程序運(yùn)行過程中,由 index_jsp 文件中的_jspService()方法通過 JspRuntimeLibrary 類
的 include()方法調(diào)用了 left_jsp 文件中的_jspService()方法。在運(yùn)行期所執(zhí)行的這種包含,稱為動態(tài)聯(lián)編。

(3)靜態(tài)聯(lián)編與動態(tài)聯(lián)編的應(yīng)用場景

在靜態(tài)聯(lián)編與動態(tài)聯(lián)編均可使用時,一般使用靜態(tài)聯(lián)編。因?yàn)樵诔绦蜻\(yùn)行時只存在一個Servlet,對資源的消耗較少,且不存在調(diào)用問題,執(zhí)行效率較高。若在兩個文件間需要共享同一變量,此時只能使用靜態(tài)聯(lián)編。若在兩個文件間存在同名變量,且不能混淆,此時只能使用動態(tài)聯(lián)編。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.什么是JSP (1)jsp全稱是Java Server Pages,它和Servlet技術(shù)一樣都是sun公司定...
    yjaal閱讀 3,834評論 5 99
  • 1.學(xué)習(xí)內(nèi)容 JSP技術(shù)入門和常用指令 JSP的內(nèi)置對象&標(biāo)簽介紹 EL表達(dá)式&EL的內(nèi)置對象 2.JSP技術(shù)入門...
    WendyVIV閱讀 2,326評論 1 18
  • 一、JSP內(nèi)置對象簡介 JSP內(nèi)置對象是Web容器創(chuàng)建的一組對象,不使用new關(guān)鍵字就可以使用的內(nèi)置對象。開發(fā)者可...
    年少懵懂丶流年夢閱讀 3,963評論 0 8
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,652評論 18 399
  • 前面講了servlet入門實(shí)踐現(xiàn)在開始介紹jsp入門實(shí)踐,開發(fā)環(huán)境的搭建請參考我前面的tomcat的文章,jsp入...
    伊豚wall閱讀 3,429評論 2 56

友情鏈接更多精彩內(nèi)容