鏈接:https://www.zhihu.com/question/31079651/answer/136106134
來源:知乎
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
HTTP協議與狀態保持:Http是一個無狀態協議
1. 實現狀態保持的方案:
1)修改Http協議,使得它支持狀態保持(難做到)
2)Cookies:通過客戶端來保持狀態信息
Cookie是服務器發給客戶端的特殊信息
cookie是以文本的方式保存在客戶端,每次請求時都帶上它
3)Session:通過服務器端來保持狀態信息
Session是服務器和客戶端之間的一系列的交互動作
服務器爲每個客戶端開闢內存空間,從而保持狀態信息
由於需要客戶端也要持有一個標識(id),因此,也要求服務器端和客戶端傳輸該標識,
標識(id)可以藉助Cookie機制或者其他的途徑來保存
2. COOKIE機制
1)Cookie的基本特點
Cookie保存在客戶端
只能保存字符串對象,不能保存對象類型
需要客戶端瀏覽器的支持:客戶端可以不支持,瀏覽器用戶可能會禁用Cookie
2)採用Cookie需要解決的問題
Cookie的創建
通常是在服務器端創建的(當然也可以通過javascript來創建)
服務器通過在http的響應頭加上特殊的指示,那麼瀏覽器在讀取這個指示後就會生成相應的cookie了
Cookie存放的內容
業務信息("key","value")
過期時間
域和路徑
瀏覽器是如何通過Cookie和服務器通信?
通過請求與響應,cookie在服務器和客戶端之間傳遞
每次請求和響應都把cookie信息加載到響應頭中;依靠cookie的key傳遞。
3. COOKIE編程
1)Cookie類
Servlet API封裝了一個類:javax.servlet.http.Cookie,封裝了對Cookie的操作,包括:
public Cookie(String name, String value) //構造方法,用來創建一個Cookie
HttpServletRequest.getCookies() //從Http請求中可以獲取Cookies
HttpServletResponse.addCookie(Cookie) //往Http響應添加Cookie
public int getMaxAge() //獲取Cookie的過期時間值
public void setMaxAge(int expiry) //設置Cookie的過期時間值
2)Cookie的創建
Cookie是一個名值對(key=value),而且不管是key還是value都是字符串
如: Cookie visit = new Cookie("visit", "1");
3)Cookie的類型——過期時間
會話Cookie
Cookie.setMaxAge(-1);//負整數
保存在瀏覽器的內存中,也就是說關閉了瀏覽器,cookie就會丟失
普通cookie
Cookie.setMaxAge(60);//正整數,單位是秒
表示瀏覽器在1分鐘內不繼續訪問服務器,Cookie就會被過時失效並銷燬(通常保存在文件中)
注意:
cookie.setMaxAge(0);//等價於不支持Cookie;
4. SESSION機制
每次客戶端發送請求,服務斷都檢查是否含有sessionId。
如果有,則根據sessionId檢索出session並處理;如果沒有,則創建一個session,並綁定一個不重複的sessionId。
1)基本特點
狀態信息保存在服務器端。這意味着安全性更高
通過類似與Hashtable的數據結構來保存
能支持任何類型的對象(session中可含有多個對象)
2)保存會話id的技術(1)
Cookie
這是默認的方式,在客戶端與服務器端傳遞JSeesionId
缺點:客戶端可能禁用Cookie
表單隱藏字段
在被傳遞迴客戶端之前,在 form 裏面加入一個hidden域,設置JSeesionId:
<input type=hidden name=jsessionid value="3948E432F90932A549D34532EE2394" />
URL重寫
直接在URL後附加上session id的信息
HttpServletResponse對象中,提供瞭如下的方法:
encodeURL(url); //url爲相對路徑
5. SESSION編程
1)HttpSession接口
Servlet API定義了接口:javax.servlet.http.HttpSession, Servlet容器必須實現它,用以跟蹤狀態。
當瀏覽器與Servlet容器建立一個http會話時,容器就會通過此接口自動產生一個HttpSession對象
2)獲取Session
HttpServletRequest對象獲取session,返回HttpSession:
request.getSession(); //表示如果session對象不存在,就創建一個新的會話
request.getSession(true); //等價於上面這句;如果session對象不存在,就創建一個新的會話
request.getSession(false); //表示如果session對象不存在就返回 null,不會創建新的會話對象
3)Session存取信息
session.setAttribute(String name,Object o) //往session中保存信息
Object session.getAttribute(String name) //從session對象中根據名字獲取信息
4)設置Session的有效時間
public void setMaxInactiveInterval(int interval)
設置最大非活動時間間隔,單位秒;
如果參數interval是負值,表示永不過時。零則是不支持session。
通過配置web.xml來設置會話超時,單位是分鐘
<seesion-config>
<session-timeout>1</session-timeout>
</session-config>
允許兩種方式並存,但前者優先級更高
5)其他常用的API
HttpSession.invalidate() //手工銷燬Session
boolean HttpSession.isNew() //判斷Session是否新建
如果是true,表示服務器已經創建了該session,但客戶端還沒有加入(還沒有建立會話的握手)
HttpSession.getId() //獲取session的id
6. 兩種狀態跟蹤機制的比較
Cookie Session
保持在客戶端 保存在服務器端
只能保持字符串對象 支持各種類型對象
通過過期時間值區分Cookie的類型 需要sessionid來維護與客戶端的通信
會話Cookie——負數 Cookie(默認)
普通Cookie——正數 表單隱藏字段
不支持Cookie——0 url重寫
應用領域:web交易需要保存狀態的時候,都可以使用,比如在分佈式場景下可以利用分佈式session技術等。