一、JSP內(nèi)置對象簡介
JSP內(nèi)置對象是Web容器創(chuàng)建的一組對象,不使用new關(guān)鍵字就可以使用的內(nèi)置對象。
開發(fā)者可以直接使用它們而不用顯式聲明。JSP隱式對象也被稱為預(yù)定義變量。
1、JSP內(nèi)置對象概覽
JSP中的9個內(nèi)置對象將由容器為用戶進行實例化,用戶直接使用即可。
以上內(nèi)置對象中常用的是pageContext、request、response、session、application,掌握了這5個,即可進行程序開發(fā)。
二、四種屬性范圍
在JSP中提供了4種屬性的保存范圍。所謂的屬性保存范圍,指的就是一個內(nèi)置對象,可以在多個頁面中保存并繼續(xù)使用。
- page:只在一個頁面中保存屬性,跳轉(zhuǎn)之后無效。
- request:只在一次請求中保存,服務(wù)器端跳轉(zhuǎn)后依然有效,超鏈接跳轉(zhuǎn)無效。
- session:再一次會話范圍中,無論何種跳轉(zhuǎn)都可以使用,但是新開瀏覽器無法使用。
- application:在整個服務(wù)器上保存,所有用戶(會話)都可以使用。如果服務(wù)器重啟,所有設(shè)置屬性將全部消失。
以上的四個內(nèi)置對象都支持下表所示的操作方法:
1、page屬性范圍(pageContext)
2、request屬性范圍
關(guān)于request屬性范圍的理解
request表示客戶端的請求。正常情況下,一次請求服務(wù)器只會給予一次回應(yīng),那么這時如果是服務(wù)器端跳轉(zhuǎn),請求的地址欄沒有改變,所以也就相當于回應(yīng)了一次;而如果地址欄改變了,就相當于是發(fā)出了第二次請求,則地一次請求的內(nèi)容肯定就已經(jīng)消失了,所以就無法取得。
request屬性范圍一般在MVC設(shè)計模式上應(yīng)用較多。
3、session屬性范圍
每一個新的瀏覽器連接上服務(wù)器后就是一個新的session。
4、application屬性范圍
application范圍的屬性設(shè)置過多會影響服務(wù)器性能。
5、深入探究page屬性范圍
從javax.servlet.jsp.PageContext類中可以發(fā)現(xiàn),有如下一種設(shè)置屬性的方法:
與之前所使用的setAttribute()方法不同,該方法中用一個int的整型變量,此變量可以指定一個屬性的保存范圍。
由上可以發(fā)現(xiàn),pageContext對象可以設(shè)置任意范圍的屬性。
三、JSP內(nèi)置對象詳解
1、request對象
request內(nèi)置對象是使用最多的一個對象,每當客戶端請求一個JSP頁面時,JSP引擎就會制造一個新的request對象來代表這個請求。
其主要作用是接收客戶端發(fā)送而來的請求信息,如請求的參數(shù)、發(fā)送的頭信息等都屬于客戶端發(fā)來的信息。
request對象提供了一系列方法來獲取HTTP頭信息,cookies,HTTP方法等等。
注意:當服務(wù)器端想得到客戶端信息時就會使用request對象來完成。
客戶端的請求信息被封裝在request對象中,通過他才能了解到客戶端需求,然后做出響應(yīng)。request對象具有請求域,即完成客戶端的請求之前,該對象一直有效。
request是javax.servlet.http.HttpServletRequest接口的實例化對象,表示此對象主要是應(yīng)用在HTTP協(xié)議上。
該接口定義如下:
public interface HttpServletRequest extends ServletRequest
從定義上可以發(fā)現(xiàn),HttpServletRequest是ServletRequest接口的子接口。
在Web開發(fā)中,交互性是重要的特點,所以request對象在實際開發(fā)中使用的較多。
常用的方法如下:
String getParameter(String name); //返回name指定參數(shù)的參數(shù)值
String[] getParameterValues(String name); //返回包含參數(shù)name的所有值的屬性
void setAttribute(String, Object); //設(shè)置此請求中的屬性
Object getAttribute(String name); //返回指定屬性的屬性值
String getContentType(); //得到請求提的MIME類型
String getProtocol(); //返回請求用的協(xié)議類型及版本號
String getServerName(); //返回請求的服務(wù)器主機名
int getServerPort(); //返回服務(wù)器接受此請求所用的端口號
String getCharacterEncoding(); //返回字符編碼方式
void setCharacterEncoding(); //設(shè)置請求的字符編碼方式
int getContentLength(); //返回請求體的長度(以字節(jié)數(shù))
String getRemoteAddr(); //返回發(fā)送此請求的客戶端IP地址
String getRealPath(); //返回一虛擬路徑的真實路徑
String request.getContentPath(); //返回上下文路徑(虛擬路徑)
1.1、亂碼解決
在Web開發(fā)中使用request接收請求參數(shù)是最常見的操作,但是,在進行參數(shù)提交時也會存在一些中文的亂碼問題。可以直接通過setCharacterEncoding()方法設(shè)置一個統(tǒng)一的編碼即可。
現(xiàn)階段的開發(fā)中最好每一個JSP頁面都寫上編碼設(shè)置。
1.2、接收請求參數(shù)
單一的參數(shù)都可以使用getParameter()接收,而一組參數(shù)要用getParameterValues()接收。
在表單控件中,像文本框(text)、單選按鈕(radio)、密碼框(password)、隱藏域(hidden)等,一般都會使用getParameter()方法進行接收,因為這些控件在使用時參數(shù)的名稱都只有一個不會重復(fù);而像復(fù)選框(checked),一般參數(shù)的名稱都是重復(fù)的,是一組參數(shù),所以只能使用getParameterValues()接收,如果不小心使用了getParameter()方法,則只會接收第一個選中的內(nèi)容。
在request內(nèi)置對象中還有一個靈活的方法就是getParameterNames(),此方法可以返回所有請求參數(shù)的名稱,但是此方法返回值的類型是Enumeration,所以需要使用hasMoreElements()方法判斷是否有內(nèi)容以及使用nextElement()方法取出內(nèi)容。
1.3、顯示全部的頭信息
Java的Web開發(fā)使用的是HTTP協(xié)議,主要操作就是基于請求和回應(yīng),但是在請求和回應(yīng)的同時也會包含一些其他的信息(如客戶端的IP、Cookie、語言等),那么這些信息就稱為頭信息。
取得頭信息的名稱,可以再直接通過request內(nèi)置對象的getHeaderNames()方法;而要想取出每一個頭信息的的內(nèi)容,則需要使用getHeader()方法。
1.4、角色驗證
如果現(xiàn)在某些JSP頁面需要輸入特定的管理員的賬號才能訪問,那么就需要進行角色驗證,而要進行角色驗證就必須使用request內(nèi)置對象中的isUserInRole()方法完成。
2、response對象
當服務(wù)器創(chuàng)建request對象時會同時創(chuàng)建用于響應(yīng)這個客戶端的response對象。
response對象的主要作用是對客戶端的請求進行回應(yīng),將Web服務(wù)器處理后的結(jié)果發(fā)回給客戶端。
通過這個對象,開發(fā)者們可以添加新的cookies,時間戳,HTTP狀態(tài)碼等等。
response對象屬于javax.servlet.http.HttpServletResponse接口的實例。
HttpServletResponse接口的定義如下:
public interface HttpServletResponse extends ServletResponse
常用方法如下:
String getCharacterEncoding(); // 返回響應(yīng)用的是何種字符編碼
void setContentType(String type); //設(shè)置響應(yīng)的MIME類型
PrintWriter getWriter(); //返回可以向客戶端輸出字符的一個對象(輸出流對象),打印輸出提前于內(nèi)置的out對象。
sendRedirect(java.lang.String location) throws IOException; //重新定向客戶端的請求
void addCookie(Cookie cookie); //向客戶端增加Cookie
void setHeader(String name, String value); //設(shè)置回應(yīng)的頭信息
2.1、設(shè)置頭信息
客戶端在進行請求時會發(fā)送許多額外的信息,這些就是頭信息。服務(wù)器端也可以根據(jù)需要向客戶端設(shè)置頭信息,在所有頭信息的設(shè)置中,定時刷新頁面的頭信息使用的最多,直接使用setHeader()方法,將頭信息名稱設(shè)置為refresh,同時制定刷新的時間。
設(shè)置指定時間跳轉(zhuǎn)到指定頁面
response.setHeader("refresh", "3;URL=hello.html");
使用HTML完成定時跳轉(zhuǎn)的功能
<meta http-equiv="refresh" content="3;url=hello.htm">
定時跳轉(zhuǎn)屬于客戶端跳轉(zhuǎn)
2.2、頁面跳轉(zhuǎn)
在JSP中除了可以通過頭信息的方式完成跳轉(zhuǎn)外,還可以使用response對象的sendRedirect()方法直接完成頁面跳轉(zhuǎn)。
response跳轉(zhuǎn)屬于客戶端跳轉(zhuǎn)。
請求轉(zhuǎn)發(fā)與請求重定向的區(qū)別:
- 請求重定向:客戶端行為,response.sendRedirect(),從本質(zhì)上講等同于再次請求,前一次的請求對象不會保存,地址欄的URL地址會改變。
- 請求轉(zhuǎn)發(fā):服務(wù)器行為,request.getRequestDispatcher().forward(req, resp);是一次請求,轉(zhuǎn)發(fā)后請求對象會保存,地址欄的URL地址不會改變。
客戶端跳轉(zhuǎn)和服務(wù)器端跳轉(zhuǎn)(<jsp:forward>)有什么區(qū)別?
服務(wù)器端跳轉(zhuǎn)后地址欄的信息不會有任何的改變,客戶端跳轉(zhuǎn)后地址欄會改變,變?yōu)樘D(zhuǎn)之后的頁面地址。
在使用request屬性范圍時,只有服務(wù)器端跳轉(zhuǎn)才能夠?qū)equest屬性保存到跳轉(zhuǎn)頁;如果客戶端跳轉(zhuǎn),則無法進行屬性的傳遞。
服務(wù)器端跳轉(zhuǎn),在執(zhí)行到跳轉(zhuǎn)語句時會立刻進行腳磚;使用的是客戶端跳轉(zhuǎn),則是在整個頁面執(zhí)行完后才執(zhí)行跳轉(zhuǎn)。
由于兩種跳轉(zhuǎn)存在這樣的差異,所以在代碼開發(fā)中,尤其在使用了JDBC的操作中,一定要在<jsp:forward>語句執(zhí)行之前關(guān)閉數(shù)據(jù)庫的鏈接,否則將再也無法關(guān)閉。
如果使用了<jsp:forward>,可以通過<jsp:forward>方便的進行參數(shù)傳遞;而如果使用了response.sendRedirect()傳遞參數(shù),則只能通過地址重寫的方式完成。
2.3、操作Cookie
Cookie是瀏覽器所提供的一種技術(shù),能夠讓服務(wù)器端將一些只需保存在客戶端或者客戶端進行處理的數(shù)據(jù),放在客戶端本身使用的計算機中,不需通過網(wǎng)絡(luò)的傳輸,因而提高了網(wǎng)頁處理的效率,而且也能夠減少服務(wù)器端的負載。但是由于Cookie是服務(wù)器端保存在客戶端的信息,所以其安全性也是很差的。
使用Cookie保存信息可以減少客戶端的部分操作。(比如記住密碼的功能)
在JSP總能專門提供了javax.servlet.http.Cookie的操作類,
所有的Cookie是由服務(wù)器端設(shè)置到客戶端上去的,所以要向客戶端增加Cookie,必須使用response對象的以下方法:
如果想要獲取向客戶端設(shè)置的Cookie,可以通過request對象完成,使用request的以下方法:
客戶端每次向服務(wù)器端發(fā)送請求時都會將之前設(shè)置Cookie隨著頭信息一起發(fā)送到服務(wù)器上,所以這時使用request對象的getCookies()方法就可以取出全部設(shè)置的Cookie。
實際上,之前設(shè)置的Cookie并沒有真正的保存在客戶端上,在重新啟動瀏覽器后,之前設(shè)置的Cookie就全部不存在了,則再使用getCookies()方法取得的就是null。如果想要真正的將Cookie保存在客戶端上,就必須設(shè)置Cookie 的保存時間,使用setMaxAge()方法即可。
雖然Cookie中可以保存信息,但是并不能無限制的保存,一般一個客戶端最多只能保存300個Cookie,所以數(shù)據(jù)量太大時將無法使用Cookie。
3、session對象
3.1.、什么是session
session表示客戶端與服務(wù)器的一次會話。Web中的session指定是用戶在瀏覽某個網(wǎng)站時,從進入網(wǎng)站到瀏覽器關(guān)閉所經(jīng)過的這段時間,也就是用戶瀏覽這個網(wǎng)站所花費的時間。從上述定義中可以看到,session實際上是一個時間上的概念。
在服務(wù)器的內(nèi)存中保存著不同用戶的session。
session對象在第一個JSP頁面被裝載時自動創(chuàng)建,完成會話期管理。
從一個客戶打開瀏覽器并連接到服務(wù)器開始,到客戶關(guān)閉瀏覽器離開這個瀏覽器結(jié)束,稱此為一個會話。
當一個客戶訪問一個服務(wù)器時,可能會在服務(wù)器的幾個頁面之間切換,服務(wù)器應(yīng)當通過某種辦法知道這是一個客戶,就需要session對象。
實際上在開發(fā)中session對象最主要的用處就是完成用戶的登錄(login)、注銷(logout)等常見功能,每一個session對象都表示不同的訪問用戶。
session對象是javax.servlet.http.HttpSession接口的實例化對象,所以session只能應(yīng)用在HTTP協(xié)議中。
session對象的常用方法如下:
long getCreationTime(); //返回session創(chuàng)建時間
public String getId(); //返回session創(chuàng)建時JSP引擎為它設(shè)的唯一ID號
public Object setAttribute(String name, Object value); //使用指定名稱將對象綁定到此會話
public Object getAttribute(String name); //返回與此會話中的指定名稱綁定在一起的對象,如果沒有對象綁定在該名稱下,則返回null
String[] getValueNames(); //返回一個包含此session的所有可用屬性的數(shù)組
int getMaxInactiveInterval(); //返回兩次請求間隔多長時間此session被取消(單位秒)
public long getLastAccessedTime(); //取得session的最后一次操作時間
public boolean isNew(); //判斷是否是新的session(新用戶)
public void invalidate(); //讓session失效
在HttpSession接口中最重要的部分還是屬性操作,主要是可以完成用戶登錄的合法性的驗證。
3.2、session的生命周期
創(chuàng)建:當客戶端第一次訪問某個JSP或者Servlet的時候,服務(wù)器會為當前會話創(chuàng)建一個sessionID,每次客戶端向服務(wù)端發(fā)送請求時,都會講此session攜帶過去,服務(wù)端會對此sessionID進行校驗。
活動:某次會話當中通過超鏈接打開的新頁面屬于同一次會話。只要當前會話頁面沒有全部關(guān)閉,重新打開的新的瀏覽器窗口訪問統(tǒng)一項目資源時屬于同一次會話。除非本次會話的所有頁面都關(guān)閉后再重新訪問某個JSP或者Servlet將會創(chuàng)建新的會話。
注意:原有會話還存在,只是這個舊的sessionID任然存在于服務(wù)端,只不過再也沒有客戶端會攜帶它然后交予服務(wù)端校驗。
銷毀:session的銷毀只有三種方式。
(1)調(diào)用了session.invalidate()方法。
(2)session過期(超時)
(3)服務(wù)器重新啟動
- Tomcat的默認session超時時間為30分鐘
- 設(shè)置session超時有兩種方式:
1、session.setMaxInactiveInterval(time); //單位秒
2、在web.xml配置
<session-config>
//單位是分鐘
<session-timeout> 10 </session-timeout>
</session-config>
3.3、取得session ID
當一個用戶連接到服務(wù)器后,服務(wù)器會自動為此session分配一個不會重復(fù)的Session Id,服務(wù)器依靠這些不同的session id 來區(qū)分每一個不同的用戶,在Web中可以使用HttpSession接口中的getId()方法取得這些編號。
在使用session時必須注意一點,對于每一個已經(jīng)連接到服務(wù)器上的用戶,如果重新啟動服務(wù)器,則這些用戶再次發(fā)出請求實際上表示的都是一個新連接的用戶,服務(wù)器會為每個用戶重新分配新的session id。
3.4、登錄及注銷
在各系中幾乎都存在用戶登錄驗證及注銷的功能,此功能完可以使用session實現(xiàn)。
具體思路是:當用戶登錄成功后,設(shè)置一個session范圍的屬性,然后在其他需要驗證的界面中判斷是否存在此session范圍的屬性,如果存在,則表示已經(jīng)是正常登陸過的合法用戶;如果不存在,則給出提示,并跳轉(zhuǎn)會登錄頁提示用戶重新登錄,用戶登陸后可以進行注銷的操作。
完成該功能,如下要求:
3.5、判斷新用戶
在session對象中可以使用inNew()方法判斷一個用戶是否是第一次訪問頁面。
3.6、取得用戶的操作時間
在session對象中,可以通過getCreationTime()方法取得一個session的創(chuàng)建時間,也可以使用getLastAccessedTime()方法取得一個session的最后一次操作時間。
關(guān)于getCreationTime()方法
當用戶第一次連接到服務(wù)器上時,服務(wù)器就會自動保留一個session的創(chuàng)建時間。
4、application對象
這個對象在JSP頁面的整個生命周期中都代表著這個JSP頁面。這個對象在JSP頁面初始化時被創(chuàng)建,隨著jspDestroy()方法的調(diào)用而被移除。
通過向application中添加屬性,則所有組成您web應(yīng)用的JSP文件都能訪問到這些屬性。
application對象實現(xiàn)了用戶間數(shù)據(jù)的共享,可存放全局變量。
application對象開始于服務(wù)器的啟動,結(jié)束予服務(wù)器的關(guān)閉。
在用戶的前后連接或不同用戶之間的連接中,可以對application對象的同一屬性進行操作。
在任何地方對application對象屬性的操作,都將影響到其他用戶對此的訪問。
服務(wù)器的啟動和關(guān)閉決定了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); //得到虛擬路徑對應(yīng)的絕對路徑
public String getContextPath(); //取得當前的虛擬路徑名稱
在application中最重要的部分也是屬性操作。
4.1、取得虛擬目錄對應(yīng)的絕對路徑
在Toncat中配置虛擬目錄:
<Context path="/mldn" docBase="D:\mldnwebdome" />
以上表示的是在瀏覽器中使用“”/mldn“”訪問 "D:\mldnwebdome"目錄,這時如果希望在Web開發(fā)中取得docBase對應(yīng)的真實路徑,就需要使用application對象中的getRealPath()方法來完成。
對于application對象而言,在Web中也可以使用getServletContext()方法代替。在開發(fā)中盡量使用該方法。
5、Web安全性及config對象
5.1、Web安全性
在Web目錄中必須存在一個WEB_INF文件夾。在JavaEES的標準中,Web目錄中的WEB_INF是必須存在的,而且此文件夾的安全性是最高的,在各個程序的開發(fā)中,基本上都將一些配置信息保存在此文件夾中。
在定義WEB_INF目錄時一定要注意大小寫的問題,這里的字母都必須是大寫。
5.2、config對象
config對象是在一個Servlet初始化時,JSP引擎向它傳遞信息用的,此信息包括Servlet初始化時所用到的參數(shù)(通過屬性名和屬性值)以及服務(wù)器的有關(guān)信息(通過傳遞一個ServletContext對象)。
config是對象是javax.servlet.ServletConfig接口的實例化對象,主要功能是取得一些初始化的配置信息。
Config對象的常用方法如下:
ServletContext getServletContext(); //返回含有服務(wù)器相關(guān)信息的ServletContext對象
String getInitParameter(String name); //返回初始化參數(shù)的值
Enumeration getInitParameterNames(String name); //返回Servlet初始化所需所有參數(shù)的枚舉
所有初始化參數(shù)一定要在web.xml中配置,即如果一個JSP文件想要通過初始化參數(shù)取得一些信息,則一定要在web.xml中完成映射。
6、out對象
out是javax.servlet.jsp.JspWriter類的實例化對象,主要功能就是完成頁面的輸出操作,使用println()或print()方法輸出,但是從實際的開發(fā)來看,直接使用out對象的幾率較小,一般使用表達式完成輸出的操作。
用來在response對象中寫入內(nèi)容。
最初的JspWriter類對象根據(jù)頁面是否有緩存來進行不同的實例化操作。可以在page指令中使用buffered='false'屬性來輕松關(guān)閉緩存。
JspWriter類包含了大部分java.io.PrintWriter類中的方法。不過,JspWriter新增了一些專為處理緩存而設(shè)計的方法。還有就是,JspWriter類會拋出IOExceptions異常,而PrintWriter不會。
常用方法如下:
public void println(); //向客戶端打印字符串
public void clear(); //清除緩存區(qū)內(nèi)容,如果在flush之后調(diào)用會拋出異常。
public void clearBuffer(); //清除緩存區(qū)的內(nèi)容,如果在flush之后調(diào)用不會拋出異常
public void flush(); //將緩存區(qū)內(nèi)容輸出到客戶端
public int getBufferSize(); //返回緩存區(qū)的大小以字節(jié)數(shù)的大小,如不設(shè)緩存區(qū)則為0
public int getRemaining(); //返回緩存區(qū)還剩余多少可用
public boolean isAutoFlush(); //返回緩存區(qū)滿時,是自動清空還是拋出異常
public void close(); //關(guān)閉輸出流
7、paget對象
page對象就是指向當前JSP頁面本身,有點像類中的this指針,它是java.lang.Object類的實例。
8、pageContext對象
pageContext對象提供了對JSP頁面內(nèi)所有的對象及名字空間的訪問。
pageContext對象可以訪問到本頁所在的session,也可以取本頁面所在的application的某一屬性值。
pageContext對象相當于頁面中所有功能的集大成者。
pageContext對象的本類名也叫pageContext。
pageContext對象是javax.servlet.jsp.PageContext類的實例,主要表示一個JSP頁面的上下文。
這個對象主要用來訪問頁面信息,同時過濾掉大部分實現(xiàn)細節(jié)。
這個對象存儲了request對象和response對象的引用。application對象,config對象,session對象,out對象可以通過訪問這個對象的屬性來導(dǎo)出。
pageContext對象也包含了傳給JSP頁面的指令信息,包括緩存信息,ErrorPage URL,頁面scope等。
PageContext類定義了一些字段,包括PAGE_SCOPE,REQUEST_SCOPE,SESSION_SCOPE, APPLICATION_SCOPE。它也提供了40余種方法,有一半繼承自javax.servlet.jsp.JspContext 類。
其中一個重要的方法就是removeArribute(),它可接受一個或兩個參數(shù)。比如,pageContext.removeArribute("attrName")移除四個scope中相關(guān)屬性。
但是下面這種方法只移除特定scope中的相關(guān)屬性:
pageContext.removeAttribute("attrName", PAGE_SCOPE);
pageContext對象的常用方法:
JspWriter getOut(); //返回當前客戶端響應(yīng)被使用的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); //設(shè)置屬性及屬性值
Object getAttribute(String name, int scope); //在指定范圍內(nèi)取屬性的值
int getAttributeScope(String name); //返回某屬性的作用范圍
void forward(String relativeUrlPath); //使當前頁面跳轉(zhuǎn)到另一頁面
void include(String relativeUrlPath); //在當前位置包含另一文件
8、Exception對象
exception對象是一個異常對象,當一個頁面在運行過程中發(fā)生了異常,就產(chǎn)生這個對象。如果一個JSP頁面要應(yīng)用此對象,就必須把isErrorPage設(shè)置為true,否則無法編譯。
exception對象是java.lang.Throwable的對象。
exception對象的常用方法如下:
String getMessage(); //返回描述異常的信息
String toString(); //返回關(guān)于異常的簡短描述信息
void printStackTrace(); //顯示異常及其棧軌跡
Throwable FIllInStackTrace(); //重寫異常的執(zhí)行棧軌跡
不難發(fā)現(xiàn),request、response、config、application、<jsp:include>、<jsp:forward>等操作實際上都可以在pageContext對象中完成。
四、實戰(zhàn)開發(fā)
使用JSP+JDBC完成一個用戶的登錄程序,登錄成功后可以使用session進行用戶的登錄驗證,用戶根據(jù)需要也可以直接進行系統(tǒng)的退出操作。