什么是session
Session一般譯作會話,牛津詞典對其的解釋是進行某活動連續的一段時間。從不同的層面看待session,它有着類似但不全然相同的含義。比如,在web應用的用戶看來,他打開瀏覽器訪問一個電子商務網站,登錄、並完成購物直到關閉瀏覽器,這是一個會話。而在web應用的開發者開來,用戶登錄時我需要創建一個數據結構以存儲用戶的登錄信息,這個結構也叫做session。因此在談論session的時候要注意上下文環境。
為什么用session
session用來解決http無狀態的問題
什么是無狀態?
- 設計HTTP最初的目的是為了提供一種發布和接收HTML頁面的方法。那個時候沒有動態頁面技術,只有純粹的靜態HTML頁面,因此根本不需要協議能保持狀態;每一次請求之間並沒有聯系。
- 用戶在收到響應時,往往要花一些時間來閱讀頁面,因此如果保持客戶端和服務端之間的連接,那么這個連接在大多數的時間里都將是空閑的,這是一種資源的無端浪費。所以HTTP原始的設計是默認短連接,即客戶端和服務端完成一次請求和響應之后就斷開TCP連接,服務器因此無法預知客戶端的下一個動作,它甚至都不知道這個用戶會不會再次訪問,因此讓HTTP協議來維護用戶的訪問狀態也全然沒有必要;
- 講一個故事:樓下老王的燒烤檔生意很好,每天都人山人海,大胖隔三差五就去一次,大胖很喜歡擼串,人人都知道,就連老王都知道(老王不知道大胖長什么樣),老王也想想給大胖這樣的客戶打個折。每次買單的時候,都跟老王說,打個折行不行,老王說不行,大胖說我經常來,老王說我知道大胖這個人經常來,但是我不知道大胖是誰,每天都有客人,我哪里知道誰是大胖,大胖心里忒不爽。在這里,大胖就好比一個用戶,老王就好比服務器,老王知道大胖這個人常來(服務器存儲了用戶的信息),"打折"這個要求就類似於用戶發送的一個請求,老王並不知道是哪個人想要打折(服務器不知道這次請求是要對誰執行),必須要要有一個證明,證明這個人是大胖。
無狀態會有什么問題?
我們每次發送請求給服務器,服務器並不知道你是誰,如果涉及到數據庫操作,要對修改某一個用戶的信息,那么這兒時候該對修改誰的?就像老王並不知道剛進店里的那個胖子是大胖,那么就沒辦法給他打折了,難不成給幾年不來一次的小瘦也打折。
怎么解決無狀態?
於是協商之下,決定辦一張大胖特有的會員卡,下次買單的時候,老王依然對大胖沒有印象。大胖心想,早預料到你這樣說了,然后從褲兜里掏出會員卡,給!老王,老王把卡上的號碼和本子一對,確實是這個人。哈哈,胖爺,原來是你,老王二話不說就給大胖打了折,然后大胖咬着牙簽,大遙大擺地走了。但是其實,老王記性還不是很好,每次都要對卡號才知道誰是大胖。
怎么用session(實現自動登錄)
因為請求是無狀態的,所以每次請求,我們都需要出示證明。
比如說我想跳過登錄,直接訪問主頁,我們會發現,我們會跳回到登陸頁。
后台:
@WebServlet("/Login")
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String username=request.getParameter("username");
String password=request.getParameter("password");
//登錄成功會給session對象設置標志
if(username.equals("123")&&password.equals("123"))
request.getSession().setAttribute("user", "usernmae");
response.sendRedirect("index.jsp");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
登錄成功后,服務器會為這個session對象做一個標記(比如在這里給這個session設置了一個屬性,登錄成功就設置)
我們試着不登錄直接訪問index.jsp,發現會跳轉到login.html。
<%@ 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">
<%
Object user=session.getAttribute("user");
if(user==null)
response.sendRedirect("login.html");
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>index.jsp</title>
</head>
<body>
登錄進來了
</body>
</html>
分析一下這個過程:

從圖上發現發送登錄請求的時候,同時發送了cookie,服務器根據這個sessionid找到對應的session(無論你有沒有登錄成功,服務器都會對應創建一個session對象),然后查找有沒有這個session對象是否正確登錄了(比如正確登錄后會在這個session對象設置“user"屬性,那么我們就知道來的這個人是大胖了),如果沒有就跳回登錄頁。
也就是說,這個發送證明的過程不用我們來做,瀏覽器幫我們做好了,但是瀏覽器要存儲這個證明(cookie)。
