javascript
JavaWeb学习总结(十七):JSP中的九个内置对象
一、JSP運(yùn)行原理
每個(gè)JSP 頁(yè)面在第一次被訪(fǎng)問(wèn)時(shí),WEB容器都會(huì)把請(qǐng)求交給JSP引擎(即一個(gè)Java程序)去處理。JSP引擎先將JSP翻譯成一個(gè)_jspServlet(實(shí)質(zhì)上也是一個(gè)servlet) ,然后按照servlet的調(diào)用方式進(jìn)行調(diào)用。
由于JSP第一次訪(fǎng)問(wèn)時(shí)會(huì)翻譯成servlet,所以第一次訪(fǎng)問(wèn)通常會(huì)比較慢,但第二次訪(fǎng)問(wèn),JSP引擎如果發(fā)現(xiàn)JSP沒(méi)有變化,就不再翻譯,而是直接調(diào)用,所以程序的執(zhí)行效率不會(huì)受到影響。
JSP引擎在調(diào)用JSP對(duì)應(yīng)的_jspServlet時(shí),會(huì)傳遞或創(chuàng)建9個(gè)與web開(kāi)發(fā)相關(guān)的對(duì)象供_jspServlet使用。JSP技術(shù)的設(shè)計(jì)者為便于開(kāi)發(fā)人員在編寫(xiě)JSP頁(yè)面時(shí)獲得這些web對(duì)象的引用,特意定義了9個(gè)相應(yīng)的變量,開(kāi)發(fā)人員在JSP頁(yè)面中通過(guò)這些變量就可以快速獲得這9大對(duì)象的引用。
二、認(rèn)識(shí)九個(gè)內(nèi)置對(duì)象
| NO. | 內(nèi)置對(duì)象 | 類(lèi)型 |
| 1 | pageContext | javax.servlet.jsp.PageContext |
| 2 | request | javax.servlet.http.HttpServletRequest |
| 3 | response | javax.servlet.http.HttpServletResponse |
| 4 | session | javax.servlet.http.HttpSession |
| 5 | application | javax.servlet.ServletContext |
| 6 | config | javax.servlet.ServletConfig |
| 7 | out | javax.servlet.jsp.JspWriter |
| 8 | page | java.lang.Object |
| 9 | exception | java.lang.Throwable |
?
?
?
?
?
?
?
?
?
?
request,response,session,application,config這些對(duì)象在前面都已經(jīng)作了詳細(xì)的介紹,這里重點(diǎn)介紹一下剩下的pageContext對(duì)象,out對(duì)象,page對(duì)象。
三、內(nèi)置對(duì)象使用說(shuō)明
3.1、page對(duì)象
page對(duì)象表示當(dāng)前一個(gè)JSP頁(yè)面,可以理解為一個(gè)對(duì)象本身,即:把一個(gè)JSP當(dāng)作一個(gè)對(duì)象來(lái)看待。page對(duì)象在開(kāi)發(fā)中幾乎不用,了解一下即可
3.2、out對(duì)象
out對(duì)象用于向客戶(hù)端發(fā)送文本數(shù)據(jù)。?
out對(duì)象是通過(guò)調(diào)用pageContext對(duì)象的getOut方法返回的,其作用和用法與ServletResponse.getWriter方法返回的PrintWriter對(duì)象非常相似。?
JSP頁(yè)面中的out對(duì)象的類(lèi)型為JspWriter,JspWriter相當(dāng)于一種帶緩存功能的PrintWriter,設(shè)置JSP頁(yè)面的page指令的buffer屬性可以調(diào)整它的緩存大小,甚至關(guān)閉它的緩存。?
只有向out對(duì)象中寫(xiě)入了內(nèi)容,且滿(mǎn)足如下任何一個(gè)條件時(shí),out對(duì)象才去調(diào)用ServletResponse.getWriter方法,并通過(guò)該方法返回的PrintWriter對(duì)象將out對(duì)象的緩沖區(qū)中的內(nèi)容真正寫(xiě)入到Servlet引擎提供的緩沖區(qū)中:
- 設(shè)置page指令的buffer屬性關(guān)閉了out對(duì)象的緩存功能
- out對(duì)象的緩沖區(qū)已滿(mǎn)
- 整個(gè)JSP頁(yè)面結(jié)束
out對(duì)象的工作原理圖
3.3、pageContext對(duì)象
pageContext對(duì)象是JSP技術(shù)中最重要的一個(gè)對(duì)象,它代表JSP頁(yè)面的運(yùn)行環(huán)境,這個(gè)對(duì)象不僅封裝了對(duì)其它8大隱式對(duì)象的引用,它自身還是一個(gè)域?qū)ο?容器),可以用來(lái)保存數(shù)據(jù)。并且,這個(gè)對(duì)象還封裝了web開(kāi)發(fā)中經(jīng)常涉及到的一些常用操作,例如引入和跳轉(zhuǎn)其它資源、檢索其它域?qū)ο笾械膶傩缘取?/p>
3.4、通過(guò)pageContext獲得其他對(duì)象
- getException方法返回exception隱式對(duì)象
- getPage方法返回page隱式對(duì)象
- getRequest方法返回request隱式對(duì)象
- getResponse方法返回response隱式對(duì)象
- getServletConfig方法返回config隱式對(duì)象
- getServletContext方法返回application隱式對(duì)象
- getSession方法返回session隱式對(duì)象
- getOut方法返回out隱式對(duì)象
3.5、pageContext封裝其它8大內(nèi)置對(duì)象的意義
如果在編程過(guò)程中,把pageContext對(duì)象傳遞給一個(gè)普通java對(duì)象,那么這個(gè)java對(duì)象將可以獲取8大隱式對(duì)象,此時(shí)這個(gè)java對(duì)象就可以和瀏覽器交互了,此時(shí)這個(gè)java對(duì)象就成為了一個(gè)動(dòng)態(tài)web資源了,這就是pageContext封裝其它8大內(nèi)置對(duì)象的意義,把pageContext傳遞給誰(shuí),誰(shuí)就能成為一個(gè)動(dòng)態(tài)web資源,那么什么情況下需要把pageContext傳遞給另外一個(gè)java類(lèi)呢,什么情況下需要使用這種技術(shù)呢,在比較正規(guī)的開(kāi)發(fā)中,jsp頁(yè)面是不允許出現(xiàn)java代碼的,如果jsp頁(yè)面出現(xiàn)了java代碼,那么就應(yīng)該想辦法把java代碼移除掉,我們可以開(kāi)發(fā)一個(gè)自定義標(biāo)簽來(lái)移除jsp頁(yè)面上的java代碼,首先圍繞自定義標(biāo)簽寫(xiě)一個(gè)java類(lèi),jsp引擎在執(zhí)行自定義標(biāo)簽的時(shí)候就會(huì)調(diào)用圍繞自定義標(biāo)簽寫(xiě)的那個(gè)java類(lèi),在調(diào)用java類(lèi)的時(shí)候就會(huì)把pageContext對(duì)象傳遞給這個(gè)java類(lèi),由于pageContext對(duì)象封裝了對(duì)其它8大隱式對(duì)象的引用,因此在這個(gè)java類(lèi)中就可以使用jsp頁(yè)面中的8大隱式對(duì)象(request,response,config,application,exception,Session,page,out)了,pageContext對(duì)象在jsp自定義標(biāo)簽開(kāi)發(fā)中特別重要。
3.6、pageContext作為域?qū)ο?/h3>
pageContext對(duì)象可以作為容器來(lái)使用,因此可以將一些數(shù)據(jù)存儲(chǔ)在pageContext對(duì)象中。
pageContext對(duì)象的常用方法
1 public void setAttribute(java.lang.String name,java.lang.Object value) 2 public java.lang.Object getAttribute(java.lang.String name) 3 public void removeAttribute(java.lang.String name) 4 public java.lang.Object findAttribute(java.lang.String name) 重點(diǎn)介紹一下findAttribute方法,這個(gè)方法是用來(lái)查找各個(gè)域中的屬性的,查看這個(gè)方法的API可以看到關(guān)于這個(gè)方法的描述:
Searches for the named attribute in page, request, session (if valid), and application scope(s) in order and returns the value associated or null.
當(dāng)要查找某個(gè)屬性時(shí),findAttribute方法按照查找順序"page→request→session→application"在這四個(gè)對(duì)象中去查找,只要找到了就返回屬性值,如果四個(gè)對(duì)象都沒(méi)有找到要查找的屬性,則返回一個(gè)null。
范例:使用pageContext的findAttribute方法查找屬性值
1 <%@page contentType="text/html;charset=UTF-8"%> 2 <%@page import="java.util.*"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <head> 5 <title>pageContext的findAttribute方法查找屬性值</title> 6 </head> 7 <% 8 pageContext.setAttribute("name1", "孤傲蒼狼"); 9 request.setAttribute("name2", "白虎神皇"); 10 session.setAttribute("name3", "玄天邪帝"); 11 application.setAttribute("name4", "滅世魔尊"); 12 %> 13 <% 14 //使用pageContext的findAttribute方法查找屬性,由于取得的值為Object類(lèi)型,因此必須使用String強(qiáng)制向下轉(zhuǎn)型,轉(zhuǎn)換成String類(lèi)型 15 //查找name1屬性,按照順序"page→request→session→application"在這四個(gè)對(duì)象中去查找 16 String refName1 = (String)pageContext.findAttribute("name1"); 17 String refName2 = (String)pageContext.findAttribute("name2"); 18 String refName3 = (String)pageContext.findAttribute("name3"); 19 String refName4 = (String)pageContext.findAttribute("name4"); 20 String refName5 = (String)pageContext.findAttribute("name5");//查找一個(gè)不存在的屬性 21 %> 22 <h1>pageContext.findAttribute方法查找到的屬性值:</h1> 23 <h3>pageContext對(duì)象的name1屬性:<%=refName1%></h3> 24 <h3>request對(duì)象的name2屬性:<%=refName2%></h3> 25 <h3>session對(duì)象的name3屬性:<%=refName3%></h3> 26 <h3>application對(duì)象的name4屬性:<%=refName4%></h3> 27 <h3>查找不存在的name5屬性:<%=refName5%></h3> 28 <hr/> 29 <h1>使用EL表達(dá)式進(jìn)行輸出:</h1> 30 <h3>pageContext對(duì)象的name1屬性:${name1}</h3> 31 <h3>request對(duì)象的name2屬性:${name2}</h3> 32 <h3>session對(duì)象的name3屬性:${name3}</h3> 33 <h3>application對(duì)象的name4屬性:${name4}</h3> 34 <h3>不存在的name5屬性:${name5}</h3>運(yùn)行結(jié)果:
EL表達(dá)式語(yǔ)句在執(zhí)行時(shí),會(huì)調(diào)用pageContext.findAttribute方法,用標(biāo)識(shí)符為關(guān)鍵字,分別從page、request、 session、application四個(gè)域中查找相應(yīng)的對(duì)象,找到則返回相應(yīng)對(duì)象,找不到則返回”” (注意,不是null,而是空字符串)。
pageContext對(duì)象中封裝了訪(fǎng)問(wèn)其它域的方法
1 public java.lang.Object getAttribute(java.lang.String name,int scope) 2 public void setAttribute(java.lang.String name, java.lang.Object value,int scope) 3 public void removeAttribute(java.lang.String name,int scope)代表各個(gè)域的常量
1 PageContext.APPLICATION_SCOPE 2 PageContext.SESSION_SCOPE 3 PageContext.REQUEST_SCOPE 4 PageContext.PAGE_SCOPE范例:pageContext訪(fǎng)問(wèn)其它域
1 <%@page contentType="text/html;charset=UTF-8"%> 2 <%@page import="java.util.*"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <head> 5 <title>pageContext訪(fǎng)問(wèn)其它域</title> 6 </head> 7 <% 8 //此時(shí)相當(dāng)于往session對(duì)象中存放了一個(gè)name屬性,等價(jià)于 session.setAttribute("name","孤傲蒼狼"); 9 pageContext.setAttribute("name","孤傲蒼狼",PageContext.SESSION_SCOPE); 10 %> 11 <% 12 //取得session對(duì)象的屬性,使用pageContext對(duì)象獲取 13 String refName1 = (String)pageContext.getAttribute("name",PageContext.SESSION_SCOPE); 14 //由于取得的值為Object類(lèi)型,因此必須使用String強(qiáng)制向下轉(zhuǎn)型,轉(zhuǎn)換成String類(lèi)型 15 String refName2 = (String)session.getAttribute("name"); 16 %> 17 <h1>取出存放在session對(duì)象中的屬性值:</h1> 18 <p>第一種做法:使用pageContext.getAttribute("attributeName",PageContext.SESSION_SCOPE);去取出session對(duì)象中值</p> 19 <h3>姓名:<%=refName1%></h3> 20 <p>第二種做法:使用session.getAttribute("attributeName");去取出session對(duì)象中值</p> 21 <h3>姓名:<%=refName2%></h3>
3.7、PageContext引入和跳轉(zhuǎn)到其他資源
PageContext類(lèi)中定義了一個(gè)forward方法(用來(lái)跳轉(zhuǎn)頁(yè)面)和兩個(gè)include方法(用來(lái)引入頁(yè)面)來(lái)分別簡(jiǎn)化和替代RequestDispatcher.forward方法和include方法。
方法接收的資源如果以“/”開(kāi)頭, “/”代表當(dāng)前web應(yīng)用。
范例:使用pageContext的forward方法跳轉(zhuǎn)到其他頁(yè)面
1 <%@page contentType="text/html;charset=UTF-8"%> 2 <%@page import="java.util.*"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <head> 5 <title>使用pageContext的forward方法跳轉(zhuǎn)頁(yè)面</title> 6 </head> 7 <% 8 //使用pageContext的forward方法跳轉(zhuǎn)到pageContextDemo05.jsp頁(yè)面,/代表了當(dāng)前的web應(yīng)用 9 pageContext.forward("/pageContextDemo05.jsp"); 10 //使用pageContext.forward(relativeUrlPath)替代RequestDispatcher.forward(relativeUrlPath) 11 //使用RequestDispatcher的forward方法實(shí)現(xiàn)的跳轉(zhuǎn)方式 12 //pageContext.getRequest().getRequestDispatcher("/pageContextDemo05.jsp").forward(request, response); 13 %>運(yùn)行結(jié)果如下:
這種寫(xiě)法是用來(lái)簡(jiǎn)化和替代pageContext.getRequest().getRequestDispatcher("/pageContextDemo05.jsp").forward(request, response);這種寫(xiě)法的。在實(shí)際開(kāi)發(fā)中,使用pageContext.forward(relativeUrlPath)方法跳轉(zhuǎn)頁(yè)面用得不多,主要是因?yàn)橐贘sp頁(yè)面中嵌套java代碼,所以這種做法簡(jiǎn)單了解一下即可,在開(kāi)發(fā)中,要想從一個(gè)Jsp頁(yè)面采用服務(wù)器端跳轉(zhuǎn)的方式跳轉(zhuǎn)到另一個(gè)Jsp頁(yè)面,那么一般會(huì)使用<jsp:forward>標(biāo)簽,<jsp:forward>標(biāo)簽用于把請(qǐng)求轉(zhuǎn)發(fā)給另外一個(gè)資源。
范例:使用pageContext的include方法引入資源
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <head> 4 <title>使用pageContext的include方法引入資源</title> 5 </head> 6 <% 7 pageContext.include("/jspfragments/head.jsp"); 8 %> 9 使用pageContext的include方法引入資源 10 <% 11 pageContext.include("/jspfragments/foot.jsp"); 12 %> 13 <hr/> 14 <%-- 15 <jsp:include page="/jspfragments/head.jsp"/> 16 使用jsp:include標(biāo)簽引入資源 17 <jsp:include page="/jspfragments/foot.jsp"/> 18 --%>運(yùn)行結(jié)果:
?在實(shí)際開(kāi)發(fā)中,使用pageContext的include方法引入頁(yè)面這種做法也很少用,一般都使用jsp:include標(biāo)簽引入資源,因此這種做法了解一下即可。
總結(jié)
以上是生活随笔為你收集整理的JavaWeb学习总结(十七):JSP中的九个内置对象的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: spark中的ALS
- 下一篇: javaweb学习总结(十五):JSP基