[toc]
第三章 Servlet 容器模型
Web容器在啟動時會加載每個Web應(yīng)用程序,并為每個Web應(yīng)用程序創(chuàng)建唯一的一個ServletContext實(shí)例對象。
3.1 ServletContext接口(???)
整個項(xiàng)目只有一個ServletContext對象
3.1.1 得到ServletContext引用
ServletContext sc = getServletContext();ServletContext sc = getServletConfig().getServletContext();
3.1.2 獲取應(yīng)用程序的初始化參數(shù)
ServletContext對象是在Web應(yīng)用程序裝載時初始化的。
檢索Servlet上下文初始化參數(shù)指定應(yīng)用程序范圍內(nèi)的信息。
public String getInitParameter(String name)-
public Enumeration getInitParameterNames()
在web.xml中設(shè)置初始化參數(shù)
<servlet-context>
<param-name>email</init-name>
<param-value>15454521@163.com</param-value>
</servlet-context>
注意,<servlet-context>元素是針對整個應(yīng)用的,所以并不嵌套在某個<servlet>中。該元素是<web-app>的直接子元素
Servlet上下文初始化參數(shù)與Servlet初始化參數(shù)是不同的,前者是屬于整個web應(yīng)用的,后者是屬于定義它們的Servlet的,不能被web應(yīng)用程序其它組件訪問。
3.1.3 通過ServletContext對象獲得資源
-
public URL getResource(String path): 路徑必須以"/"開頭,它相對于該Web應(yīng)用程序的文檔根目錄。 -
public InputStream getResourceAsStream(String path): 從資源上獲得InputStream對象 - p59
3.1.4 登陸日志(?)
p60
3.1.5 使用RequestDispatcher實(shí)現(xiàn)請求轉(zhuǎn)發(fā)
-
RequestDispatcher getRequestDispatcher(String name): 參數(shù)path表示資源路徑,它必須以"/"開頭,表示相對于web應(yīng)用的文檔根目錄。 -
RequestDispatcher getNamedDispatcher(String name): 參數(shù)name為一個命名的Servlet對象。
ServletContext的getRequestDispatcher與ServletRequest的getRequestDispatcher區(qū)別是,前者只能傳遞以"/"開頭的路徑,而后者可以傳遞一個相對路徑。
例如:request.getRequestDispatcher("../html/copyright.html")是合法的
3.1.6 使用ServletContext對象存儲數(shù)據(jù)(????)
該對象也是一個作用域?qū)ο?,它的作用域是整個應(yīng)用程序。
public void setAttribute(String name, Object object)public Object getAttribute(String name)public Enumeration getAttributeValues(String name)public void removeAttribute(String name)
3.2 會話管理(???)
3.2.1 理解狀態(tài)與會話
協(xié)議記住用戶及其請求的能力稱為狀態(tài)
- HTTP的無狀態(tài)特征
服務(wù)器無法確定多個請求是來自相同的客戶還是不同的客戶。 - 會話的概念
會話是一個客戶與服務(wù)器之間的不間斷的請求響應(yīng)序列。當(dāng)一個客戶向服務(wù)器發(fā)送第一個請求時就開始了一個會話。對該客戶之后的每個請求,服務(wù)器都能識別出來請求來自同一個客戶。
3.2.2 會話管理機(jī)制
- 當(dāng)客戶向服務(wù)器發(fā)送第一個請求時,服務(wù)器就可以為該客戶創(chuàng)建一個HTTPSession會話對象,并將請求對象與該會話對象關(guān)聯(lián)。服務(wù)器在創(chuàng)建會話對象時為其指定一個唯一標(biāo)識符,稱為會話ID。
- 當(dāng)服務(wù)器向客戶發(fā)送響應(yīng)時,服務(wù)器將該會話ID與響應(yīng)數(shù)據(jù)一起發(fā)送給客戶
- 客戶在接受到響應(yīng)后將會話ID存儲在瀏覽器的內(nèi)存中。當(dāng)客戶再次向服務(wù)器發(fā)送一個請求時,它將通過Cookie請求頭把會話ID與請求一起發(fā)送給服務(wù)器。
- 服務(wù)器接收到請求后,從請求對象中取出會話ID,在服務(wù)器中查找之前創(chuàng)建的會話對象,找到后將該請求與之前創(chuàng)建的ID值相同的會話對象關(guān)聯(lián)起來。
注意:不能使用客戶的ID地址唯一標(biāo)識客戶。因?yàn)?,客戶可能時通過局域網(wǎng)訪問Internet。盡管在局域網(wǎng)中每個客戶有一個IP地址,但對于服務(wù)器來說,客戶的實(shí)際IP地址是路由器的IP地址,所以該局域網(wǎng)的所有客戶的IP地址都相同,因此無法唯一標(biāo)識客戶。
3.2.3 HttpSession API
public String getId()-
public long getCreationTime(): 返回會話創(chuàng)建時間 - ...
-
public boolean isNew(): 如果會話對象還沒有同客戶關(guān)聯(lián),則返回true -
public ServletContext getServletContext(): 返回該會話所屬的ServletContext對象 public void setAttribute(String name, Object value)public Object getAttribute(String name)- ...
3.2.4 使用HttpSession對象
共三步:
- 創(chuàng)建或返回與客戶請求關(guān)聯(lián)的會話對象。
-
public HttpSession getSession(boolean create): 返回或創(chuàng)建與當(dāng)前請求關(guān)聯(lián)的會話對象。如果沒有與當(dāng)前請求關(guān)聯(lián)的會話對象,當(dāng)參數(shù)為true時創(chuàng)建一個新的會話對象,當(dāng)參數(shù)為false時返回null。 -
public HttpSession getSession(): 該方法與調(diào)用getSession(true)等價。
-
- 在會話對象中添加或刪除"名/值"對屬性
- 如果需要可使會話失效
3.2.5 會話超時與失效
設(shè)置會話超時時間, 0或者小于0表示會話永不過期。這種設(shè)置方法針對web應(yīng)用程序的所有會話對象,但有時需要對特定的會話對象指定超時時間,可使用會話對象的setMaxInactiveInterval()
<session-config>
<session-timeout>10</session-timeout>
</session-config>
如果沒有這樣進(jìn)行設(shè)置,默認(rèn)時間為30分鐘。
手動銷毀對象可使用HttpSession接口的invalidate()
3.3 Cookie及其應(yīng)用
3.3.1 Cookie API
構(gòu)造方法public Cookie(String name, String value)
常用方法:
-
public String getName(): 返回Cookie名稱 -
public String getValue(): 返回Cookie的值 public void setValue(String newValue)public void setMaxAge(int expiry)public int getMaxAge()- p64
3.3.2 向客戶端發(fā)送Cookie
- 創(chuàng)建Cookie對象
Cookie userCookie = new Cookie("username", "hacker");
- 設(shè)置Cookie的最大存活時間
- 在默認(rèn)情況下,發(fā)送到客戶端的Cookie對象只是一個會話級別的Cookie,它存儲在瀏覽器內(nèi)存中,用戶關(guān)閉瀏覽器后Cookie對象將被刪除。如果希望瀏覽器將Cookie對象存儲到磁盤上,需要使用Cookie類的
setMaxAge()設(shè)置Cookie的最大存活時間。userCookie.setMaxAge(60*60824*7);
- 在默認(rèn)情況下,發(fā)送到客戶端的Cookie對象只是一個會話級別的Cookie,它存儲在瀏覽器內(nèi)存中,用戶關(guān)閉瀏覽器后Cookie對象將被刪除。如果希望瀏覽器將Cookie對象存儲到磁盤上,需要使用Cookie類的
- 向客戶發(fā)送Cookie對象
- 要將Cookie對象發(fā)送到客戶端,需要調(diào)用響應(yīng)對象的
addCookie()將Cookie添加到SetCookie響應(yīng)頭。response.addCookie(userCookie);
- 要將Cookie對象發(fā)送到客戶端,需要調(diào)用響應(yīng)對象的
3.3.3 從客戶端讀取Cookie
從客戶端得到Cookies,調(diào)用請求對象的getCookies(),該方法返回一個Cookies數(shù)組
- 調(diào)用請求對象的
getCookies()Cookie[] cookies = request.getCookies();
- 對Cookie數(shù)組循環(huán)
- 調(diào)用每個Cookie的getName()直到找到一個與希望的名稱相同的對象為止。
3.3.4 Cookie的安全問題
p69
3.3.5 實(shí)例:用Cookie實(shí)現(xiàn)自動登陸
p70