首先要聲明一點,所謂「做用域」就是「信息共享的範圍」,也就是說一個信息可以在多大的範圍內有效。4個JSP內置對象的做用域分別爲:application、session、request、page 。JSP內置對象做用域表以下:html
名稱java |
做用域web |
application瀏覽器 |
在全部應用程序中有效服務器 |
sessionsession |
在當前會話中有效app |
requestjsp |
在當前請求中有效ide |
pageoop |
在當前頁面有效 |
Web交互的最基本單位爲HTTP請求。每一個用戶從進入網站到離開網站這段過程稱爲一個HTTP會話,一個服務器的運行過程當中會有多個用戶訪問,就是多個HTTP會話。做用域解釋以下。
若是把變量放到application裏,就說明它的做用域是application,它的有效範圍是整個應用。 整個應用是指從應用啓動,到應用結束。咱們沒有說「從服務器啓動,到服務器關閉」,是由於一個服務器可能部署多個應用,固然你關閉了服務器,就會把上面全部的應用都關閉了。 application做用域裏的變量,它們的存活時間是最長的,若是不進行手工刪除,它們就一直能夠使用。
application做用域上的信息傳遞是經過ServletContext實現的,它提供的主要方法以下所示:
Object getAttribute(String name) //從application中獲取信息;
void setAttribute(String name, Object value) //向application做用域中設置信息。
session做用域比較容易理解,同一瀏覽器對服務器進行屢次訪問,在這屢次訪問之間傳遞信息,就是session做用域的體現。若是把變量放到session裏,就說明它的做用域是session,它的有效範圍是當前會話。所謂當前會話,就是指從用戶打開瀏覽器開始,到用戶關閉瀏覽器這中間的過程。這個過程可能包含多個請求響應。也就是說,只要用戶不關瀏覽器,服務器就有辦法知道這些請求是一我的發起的,整個過程被稱爲一個會話(session),而放到會話中的變量,就能夠在當前會話的全部請求裏使用。
session是經過HttpSession接口實現的,它提供的主要方法以下所示:
Object HttpSession.getAttribute(String name) //從session中獲取信息。
void HttpSession.setAttribute(String name, Object value)//向session中保存信息。
HttpSession HttpServletRequest.getSessio() //獲取當前請求所在的session的對象。
session的開始時刻比較容易判斷,它從瀏覽器發出第一個HTTP請求便可認爲會話開始。但結束時刻就很差判斷了,由於瀏覽器關閉時並不會通知服務器,因此只能經過以下這種方法判斷:若是必定的時間內客戶端沒有反應,則認爲會話結束。Tomcat的默認值爲120分鐘,但這個值也能夠經過HttpSession的setMaxInactiveInterval()方法來設置:
void setMaxInactiveInterval(int interval)
一個HTTP請求的處理可能須要多個Servlet合做,而這幾個Servlet之間能夠經過某種方式傳遞信息,但這個信息在請求結束後就無效了。request裏的變量能夠跨越forward先後的兩頁。可是隻要刷新頁面,它們就從新計算了。若是把變量放到request裏,就說明它的做用域是request,它的有效範圍是當前請求週期。 所謂請求週期,就是指從http請求發起,到服務器處理結束,返回響應的整個過程。在這個過程當中可能使用forward的方式跳轉了多個jsp頁面,在這些頁面裏你均可以使用這個變量。
Servlet之間的信息共享是經過HttpServletRequest接口的兩個方法來實現的:
void setAttribute(String name, Object value) //將對象value以name爲名稱保存到request做用域中。
Object getAttribute(String name)//從request做用域中取得指定名字的信息。
JSP中的doGet()、doPost()方法的第一個參數就是HttpServletRequest對象,使用這個對象的 setAttribute()方法便可傳遞信息。那麼在設置好信息以後,要經過何種方式將信息傳給其餘的Servlet呢?這就要用到RequestDispatcher接口的forward()方法,經過它將請求轉發給其餘Servlet。
RequestDispatcher ServletContext.getRequestDispatcher(String path) //取得Dispatcher以便轉發,path爲轉發的目的Servlet。
void RequestDispatcher.forward(ServletRequest request, ServletResponse response)//將request和response轉發
所以,只須要在當前Servlet中先經過setAttribute()方法設置相應的屬性,而後使用forward()方法進行跳轉,最後在跳轉到的Servlet中經過使用getAttribute()方法便可實現信息傳遞。
須要注意兩點:
一、轉發不是重定向,轉發是在Web應用內部進行的。
二、轉發對瀏覽器是透明的,也就是說,不管在服務器上如何轉發,瀏覽器地址欄中顯示的仍然是最初那個Servlet的地址。
page對象的做用範圍僅限於用戶請求的當前頁面,對於page對象的引用將在響應返回給客戶端以後被釋放,或者在請求被轉發到其餘地方後被釋放。page裏的變量只要頁面跳轉了,它們就不見了。若是把變量放到pageContext裏,就說明它的做用域是page,它的有效範圍只在當前jsp頁面裏。從把變量放到pageContext開始,到jsp頁面結束,你均可以使用這個變量。
以上介紹的做用範圍愈來愈小,request和page的生命週期都是短暫的,它們之間的區別:一個request能夠包含多個page頁(include,forward及filter)。
【程序1】page01.jsp
【程序2】page02.jsp
測試步驟以及結果分析:
一、直接運行程序1的結果爲:(圖1)
咱們看到,page的做用域的值爲page02,說明確實只在當前的頁面起做用,即跳轉到的page2頁面;request的做用域在當前請求中有效,因此其值爲程序1和跳轉到程序2之和;session的做用域爲當前會話,因此其值也是程序1和跳轉到程序2之和;而application對全部應用有效,也就是隻要在應用,都要疊加,即程序1中的值與程序2中的值的疊加;
二、不要關閉程序1運行的瀏覽器,直接運行程序2,其結果爲:(圖2)
對比圖1的結果,咱們發現page做用域沒有變化,它的值只是程序2裏的值;request做用域僅在當前請求做用,故也以程序2的值爲準,變成page02;session的做用域爲當前會話,由於運行程序1的瀏覽器保持着,說明還處於同一會話中,因此要在以前的基礎上疊加上一個page02;而application對全部應用有效,也就是隻要在應用,都要疊加,即在以前的基礎上疊加上一個程序2的page02;
三、將上兩步運行程序1和程序2的瀏覽器關閉,但不關閉服務器,從新運行程序2,其結果以下:
對比以前的結果,咱們發現page做用域依舊沒有變化,它的值只是程序2即所在頁面裏的值;request做用域僅在當前請求做用,故也以程序2的值爲準,變成page02;session的做用域爲當前會話,由於前兩步運行程序的瀏覽器關閉了,說明以前的會話都結束了,因此其值恢復成當前的程序2裏的值page02;而application對全部應用有效,也就是隻要在應用即服務器還沒重啓清空,都要疊加,即在以前的基礎上再疊加上一個程序2的page02;