javascript
JSP四大作用域详解
首先要聲明一點(diǎn),所謂“作用域”就是“信息共享的范圍”,也就是說(shuō)一個(gè)信息能夠在多大的范圍內(nèi)有效。4個(gè)JSP內(nèi)置對(duì)象的作用域分別為:application、session、request、page 。JSP內(nèi)置對(duì)象作用域表如下:
| 名稱(chēng) | 作用域 |
| application | 在所有應(yīng)用程序中有效 |
| session | 在當(dāng)前會(huì)話(huà)中有效 |
| request | 在當(dāng)前請(qǐng)求中有效 |
| page | 在當(dāng)前頁(yè)面有效 |
?Web交互的最基本單位為HTTP請(qǐng)求。每個(gè)用戶(hù)從進(jìn)入網(wǎng)站到離開(kāi)網(wǎng)站這段過(guò)程稱(chēng)為一個(gè)HTTP會(huì)話(huà),一個(gè)服務(wù)器的運(yùn)行過(guò)程中會(huì)有多個(gè)用戶(hù)訪問(wèn),就是多個(gè)HTTP會(huì)話(huà)。作用域解釋如下。
application 作用域
?????如果把變量放到application里,就說(shuō)明它的作用域是application,它的有效范圍是整個(gè)應(yīng)用。?整個(gè)應(yīng)用是指從應(yīng)用啟動(dòng),到應(yīng)用結(jié)束。我們沒(méi)有說(shuō)“從服務(wù)器啟動(dòng),到服務(wù)器關(guān)閉”,是因?yàn)橐粋€(gè)服務(wù)器可能部署多個(gè)應(yīng)用,當(dāng)然你關(guān)閉了服務(wù)器,就會(huì)把上面所有的應(yīng)用都關(guān)閉了。 application作用域里的變量,它們的存活時(shí)間是最長(zhǎng)的,如果不進(jìn)行手工刪除,它們就一直可以使用。
application作用域上的信息傳遞是通過(guò)ServletContext實(shí)現(xiàn)的,它提供的主要方法如下所示:
Object getAttribute(String name) ?//從application中獲取信息;
void setAttribute(String name, Object value) ?//向application作用域中設(shè)置信息。
?
session作用域
?? ?? ?session作用域比較容易理解,同一瀏覽器對(duì)服務(wù)器進(jìn)行多次訪問(wèn),在這多次訪問(wèn)之間傳遞信息,就是session作用域的體現(xiàn)。如果把變量放到session里,就說(shuō)明它的作用域是session,它的有效范圍是當(dāng)前會(huì)話(huà)。所謂當(dāng)前會(huì)話(huà),就是指從用戶(hù)打開(kāi)瀏覽器開(kāi)始,到用戶(hù)關(guān)閉瀏覽器這中間的過(guò)程。這個(gè)過(guò)程可能包含多個(gè)請(qǐng)求響應(yīng)。也就是說(shuō),只要用戶(hù)不關(guān)瀏覽器,服務(wù)器就有辦法知道這些請(qǐng)求是一個(gè)人發(fā)起的,整個(gè)過(guò)程被稱(chēng)為一個(gè)會(huì)話(huà)(session),而放到會(huì)話(huà)中的變量,就可以在當(dāng)前會(huì)話(huà)的所有請(qǐng)求里使用。?
?session是通過(guò)HttpSession接口實(shí)現(xiàn)的,它提供的主要方法如下所示:
Object HttpSession.getAttribute(String name) ??//從session中獲取信息。
void HttpSession.setAttribute(String name, Object value)//向session中保存信息。
HttpSession HttpServletRequest.getSessio() ?//獲取當(dāng)前請(qǐng)求所在的session的對(duì)象。
?session的開(kāi)始時(shí)刻比較容易判斷,它從瀏覽器發(fā)出第一個(gè)HTTP請(qǐng)求即可認(rèn)為會(huì)話(huà)開(kāi)始。但結(jié)束時(shí)刻就不好判斷了,因?yàn)闉g覽器關(guān)閉時(shí)并不會(huì)通知服務(wù)器,所以只能通過(guò)如下這種方法判斷:如果一定的時(shí)間內(nèi)客戶(hù)端沒(méi)有反應(yīng),則認(rèn)為會(huì)話(huà)結(jié)束。
Tomcat的默認(rèn)值為120分鐘,但這個(gè)值也可以通過(guò)HttpSession的setMaxInactiveInterval()方法來(lái)設(shè)置:
void setMaxInactiveInterval(int interval)
如果想主動(dòng)讓會(huì)話(huà)結(jié)束,例如用戶(hù)單擊“注銷(xiāo)”按鈕的時(shí)候,可以使用 HttpSession 的 invalidate()方法,用于強(qiáng)制結(jié)束當(dāng)前session:void invalidate()
?
?
request作用域
?? ? 一個(gè)HTTP請(qǐng)求的處理可能需要多個(gè)Servlet合作,而這幾個(gè)Servlet之間可以通過(guò)某種方式傳遞信息,但這個(gè)信息在請(qǐng)求結(jié)束后就無(wú)效了。request里的變量可以跨越forward前后的兩頁(yè)。但是只要刷新頁(yè)面,它們就重新計(jì)算了。如果把變量放到request里,就說(shuō)明它的作用域是request,它的有效范圍是當(dāng)前請(qǐng)求周期。?所謂請(qǐng)求周期,就是指從http請(qǐng)求發(fā)起,到服務(wù)器處理結(jié)束,返回響應(yīng)的整個(gè)過(guò)程。在這個(gè)過(guò)程中可能使用forward的方式跳轉(zhuǎn)了多個(gè)jsp頁(yè)面,在這些頁(yè)面里你都可以使用這個(gè)變量。
Servlet之間的信息共享是通過(guò)HttpServletRequest接口的兩個(gè)方法來(lái)實(shí)現(xiàn)的:
void setAttribute(String name, Object value) ??//將對(duì)象value以name為名稱(chēng)保存到request作用域中。
Object getAttribute(String name) //從request作用域中取得指定名字的信息。
?? ? JSP中的doGet()、doPost()方法的第一個(gè)參數(shù)就是HttpServletRequest對(duì)象,使用這個(gè)對(duì)象的 setAttribute()方法即可傳遞信息。那么在設(shè)置好信息之后,要通過(guò)何種方式將信息傳給其他的Servlet呢?這就要用到RequestDispatcher接口的forward()方法,通過(guò)它將請(qǐng)求轉(zhuǎn)發(fā)給其他Servlet。
? ? ? RequestDispatcher ServletContext.getRequestDispatcher(String path)? ? ? ? ? ? ? ? ? ? ? ? ?//取得Dispatcher以便轉(zhuǎn)發(fā),path為轉(zhuǎn)發(fā)的目的Servlet。
? ? ? void RequestDispatcher.forward(ServletRequest request, ServletResponse response)//將request和response轉(zhuǎn)發(fā)
?? ? 因此,只需要在當(dāng)前Servlet中先通過(guò)setAttribute()方法設(shè)置相應(yīng)的屬性,然后使用forward()方法進(jìn)行跳轉(zhuǎn),最后在跳轉(zhuǎn)到的Servlet中通過(guò)使用getAttribute()方法即可實(shí)現(xiàn)信息傳遞。
??需要注意兩點(diǎn):
1、轉(zhuǎn)發(fā)不是重定向,轉(zhuǎn)發(fā)是在Web應(yīng)用內(nèi)部進(jìn)行的。
2、轉(zhuǎn)發(fā)對(duì)瀏覽器是透明的,也就是說(shuō),無(wú)論在服務(wù)器上如何轉(zhuǎn)發(fā),瀏覽器地址欄中顯示的仍然是最初那個(gè)Servlet的地址。
?
page作用域
page對(duì)象的作用范圍僅限于用戶(hù)請(qǐng)求的當(dāng)前頁(yè)面,對(duì)于page對(duì)象的引用將在響應(yīng)返回給客戶(hù)端之后被釋放,或者在請(qǐng)求被轉(zhuǎn)發(fā)到其他地方后被釋放。page里的變量只要頁(yè)面跳轉(zhuǎn)了,它們就不見(jiàn)了。如果把變量放到pageContext里,就說(shuō)明它的作用域是page,它的有效范圍只在當(dāng)前jsp頁(yè)面里。從把變量放到pageContext開(kāi)始,到j(luò)sp頁(yè)面結(jié)束,你都可以使用這個(gè)變量。
以上介紹的作用范圍越來(lái)越小,request和page的生命周期都是短暫的,它們之間的區(qū)別:一個(gè)request可以包含多個(gè)page頁(yè)(include,forward及filter)。
?
為了讓大家更容易理解application、session、request、page 4個(gè)對(duì)象的作用范圍,我們給出兩個(gè)程序來(lái)進(jìn)行詳細(xì)說(shuō)明。
【程序1】page01.jsp
<%@?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">???? <jsp:useBean?id="pagevar"?scope="page"?class="java.lang.StringBuffer"/>???? <jsp:useBean?id="requestvar"?scope="request"?class="java.lang.StringBuffer"/>???? <jsp:useBean?id="sessionvar"?scope="session"??class="java.lang.StringBuffer"/>????<jsp:useBean?id="applicationvar"?scope="application"??class="java.lang.StringBuffer"/>???? <html>???? <head>???? <meta?http-equiv="Content-Type"?content="text/html;?charset=UTF-8">???? <title>JSP內(nèi)置對(duì)象作用域</title>???? </head>???? <body>????<%????pagevar.append("page01");????requestvar.append("page01");????sessionvar.append("page01");????applicationvar.append("page01");???? %>???? <jsp:forward?page="page02.jsp"/>???? </body>???? </html>????【程序2】page02.jsp
<%@ page language="java" import="java.util.*" 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"> <jsp:useBean id="pagevar" scope="page" class="java.lang.StringBuffer"/> <jsp:useBean id="requestvar" scope="request" class="java.lang.StringBuffer"/> <jsp:useBean id="sessionvar" scope="session" class="java.lang.StringBuffer"/> <jsp:useBean id="applicationvar" scope="application" class="java.lang.StringBuffer"/> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP內(nèi)置對(duì)象作用域</title> </head> <body> <% pagevar.append("page02"); requestvar.append("page02"); sessionvar.append("page02"); applicationvar.append("page02"); %> page = <%=pagevar.toString()%><br/> request = <%=requestvar.toString()%><br/> session = <%=sessionvar.toString()%><br/> application = <%=applicationvar.toString()%><br/> </body> </html>測(cè)試步驟以及結(jié)果分析:
1、直接運(yùn)行程序1的結(jié)果為:(圖1)
?
我們看到,page的作用域的值為page02,說(shuō)明確實(shí)只在當(dāng)前的頁(yè)面起作用,即跳轉(zhuǎn)到的page2頁(yè)面;request的作用域在當(dāng)前請(qǐng)求中有效,所以其值為程序1和跳轉(zhuǎn)到程序2之和;session的作用域?yàn)楫?dāng)前會(huì)話(huà),所以其值也是程序1和跳轉(zhuǎn)到程序2之和;而application對(duì)所有應(yīng)用有效,也就是只要在應(yīng)用,都要疊加,即程序1中的值與程序2中的值的疊加;
2.不要關(guān)閉程序1運(yùn)行的瀏覽器,直接運(yùn)行程序2,其結(jié)果為:(圖2)
對(duì)比圖1的結(jié)果,我們發(fā)現(xiàn)page作用域沒(méi)有變化,它的值只是程序2里的值;request作用域僅在當(dāng)前請(qǐng)求作用,故也以程序2的值為準(zhǔn),變成page02;session的作用域?yàn)楫?dāng)前會(huì)話(huà),因?yàn)檫\(yùn)行程序1的瀏覽器保持著,說(shuō)明還處于同一會(huì)話(huà)中,所以要在之前的基礎(chǔ)上疊加上一個(gè)page02;而application對(duì)所有應(yīng)用有效,也就是只要在應(yīng)用,都要疊加,即在之前的基礎(chǔ)上疊加上一個(gè)程序2的page02;
3.將上兩步運(yùn)行程序1和程序2的瀏覽器關(guān)閉,但不關(guān)閉服務(wù)器,重新運(yùn)行程序2,其結(jié)果如下:
?
對(duì)比之前的結(jié)果,我們發(fā)現(xiàn)page作用域依舊沒(méi)有變化,它的值只是程序2即所在頁(yè)面里的值;request作用域僅在當(dāng)前請(qǐng)求作用,故也以程序2的值為準(zhǔn),變成page02;session的作用域?yàn)楫?dāng)前會(huì)話(huà),因?yàn)榍皟刹竭\(yùn)行程序的瀏覽器關(guān)閉了,說(shuō)明之前的會(huì)話(huà)都結(jié)束了,所以其值恢復(fù)成當(dāng)前的程序2里的值page02;而application對(duì)所有應(yīng)用有效,也就是只要在應(yīng)用即服務(wù)器還沒(méi)重啟清空,都要疊加,即在之前的基礎(chǔ)上再疊加上一個(gè)程序2的page02;
總結(jié)
以上是生活随笔為你收集整理的JSP四大作用域详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: go语言学习笔记——godoc的使用(超
- 下一篇: A lpad、rpad填充函数--mys