一、JSP運(yùn)行原理
每個JSP 頁面在第一次被訪問時,WEB容器都會把請求交給JSP引擎(即一個Java程序)去處理慌核。JSP引擎先將JSP翻譯成一個_jspServlet(實質(zhì)上也是一個servlet) 谈跛,然后按照servlet的調(diào)用方式進(jìn)行調(diào)用蜕猫。
由于JSP第一次訪問時會翻譯成servlet箫措,所以第一次訪問通常會比較慢腹备,但第二次訪問,JSP引擎如果發(fā)現(xiàn)JSP沒有變化斤蔓,就不再翻譯植酥,而是直接調(diào)用,所以程序的執(zhí)行效率不會受到影響弦牡。
JSP引擎在調(diào)用JSP對應(yīng)的_jspServlet時友驮,會傳遞或創(chuàng)建9個與web開發(fā)相關(guān)的對象供_jspServlet使用。JSP技術(shù)的設(shè)計者為便于開發(fā)人員在編寫JSP頁面時獲得這些web對象的引用驾锰,特意定義了9個相應(yīng)的變量卸留,開發(fā)人員在JSP頁面中通過這些變量就可以快速獲得這9大對象的引用。
二椭豫、認(rèn)識九個內(nèi)置對象
1耻瑟、request對象
request 對象是 javax.servlet.httpServletRequest類型的對象。 該對象代表了客戶端的請求信息捻悯,主要用于接受通過HTTP協(xié)議傳送到服務(wù)器的數(shù)據(jù)甩骏。(包括頭信息族吻、系統(tǒng)信息、請求方式以及請求參數(shù)等)。request對象的作用域為一次請求外厂。
2泽台、response對象
response 代表的是對客戶端的響應(yīng)莽龟,主要是將JSP容器處理過的對象傳回到客戶端岁经。response對象也具有作用域,它只在JSP頁面內(nèi)有效何荚。
3囱淋、session對象
session 對象是由服務(wù)器自動創(chuàng)建的與用戶請求相關(guān)的對象。服務(wù)器為每個用戶都生成一個session對象餐塘,用于保存該用戶的信息妥衣,跟蹤用戶的操作狀態(tài)。session對象內(nèi)部使用Map類來保存數(shù)據(jù)戒傻,因此保存數(shù)據(jù)的格式為 “Key/value”税手。 session對象的value可以使復(fù)雜的對象類型,而不僅僅局限于字符串類型需纳。
4芦倒、application對象
application 對象可將信息保存在服務(wù)器中,直到服務(wù)器關(guān)閉不翩,否則application對象中保存的信息會在整個應(yīng)用中都有效兵扬。與session對象相比麻裳,application對象生命周期更長,類似于系統(tǒng)的“全局變量”器钟。
5津坑、out 對象
out 對象用于在Web瀏覽器內(nèi)輸出信息,并且管理應(yīng)用服務(wù)器上的輸出緩沖區(qū)傲霸。在使用 out 對象輸出數(shù)據(jù)時国瓮,可以對數(shù)據(jù)緩沖區(qū)進(jìn)行操作,及時清除緩沖區(qū)中的殘余數(shù)據(jù)狞谱,為其他的輸出讓出緩沖空間。待數(shù)據(jù)輸出完畢后禁漓,要及時關(guān)閉輸出流跟衅。
6、pageContext 對象
pageContext 對象的作用是取得任何范圍的參數(shù)播歼,通過它可以獲取 JSP頁面的out伶跷、request、reponse秘狞、session叭莫、application 等對象。pageContext對象的創(chuàng)建和初始化都是由容器來完成的烁试,在JSP頁面中可以直接使用 pageContext對象雇初。
7、config 對象
config 對象的主要作用是取得服務(wù)器的配置信息减响。通過 pageConext對象的 getServletConfig() 方法可以獲取一個config對象靖诗。當(dāng)一個Servlet 初始化時,容器把某些信息通過 config對象傳遞給這個 Servlet支示。 開發(fā)者可以在web.xml 文件中為應(yīng)用程序環(huán)境中的Servlet程序和JSP頁面提供初始化參數(shù)刊橘。
8、page 對象
page 對象代表JSP本身颂鸿,只有在JSP頁面內(nèi)才是合法的促绵。 page隱含對象本質(zhì)上包含當(dāng)前 Servlet接口引用的變量,類似于Java編程中的 this 指針嘴纺。
9败晴、exception 對象
exception 對象的作用是顯示異常信息,只有在包含 isErrorPage="true" 的頁面中才可以被使用颖医,在一般的JSP頁面中使用該對象將無法編譯JSP文件位衩。excepation對象和Java的所有對象一樣,都具有系統(tǒng)提供的繼承結(jié)構(gòu)熔萧。exception 對象幾乎定義了所有異常情況糖驴。在Java程序中僚祷,可以使用try/catch關(guān)鍵字來處理異常情況; 如果在JSP頁面中出現(xiàn)沒有捕獲到的異常贮缕,就會生成 exception 對象辙谜,并把 exception 對象傳送到在page指令中設(shè)定的錯誤頁面中,然后在錯誤頁面中處理相應(yīng)的 exception 對象感昼。
三装哆、內(nèi)置對象使用說明
3.1 page對象
page對象表示當(dāng)前一個JSP頁面,可以理解為一個對象本身定嗓,即:把一個JSP當(dāng)作一個對象來看待蜕琴。page對象在開發(fā)中幾乎不用,了解一下即可
3.2 pageContext對象
pageContext對象是JSP技術(shù)中最重要的一個對象宵溅,它代表JSP頁面的運(yùn)行環(huán)境凌简,這個對象不僅封裝了對其它8大隱式對象的引用,它自身還是一個域?qū)ο?容器)恃逻,可以用來保存數(shù)據(jù)雏搂。并且,這個對象還封裝了web開發(fā)中經(jīng)常涉及到的一些常用操作寇损,例如引入和跳轉(zhuǎn)其它資源凸郑、檢索其它域?qū)ο笾械膶傩缘取?/p>
3.3 通過pageContext獲得其他對象
- getException方法返回exception隱式對象
- getPage方法返回page隱式對象
- getRequest方法返回request隱式對象
- getResponse方法返回response隱式對象
- getServletConfig方法返回config隱式對象
- getServletContext方法返回application隱式對象
- getSession方法返回session隱式對象
- getOut方法返回out隱式對象
3.4 pageContext封裝其它8大內(nèi)置對象的意義
如果在編程過程中,把pageContext對象傳遞給一個普通java對象矛市,那么這個java對象將可以獲取8大隱式對象芙沥,此時這個java對象就可以和瀏覽器交互了,此時這個java對象就成為了一個動態(tài)web資源了尘盼,這就是pageContext封裝其它8大內(nèi)置對象的意義憨愉,把pageContext傳遞給誰,誰就能成為一個動態(tài)web資源卿捎,那么什么情況下需要把pageContext傳遞給另外一個java類呢配紫,什么情況下需要使用這種技術(shù)呢,在比較正規(guī)的開發(fā)中午阵,jsp頁面是不允許出現(xiàn)java代碼的躺孝,如果jsp頁面出現(xiàn)了java代碼,那么就應(yīng)該想辦法把java代碼移除掉底桂,我們可以開發(fā)一個自定義標(biāo)簽來移除jsp頁面上的java代碼植袍,首先圍繞自定義標(biāo)簽寫一個java類,jsp引擎在執(zhí)行自定義標(biāo)簽的時候就會調(diào)用圍繞自定義標(biāo)簽寫的那個java類籽懦,在調(diào)用java類的時候就會把pageContext對象傳遞給這個java類于个,由于pageContext對象封裝了對其它8大隱式對象的引用,因此在這個java類中就可以使用jsp頁面中的8大隱式對象(request暮顺,response厅篓,config秀存,application,exception羽氮,Session或链,page,out)了档押,pageContext對象在jsp自定義標(biāo)簽開發(fā)中特別重要澳盐。
3.5 pageContext作為域?qū)ο?/h6>
pageContext對象可以作為容器來使用,因此可以將一些數(shù)據(jù)存儲在pageContext對象中令宿。
當(dāng)要查找某個屬性時叼耙,findAttribute方法按照查找順序"page→request→session→application"在這四個對象中去查找,只要找到了就返回屬性值粒没,如果四個對象都沒有找到要查找的屬性旬蟋,則返回一個null。
范例:使用pageContext的findAttribute方法查找屬性值
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>pageContext的findAttribute方法查找屬性值</title>
</head>
<body>
<%
pageContext.setAttribute("name1", "宋江");
request.setAttribute("name2", "盧俊義");
session.setAttribute("name3", "李逵");
application.setAttribute("name4", "小李廣花榮");
%>
<%
//使用pageContext查找對象革娄,按照順序page->request->session->application去查找
String namedesc1 = (String)pageContext.getAttribute("name1",pageContext.PAGE_SCOPE);
String namedesc2 = (String)pageContext.getAttribute("name2",pageContext.REQUEST_SCOPE);
String namedesc3 = (String)pageContext.getAttribute("name3",pageContext.SESSION_SCOPE);
String namedesc4 = (String)pageContext.getAttribute("name4",pageContext.APPLICATION_SCOPE);
String namedesc5 = (String)pageContext.getAttribute("name5",pageContext.PAGE_SCOPE);
%>
<h1>pageContext.findAttribute方法查找到的屬性值:</h1>
<h3>pageContext對象的name1屬性值為:<%=namedesc1 %> </h3>
<h3>request對象的name2屬性值為:<%=namedesc2 %></h3>
<h3>session對象的name3屬性值為:<%=namedesc3 %></h3>
<h3>application對象的name4屬性值為:<%=namedesc4 %></h3>
<h3>查找不存在的name屬性: <%=namedesc5 %></h3>
<hr>
<!-- 使用el表達(dá)式進(jìn)行輸出: -->
<h1>使用EL表達(dá)式進(jìn)行輸出:</h1>
<h3>pageContext對象的name1屬性值為:${name1}</h3>
<h3>request對象的name2屬性值為:${name2}</h3>
<h3>session對象的name3屬性值為:${name3}</h3>
<h3>application對象的name4屬性值為:${name4}</h3>
<h3>查找不存在的name屬性: ${name5 }</h3>
</body>
</html>
運(yùn)行結(jié)果:
EL表達(dá)式語句在執(zhí)行時,會調(diào)用pageContext.findAttribute方法冕碟,用標(biāo)識符為關(guān)鍵字拦惋,分別從page、request安寺、 session厕妖、application四個域中查找相應(yīng)的對象,找到則返回相應(yīng)對象挑庶,找不到則返回”” (注意言秸,不是null,而是空字符串)迎捺。
代表各個域的常量
- PageContext.APPLICATION_SCOPE
- PageContext.SESSION_SCOPE
- PageContext.REQUEST_SCOPE
- PageContext.PAGE_SCOPE