JSP九大內置對象(隱式對象)

一、JSP內置對象簡介

JSP內置對象是Web容器創建的一組對象,不使用new關鍵字就可以使用的內置對象。
開發者可以直接使用它們而不用顯式聲明。JSP隱式對象也被稱為預定義變量。

1、JSP內置對象概覽

JSP中的9個內置對象將由容器為用戶進行實例化,用戶直接使用即可。

JSP中的9個內置對象

以上內置對象中常用的是pageContext、request、response、session、application,掌握了這5個,即可進行程序開發。

二、四種屬性范圍

在JSP中提供了4種屬性的保存范圍。所謂的屬性保存范圍,指的就是一個內置對象,可以在多個頁面中保存并繼續使用。

  • page:只在一個頁面中保存屬性,跳轉之后無效。
  • request:只在一次請求中保存,服務器端跳轉后依然有效,超鏈接跳轉無效。
  • session:再一次會話范圍中,無論何種跳轉都可以使用,但是新開瀏覽器無法使用。
  • application:在整個服務器上保存,所有用戶(會話)都可以使用。如果服務器重啟,所有設置屬性將全部消失。

以上的四個內置對象都支持下表所示的操作方法:

屬性操作方法
1、page屬性范圍(pageContext)
page屬性范圍
2、request屬性范圍
request屬性傳遞

關于request屬性范圍的理解
request表示客戶端的請求。正常情況下,一次請求服務器只會給予一次回應,那么這時如果是服務器端跳轉,請求的地址欄沒有改變,所以也就相當于回應了一次;而如果地址欄改變了,就相當于是發出了第二次請求,則地一次請求的內容肯定就已經消失了,所以就無法取得。
request屬性范圍一般在MVC設計模式上應用較多。

3、session屬性范圍
session屬性范圍

每一個新的瀏覽器連接上服務器后就是一個新的session。

4、application屬性范圍
application屬性范圍

application范圍的屬性設置過多會影響服務器性能。

5、深入探究page屬性范圍

從javax.servlet.jsp.PageContext類中可以發現,有如下一種設置屬性的方法:

設置屬性的方法

與之前所使用的setAttribute()方法不同,該方法中用一個int的整型變量,此變量可以指定一個屬性的保存范圍。

4種屬性范圍常量

由上可以發現,pageContext對象可以設置任意范圍的屬性。

三、JSP內置對象詳解

1、request對象

request內置對象是使用最多的一個對象,每當客戶端請求一個JSP頁面時,JSP引擎就會制造一個新的request對象來代表這個請求。
其主要作用是接收客戶端發送而來的請求信息,如請求的參數、發送的頭信息等都屬于客戶端發來的信息。
request對象提供了一系列方法來獲取HTTP頭信息,cookies,HTTP方法等等。
注意:當服務器端想得到客戶端信息時就會使用request對象來完成。

客戶端的請求信息被封裝在request對象中,通過他才能了解到客戶端需求,然后做出響應。request對象具有請求域,即完成客戶端的請求之前,該對象一直有效。

request是javax.servlet.http.HttpServletRequest接口的實例化對象,表示此對象主要是應用在HTTP協議上。
該接口定義如下:

public interface HttpServletRequest extends ServletRequest

從定義上可以發現,HttpServletRequest是ServletRequest接口的子接口。

在Web開發中,交互性是重要的特點,所以request對象在實際開發中使用的較多。

常用的方法如下:

String getParameter(String name);    //返回name指定參數的參數值

String[] getParameterValues(String name);    //返回包含參數name的所有值的屬性

void setAttribute(String, Object);    //設置此請求中的屬性

Object getAttribute(String name);    //返回指定屬性的屬性值

String getContentType();    //得到請求提的MIME類型

String getProtocol();    //返回請求用的協議類型及版本號

String getServerName();    //返回請求的服務器主機名

int getServerPort();    //返回服務器接受此請求所用的端口號

String getCharacterEncoding();    //返回字符編碼方式

void setCharacterEncoding();    //設置請求的字符編碼方式

int getContentLength();    //返回請求體的長度(以字節數)

String getRemoteAddr();    //返回發送此請求的客戶端IP地址

String getRealPath();    //返回一虛擬路徑的真實路徑

String request.getContentPath();    //返回上下文路徑(虛擬路徑)
request內置對象的常用方法

1.1、亂碼解決

在Web開發中使用request接收請求參數是最常見的操作,但是,在進行參數提交時也會存在一些中文的亂碼問題。可以直接通過setCharacterEncoding()方法設置一個統一的編碼即可。

現階段的開發中最好每一個JSP頁面都寫上編碼設置。

1.2、接收請求參數

單一的參數都可以使用getParameter()接收,而一組參數要用getParameterValues()接收。
在表單控件中,像文本框(text)、單選按鈕(radio)、密碼框(password)、隱藏域(hidden)等,一般都會使用getParameter()方法進行接收,因為這些控件在使用時參數的名稱都只有一個不會重復;而像復選框(checked),一般參數的名稱都是重復的,是一組參數,所以只能使用getParameterValues()接收,如果不小心使用了getParameter()方法,則只會接收第一個選中的內容。

在request內置對象中還有一個靈活的方法就是getParameterNames(),此方法可以返回所有請求參數的名稱,但是此方法返回值的類型是Enumeration,所以需要使用hasMoreElements()方法判斷是否有內容以及使用nextElement()方法取出內容。

1.3、顯示全部的頭信息

Java的Web開發使用的是HTTP協議,主要操作就是基于請求和回應,但是在請求和回應的同時也會包含一些其他的信息(如客戶端的IP、Cookie、語言等),那么這些信息就稱為頭信息。

取得頭信息的名稱,可以再直接通過request內置對象的getHeaderNames()方法;而要想取出每一個頭信息的的內容,則需要使用getHeader()方法。

1.4、角色驗證

如果現在某些JSP頁面需要輸入特定的管理員的賬號才能訪問,那么就需要進行角色驗證,而要進行角色驗證就必須使用request內置對象中的isUserInRole()方法完成。

2、response對象

當服務器創建request對象時會同時創建用于響應這個客戶端的response對象。
response對象的主要作用是對客戶端的請求進行回應,將Web服務器處理后的結果發回給客戶端。
通過這個對象,開發者們可以添加新的cookies,時間戳,HTTP狀態碼等等。
response對象屬于javax.servlet.http.HttpServletResponse接口的實例。

HttpServletResponse接口的定義如下:

public interface HttpServletResponse extends ServletResponse

常用方法如下:

String getCharacterEncoding();    //  返回響應用的是何種字符編碼

void setContentType(String type);    //設置響應的MIME類型

PrintWriter getWriter();    //返回可以向客戶端輸出字符的一個對象(輸出流對象),打印輸出提前于內置的out對象。

sendRedirect(java.lang.String location) throws IOException;    //重新定向客戶端的請求

void addCookie(Cookie cookie);    //向客戶端增加Cookie

void setHeader(String name, String value);    //設置回應的頭信息

2.1、設置頭信息

客戶端在進行請求時會發送許多額外的信息,這些就是頭信息。服務器端也可以根據需要向客戶端設置頭信息,在所有頭信息的設置中,定時刷新頁面的頭信息使用的最多,直接使用setHeader()方法,將頭信息名稱設置為refresh,同時制定刷新的時間。

設置指定時間跳轉到指定頁面
response.setHeader("refresh", "3;URL=hello.html");
使用HTML完成定時跳轉的功能
<meta http-equiv="refresh" content="3;url=hello.htm">

定時跳轉屬于客戶端跳轉

2.2、頁面跳轉

在JSP中除了可以通過頭信息的方式完成跳轉外,還可以使用response對象的sendRedirect()方法直接完成頁面跳轉。

response跳轉屬于客戶端跳轉。

請求轉發與請求重定向的區別:

  • 請求重定向:客戶端行為,response.sendRedirect(),從本質上講等同于再次請求,前一次的請求對象不會保存,地址欄的URL地址會改變。
  • 請求轉發:服務器行為,request.getRequestDispatcher().forward(req, resp);是一次請求,轉發后請求對象會保存,地址欄的URL地址不會改變。

客戶端跳轉和服務器端跳轉(<jsp:forward>)有什么區別?
服務器端跳轉后地址欄的信息不會有任何的改變,客戶端跳轉后地址欄會改變,變為跳轉之后的頁面地址。
在使用request屬性范圍時,只有服務器端跳轉才能夠將request屬性保存到跳轉頁;如果客戶端跳轉,則無法進行屬性的傳遞。
服務器端跳轉,在執行到跳轉語句時會立刻進行腳磚;使用的是客戶端跳轉,則是在整個頁面執行完后才執行跳轉。

由于兩種跳轉存在這樣的差異,所以在代碼開發中,尤其在使用了JDBC的操作中,一定要在<jsp:forward>語句執行之前關閉數據庫的鏈接,否則將再也無法關閉。

如果使用了<jsp:forward>,可以通過<jsp:forward>方便的進行參數傳遞;而如果使用了response.sendRedirect()傳遞參數,則只能通過地址重寫的方式完成。

2.3、操作Cookie

Cookie是瀏覽器所提供的一種技術,能夠讓服務器端將一些只需保存在客戶端或者客戶端進行處理的數據,放在客戶端本身使用的計算機中,不需通過網絡的傳輸,因而提高了網頁處理的效率,而且也能夠減少服務器端的負載。但是由于Cookie是服務器端保存在客戶端的信息,所以其安全性也是很差的。

使用Cookie保存信息可以減少客戶端的部分操作。(比如記住密碼的功能)

在JSP總能專門提供了javax.servlet.http.Cookie的操作類,

Cookie定義的常用方法

所有的Cookie是由服務器端設置到客戶端上去的,所以要向客戶端增加Cookie,必須使用response對象的以下方法:

設置Cookie

如果想要獲取向客戶端設置的Cookie,可以通過request對象完成,使用request的以下方法:

取得Cookie

客戶端每次向服務器端發送請求時都會將之前設置Cookie隨著頭信息一起發送到服務器上,所以這時使用request對象的getCookies()方法就可以取出全部設置的Cookie。

實際上,之前設置的Cookie并沒有真正的保存在客戶端上,在重新啟動瀏覽器后,之前設置的Cookie就全部不存在了,則再使用getCookies()方法取得的就是null。如果想要真正的將Cookie保存在客戶端上,就必須設置Cookie 的保存時間,使用setMaxAge()方法即可。
雖然Cookie中可以保存信息,但是并不能無限制的保存,一般一個客戶端最多只能保存300個Cookie,所以數據量太大時將無法使用Cookie。

3、session對象

3.1.、什么是session

session表示客戶端與服務器的一次會話。Web中的session指定是用戶在瀏覽某個網站時,從進入網站到瀏覽器關閉所經過的這段時間,也就是用戶瀏覽這個網站所花費的時間。從上述定義中可以看到,session實際上是一個時間上的概念。
在服務器的內存中保存著不同用戶的session。

session對象在第一個JSP頁面被裝載時自動創建,完成會話期管理。
從一個客戶打開瀏覽器并連接到服務器開始,到客戶關閉瀏覽器離開這個瀏覽器結束,稱此為一個會話。
當一個客戶訪問一個服務器時,可能會在服務器的幾個頁面之間切換,服務器應當通過某種辦法知道這是一個客戶,就需要session對象。

實際上在開發中session對象最主要的用處就是完成用戶的登錄(login)、注銷(logout)等常見功能,每一個session對象都表示不同的訪問用戶。
session對象是javax.servlet.http.HttpSession接口的實例化對象,所以session只能應用在HTTP協議中。

session對象的常用方法如下:

long getCreationTime();    //返回session創建時間

public String getId();    //返回session創建時JSP引擎為它設的唯一ID號

public Object setAttribute(String name, Object value);    //使用指定名稱將對象綁定到此會話

public Object getAttribute(String name);    //返回與此會話中的指定名稱綁定在一起的對象,如果沒有對象綁定在該名稱下,則返回null

String[] getValueNames();    //返回一個包含此session的所有可用屬性的數組

int getMaxInactiveInterval();    //返回兩次請求間隔多長時間此session被取消(單位秒)

public long getLastAccessedTime();    //取得session的最后一次操作時間

public boolean isNew();    //判斷是否是新的session(新用戶)

public void invalidate();    //讓session失效

在HttpSession接口中最重要的部分還是屬性操作,主要是可以完成用戶登錄的合法性的驗證。

3.2、session的生命周期

創建:當客戶端第一次訪問某個JSP或者Servlet的時候,服務器會為當前會話創建一個sessionID,每次客戶端向服務端發送請求時,都會講此session攜帶過去,服務端會對此sessionID進行校驗。
活動:某次會話當中通過超鏈接打開的新頁面屬于同一次會話。只要當前會話頁面沒有全部關閉,重新打開的新的瀏覽器窗口訪問統一項目資源時屬于同一次會話。除非本次會話的所有頁面都關閉后再重新訪問某個JSP或者Servlet將會創建新的會話。

注意:原有會話還存在,只是這個舊的sessionID任然存在于服務端,只不過再也沒有客戶端會攜帶它然后交予服務端校驗。

銷毀:session的銷毀只有三種方式。
(1)調用了session.invalidate()方法。
(2)session過期(超時)
(3)服務器重新啟動

  • Tomcat的默認session超時時間為30分鐘
  • 設置session超時有兩種方式:
    1、session.setMaxInactiveInterval(time); //單位秒
    2、在web.xml配置
<session-config>
        //單位是分鐘
        <session-timeout> 10 </session-timeout>
</session-config>

3.3、取得session ID

當一個用戶連接到服務器后,服務器會自動為此session分配一個不會重復的Session Id,服務器依靠這些不同的session id 來區分每一個不同的用戶,在Web中可以使用HttpSession接口中的getId()方法取得這些編號。

在使用session時必須注意一點,對于每一個已經連接到服務器上的用戶,如果重新啟動服務器,則這些用戶再次發出請求實際上表示的都是一個新連接的用戶,服務器會為每個用戶重新分配新的session id。

3.4、登錄及注銷

在各系中幾乎都存在用戶登錄驗證及注銷的功能,此功能完可以使用session實現。
具體思路是:當用戶登錄成功后,設置一個session范圍的屬性,然后在其他需要驗證的界面中判斷是否存在此session范圍的屬性,如果存在,則表示已經是正常登陸過的合法用戶;如果不存在,則給出提示,并跳轉會登錄頁提示用戶重新登錄,用戶登陸后可以進行注銷的操作。

完成該功能,如下要求:

程序列表

3.5、判斷新用戶

在session對象中可以使用inNew()方法判斷一個用戶是否是第一次訪問頁面。

3.6、取得用戶的操作時間

在session對象中,可以通過getCreationTime()方法取得一個session的創建時間,也可以使用getLastAccessedTime()方法取得一個session的最后一次操作時間。

關于getCreationTime()方法
當用戶第一次連接到服務器上時,服務器就會自動保留一個session的創建時間。

4、application對象

這個對象在JSP頁面的整個生命周期中都代表著這個JSP頁面。這個對象在JSP頁面初始化時被創建,隨著jspDestroy()方法的調用而被移除。
通過向application中添加屬性,則所有組成您web應用的JSP文件都能訪問到這些屬性。

application對象實現了用戶間數據的共享,可存放全局變量。
application對象開始于服務器的啟動,結束予服務器的關閉。
在用戶的前后連接或不同用戶之間的連接中,可以對application對象的同一屬性進行操作。
在任何地方對application對象屬性的操作,都將影響到其他用戶對此的訪問。
服務器的啟動和關閉決定了application對象的生命。
application對象是javax.servlet.ServletContext接口的實例化對象。

application對象常用方法如下:

public void setAttribute(String name, Object value);    //使用指定名稱將對象綁定到此對話

public Object getAttribute(String name);    //返回與此會話中的指定名稱綁定在一起的對象,如果沒有對象綁定在該名稱下,則返回null

Enumeration getAttributeName();    //返回所有可用屬性名的枚舉

String setServerInfo();    //返回JSP(Servlet)引擎名及版本號

String getRealPath(String path);    //得到虛擬路徑對應的絕對路徑

public String getContextPath();    //取得當前的虛擬路徑名稱

在application中最重要的部分也是屬性操作。

4.1、取得虛擬目錄對應的絕對路徑

在Toncat中配置虛擬目錄:

 <Context path="/mldn" docBase="D:\mldnwebdome" />

以上表示的是在瀏覽器中使用“”/mldn“”訪問 "D:\mldnwebdome"目錄,這時如果希望在Web開發中取得docBase對應的真實路徑,就需要使用application對象中的getRealPath()方法來完成。

對于application對象而言,在Web中也可以使用getServletContext()方法代替。在開發中盡量使用該方法。

5、Web安全性及config對象

5.1、Web安全性

在Web目錄中必須存在一個WEB_INF文件夾。在JavaEES的標準中,Web目錄中的WEB_INF是必須存在的,而且此文件夾的安全性是最高的,在各個程序的開發中,基本上都將一些配置信息保存在此文件夾中。
在定義WEB_INF目錄時一定要注意大小寫的問題,這里的字母都必須是大寫。

5.2、config對象

config對象是在一個Servlet初始化時,JSP引擎向它傳遞信息用的,此信息包括Servlet初始化時所用到的參數(通過屬性名和屬性值)以及服務器的有關信息(通過傳遞一個ServletContext對象)。
config是對象是javax.servlet.ServletConfig接口的實例化對象,主要功能是取得一些初始化的配置信息。

Config對象的常用方法如下:

ServletContext getServletContext();    //返回含有服務器相關信息的ServletContext對象

String getInitParameter(String name);    //返回初始化參數的值

Enumeration getInitParameterNames(String name);    //返回Servlet初始化所需所有參數的枚舉

所有初始化參數一定要在web.xml中配置,即如果一個JSP文件想要通過初始化參數取得一些信息,則一定要在web.xml中完成映射。

6、out對象

out是javax.servlet.jsp.JspWriter類的實例化對象,主要功能就是完成頁面的輸出操作,使用println()或print()方法輸出,但是從實際的開發來看,直接使用out對象的幾率較小,一般使用表達式完成輸出的操作。
用來在response對象中寫入內容。
最初的JspWriter類對象根據頁面是否有緩存來進行不同的實例化操作。可以在page指令中使用buffered='false'屬性來輕松關閉緩存。
JspWriter類包含了大部分java.io.PrintWriter類中的方法。不過,JspWriter新增了一些專為處理緩存而設計的方法。還有就是,JspWriter類會拋出IOExceptions異常,而PrintWriter不會。

常用方法如下:

public void println();   //向客戶端打印字符串

public void clear();   //清除緩存區內容,如果在flush之后調用會拋出異常。

public void clearBuffer();    //清除緩存區的內容,如果在flush之后調用不會拋出異常

public void flush();      //將緩存區內容輸出到客戶端

public int getBufferSize();      //返回緩存區的大小以字節數的大小,如不設緩存區則為0

public int getRemaining();    //返回緩存區還剩余多少可用

public boolean isAutoFlush();    //返回緩存區滿時,是自動清空還是拋出異常

public void close();    //關閉輸出流
7、paget對象

page對象就是指向當前JSP頁面本身,有點像類中的this指針,它是java.lang.Object類的實例。

8、pageContext對象

pageContext對象提供了對JSP頁面內所有的對象及名字空間的訪問。
pageContext對象可以訪問到本頁所在的session,也可以取本頁面所在的application的某一屬性值。
pageContext對象相當于頁面中所有功能的集大成者。
pageContext對象的本類名也叫pageContext。
pageContext對象是javax.servlet.jsp.PageContext類的實例,主要表示一個JSP頁面的上下文。
這個對象主要用來訪問頁面信息,同時過濾掉大部分實現細節。
這個對象存儲了request對象和response對象的引用。application對象,config對象,session對象,out對象可以通過訪問這個對象的屬性來導出。
pageContext對象也包含了傳給JSP頁面的指令信息,包括緩存信息,ErrorPage URL,頁面scope等。
PageContext類定義了一些字段,包括PAGE_SCOPE,REQUEST_SCOPE,SESSION_SCOPE, APPLICATION_SCOPE。它也提供了40余種方法,有一半繼承自javax.servlet.jsp.JspContext 類。
其中一個重要的方法就是removeArribute(),它可接受一個或兩個參數。比如,pageContext.removeArribute("attrName")移除四個scope中相關屬性。
但是下面這種方法只移除特定scope中的相關屬性:

pageContext.removeAttribute("attrName", PAGE_SCOPE);

pageContext對象的常用方法:

JspWriter getOut();    //返回當前客戶端響應被使用的JspWriter流(out)

HttpSession getSession();    //返回當前頁中的HttpSession對象(session)

Object getPage();    //返回當前頁的Object對象(page)

ServletRequest getRequest();    //返回當前頁的ServletRequest對象(request)

ServletResponse getResponse();    //返回當前頁的ServletResponse對象(response)

ServletConfig getServletConfig();    //返回當前頁的ServletConfig對象(config)

void setAttribute(String name, Object attribute);    //設置屬性及屬性值

Object getAttribute(String name, int scope);    //在指定范圍內取屬性的值

int getAttributeScope(String name);    //返回某屬性的作用范圍

void forward(String relativeUrlPath);    //使當前頁面跳轉到另一頁面

void include(String relativeUrlPath);    //在當前位置包含另一文件
8、Exception對象

exception對象是一個異常對象,當一個頁面在運行過程中發生了異常,就產生這個對象。如果一個JSP頁面要應用此對象,就必須把isErrorPage設置為true,否則無法編譯。
exception對象是java.lang.Throwable的對象。

exception對象的常用方法如下:

String getMessage();    //返回描述異常的信息

String toString();    //返回關于異常的簡短描述信息

void printStackTrace();    //顯示異常及其棧軌跡

Throwable FIllInStackTrace();    //重寫異常的執行棧軌跡

不難發現,request、response、config、application、<jsp:include>、<jsp:forward>等操作實際上都可以在pageContext對象中完成。

四、實戰開發

使用JSP+JDBC完成一個用戶的登錄程序,登錄成功后可以使用session進行用戶的登錄驗證,用戶根據需要也可以直接進行系統的退出操作。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容