Cookie & Session
會話的概念
日常生活來講,會話就是兩個人聊天.。聊天的前提,聊天雙方需要有記憶力.。在聊的過程中,都是基于之前聊的狀態(tài),繼續(xù)往下聊。
我們JavaWeb中,瀏覽器和服務器也可以看作是雙方在聊天(請求,響應).。瀏覽器服務器雙方也需要有"記憶力",保存之前的聊天狀態(tài)。服務器和瀏覽器才可以完成會話。
會話的范圍
兩個從打招呼到兩人互相道別。是一次會話。
打開網(wǎng)站,完成我們想做的需求,到關閉瀏覽器,是一次會話。
- Cookie: 讓瀏覽器能夠記錄信息。
- Session: 讓服務器端能夠記錄信息。
Cookie原理
第一次訪問服務器時候,服務器響應時候,要求瀏覽器記住一個信息。response.addCookie(cookie);
以后每次訪問服務器時候,攜帶第一次記住的信息訪問。

下面是個簡單的例子,Aservlet訪問服務器,讓瀏覽器記住Cookie,再讓Bservlet訪問服務器,這時候可以從瀏覽器將Cookie取出來。
Aservlet
package cookie;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Aservlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 瀏覽器的Response Headers里面可以看到這么一行。Set-Cookie:username=Tom
// 所以可以用如下寫法
// response.addHeader("set-Cookie", "username=Tom");
// 當然更簡單的方式是以下
Cookie cookie = new Cookie("username", "Tom");
response.addCookie(cookie);
}
}
Bservlet
package cookie;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Bservlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 獲得瀏覽器發(fā)來的全部cookie
Cookie[] cookies = request.getCookies();
Cookie nameCookie = null;
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("username".equals(cookie.getName())) {
nameCookie = cookie;
}
}
}
if (nameCookie != null) {
System.out.println(nameCookie.getName() + " : " + nameCookie.getValue());
} else {
System.out.println("未找到cookie");
}
}
}
Cookie細節(jié)
Cookie在瀏覽器存留時間
默認情況是關閉瀏覽器就會刪除Cookie。如下圖過期時間所示。

在發(fā)送cookie之前手動設置:
cookie.setMaxAge(60*60*24*7*2); //告訴瀏覽器保存2周
cookie.setMaxAge(-1); // -1代表 在會話結束時刪除cookie(默認情況)
cookie.setMaxAge(0); // 通常用于刪除已經(jīng)存在的cookie.使用一個壽命為0的cookie,覆蓋要刪除的cookie
瀏覽器在什么情況下發(fā)送cookie(cookie的路徑問題)
如果 cookie路徑是"/cookie_session", 主機(域)是:localhost . 那么瀏覽器在訪問cookie路徑的所有子路徑時會攜帶cookie。
http://localhost:8080/cookie_session/BServlet 會發(fā)送
http://localhost:8080/cookie_session/ABC/BCD/CServlet 會發(fā)送
http://localhost:8080/else/AServlet 不會發(fā)送(項目名)
http://www.baidu.com/cookie_session/BServlet 不會發(fā)送(主機)
Cookie路徑的設置
cookie的默認路徑就是 發(fā)送cookie的動態(tài)資源所在的上一級路徑。比如這里/cookie_session/AServlet,是Aservlet發(fā)送的,那么默認就是上一級/cookie_session。
手動設置:cookie.setPath("/cookie_session/abc");

cookie的主機設置
cookie的主機(域)設置 (了解即可)
默認情況: 發(fā)送Cookie的資源所在主機。
手動設置:
//自己當前是什么主機,你就只能設置為什么主機,或者主機名的一部分
// 假設自己的主機是www.baidu.com那么可以如下設置:
c.setDomain(".baidu.com");
Cookie的刪除
刪除cookie原理就是 使用一個壽命為0的cookie 覆蓋需要刪除的cookie。c.setMaxAge(0);
覆蓋cookie要求?
需要路徑、鍵、主機 一致,即可覆蓋。
使用cookie記錄中文鍵值對問題
為什么不能直接使用中文?
因為http協(xié)議中,除正文部分都不得使用Latin碼表以外的其他碼表。所以不管是cookie還是之前的Cotent-disposition。都不能直接使用中文。
- 使用 URLEncoder 對中文進行url編碼。
URLEncoder.encode("中文", "UTF-8") - 在獲取cookie時,使用URLDecoder進行解碼。
URLDecoder.decode("中文", "UTF-8")。
使用cookie 記錄瀏覽歷史
先做一個工具類,按填入的參數(shù)獲取指定Cookie。
package cookie;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
public class CookieUtils {
public static Cookie getCooieByName(HttpServletRequest req, String key) {
Cookie cookie = null;
Cookie[] cookies = req.getCookies();
if (cookies != null) {
for (Cookie c : cookies) {
if (key.equals(c.getName())) {
cookie = c;
}
}
}
return cookie;
}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'list.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<a href="/cookie_session/Cservlet?name=dell">dell</a> <br />
<a href="/cookie_session/Cservlet?name=lenovo">lenovo</a> <br />
<a href="/cookie_session/Cservlet?name=hp">hp</a> <br />
<a href="/cookie_session/Cservlet?name=acer">acer</a> <br />
<a href="/cookie_session/Cservlet?name=apple">apple</a> <br />
瀏覽歷史:${cookie.history.value }
</body>
</html>
package cookie;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Cservlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 使用cookie 記錄瀏覽歷史.
// 1.獲得參數(shù),地址欄的name=lenovo等
String name = request.getParameter("name");
// 2.獲得Cookie
Cookie history = CookieUtils.getCooieByName(request, "history");
//存在 => 修改cookie加上現(xiàn)在瀏覽器的品牌
if (history != null) {
// 重復點擊不會繼續(xù)增加
if (!history.getValue().contains(name)) {
// 需要注意的是,高版本的Tomcatcookie里不支持“,”逗號。換成其他符號
history = new Cookie("history", history.getValue()+"-"+name);
}
} else {
//不存在 => 創(chuàng)建cookie
history = new Cookie("history", name);
}
// 3.將cookie發(fā)送會瀏覽器
response.addCookie(history);
// 4.重定向到列表頁面
response.sendRedirect("/cookie_session/history/list.jsp");
// /cookie_session/WebRoot/history/list.jsp
}
}
效果是每點擊一次,瀏覽歷史里面就新增一個,重復點擊不會繼續(xù)增加。

記住用戶名和密碼
流程如下。

登錄界面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'login.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form action="/cookie_session/Dservlet" >
用戶名:<input type="text" name="name" value="${cookie.remember.value}" />
<font color="red">${requestScope.error}</font>
<br>
密碼:<input type="text" name="password" /><br>
<input type="checkbox" name="remember" value="yes" ${cookie.remember==null?"":"checked=checked"} />記住用戶名<br>
<input type="submit" value="登錄" />
</form>
</body>
</html>
Dservlet
package cookie;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Dservlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1.獲得用戶名密碼
String name = request.getParameter("username");
// 2.校驗用戶名密碼
if (name == null || "".equals(name.trim())) {
// //失敗=> 轉發(fā)到表單頁面,并提示錯誤
request.setAttribute("error", "請輸入用戶名!"); request.getRequestDispatcher("/remember/login.jsp").forward(request, response);
// 轉發(fā)后不再繼續(xù)處理邏輯
return;
}
// 3.創(chuàng)建cookie 添加要保存的用戶名,
Cookie c = new Cookie("remember", name);
// 4.查看記住用戶名是否被選中
String remember = request.getParameter("remember");
//選中 => 設置保存時間為2周
if ("yes".equals(remember)) {
c.setMaxAge(60*60*24*7*2);
} else {
//沒選中=>設置保存事件為0
c.setMaxAge(0); // 清除cookie
}
// 5.添加到響應中
response.addCookie(c);
// 6.重定向到成功頁面
response.sendRedirect("/cookie_session/index.jsp");
}
}
Session原理
獲取session時候,request.getSession();若瀏覽器第一次訪問,服務器會響應一個cookie給瀏覽器。這個cookie記錄的就是sessionId,tomcat生成的sessionid叫做jsessionid。以后每次訪問攜帶著這個sessionId,在服務器里找這個sessionId。找到后就可以獲取這個sessionId里面的數(shù)據(jù)。
package session;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class Gservlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//參數(shù)類型是boolean型
//true=> 無論如何都要獲得session
//false => 如果沒有sessionID ,不會獲得session
//request.getSession(true);
HttpSession session = request.getSession();//相當于上面的方法 填寫true
// 上面的方法執(zhí)行后,第一次訪問服務器時候,服務器會響應一個cookie給瀏覽器。這個cookie記錄的就是sessionId,tomcat生成的sessionid叫做jsessionid。
// 比如Set-Cookie:JSESSIONID=44D210CF971936BF86AACD72DED04A82; Path=/cookie_session
// 再次訪問這個網(wǎng)址,攜帶這個cookie。如Cookie:JSESSIONID=44D210CF971936BF86AACD72DED04A82
}
}
session的操作
getAttribute();
setAttribute();
removeAttribute();
getAttributeNames();
session的細節(jié)
session能在服務器端保存多久?
<session-config>
<session-timeout>30</session-timeout>
</session-config>
在tomcat/conf/web.xml 有如上配置。該配置決定了session對象的有效存活時間為30分鐘。
在我們項目的web.xml中, 也可以加上如上配置.區(qū)別就是影響的范圍不同。在項目中配只影響當前項目.
3.(了解)。在session對象中,還有如下方法. 該方法也是控制session對象 的有效存活時間的,單位是秒。范圍是只影響調(diào)用該方法的某個session.
void setMaxInactiveInterval(int interval)
session的范圍問題
瀏覽器第一次訪問服務器,服務器創(chuàng)建session對象,會話開始。
三種方式銷毀session
- 瀏覽器關閉,保存sessionID的cookie丟失。(Cookie默認在瀏覽器關閉時候過期) 會話結束。(session還在服務器中,等死)
- session到了過期時間(默認30分鐘無操作)
- 手動銷毀session
session中的其他方法
package session;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class Hservlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
System.out.println("session.isNew()"+session.isNew());// 判斷session是否 是新的.
System.out.println("session.getCreationTime()"+new Date(session.getCreationTime()));//獲得session的創(chuàng)建時間
System.out.println("session.getId()"+session.getId());//獲得session的id
System.out.println("session.getLastAccessedTime()"+new Date(session.getLastAccessedTime()));//獲得最后一次的訪問時間
System.out.println("session.getMaxInactiveInterval()"+session.getMaxInactiveInterval());// 獲得session的最大有效時間
session.setMaxInactiveInterval(60);//設置session的最大有效時間為60秒
session.invalidate();//需要記住: 立即讓session銷毀。
// 所以每次訪問都會創(chuàng)建新的session,isNew打印true,ID也是新的,創(chuàng)建時間和上次訪問時間也是最新的
}
驗證碼例子

為什么要用session域來存放驗證碼的正確code?
- 如果用request域,則開始會向專門生成驗證碼圖片的Aservlet發(fā)送請求,正確的code在這個request域中,當我們點擊登錄,又是一個新的請求,這個新的request里面根本就沒有正確code,也不存在和用戶自己輸入的code進行比較一說。
- 如果用的application域:Application 的作用范圍在服務器一開始執(zhí)行服務,到服務器關閉為止Application 的范圍最、停留的時間也最久。一個web項目只有一個,考慮到線程不安全,所以多個用戶共享同一個域,后面的會把前面的覆蓋。
session在會話期間會一直保持著正確的code,所以session域是最合適的。
登錄界面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'login.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<script type="text/javascript">
function fun1() {
// 獲得img標簽對象
var img = document.getElementById("one");
// 改變src屬性,由于Iservlet沒有參數(shù),所以這里隨意填,用Date的目的是保證每次訪問的唯一性
img.src = "/cookie_session/Iservlet?date="+new Date();
}
</script>
<form action="/cookie_session/Jservlet" >
用戶名:<input type="text" name="name" value="${cookie.remember.value}" /> <br>
密碼:<input type="text" name="password" /><br>
驗證碼:<input type="text" name="code" size=4 /> 
<!-- javascript:void(0)什么也不做,讓fun1完成 -->
<a href="javascript:void(0)" onclick="fun1();">看不清,換一張</a>
<font color="red">${requestScope.error}</font>
<br />
<input type="checkbox" name="remember" value="yes" ${cookie.remember==null?"":"checked=checked"} />記住用戶名<br>
<input type="submit" value="登錄" />
</form>
</body>
</html>
專門用于生成驗證碼的Iservlet,注意cn.dsna.util.images.ValidateCode用的是第三方包。
package session;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.dsna.util.images.ValidateCode;
public class Iservlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 要項瀏覽器正文輸入時,必須指定類型
// response.setContentType("image/jpeg");
// 1. 生成驗證碼
ValidateCode code = new ValidateCode(120, 40, 4, 2);
// 2. 將正確答案放進Session
String correctCode = code.getCode();
request.getSession().setAttribute("code", correctCode);
// 3. 將圖片發(fā)送給瀏覽器
System.out.println(correctCode);
code.write(response.getOutputStream());
}
}
點擊登錄跳轉到Jservlet,取出用戶輸入的code和session域存放的正確code比較。
package session;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Jservlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1. 獲得用戶填寫的驗證碼
String userCode = request.getParameter("code");
// 2. 獲得session中的正確驗證碼
String correctCode = (String) request.getSession().getAttribute("code");
// 3. 比較兩者
if (userCode != null && userCode.equalsIgnoreCase(correctCode)) {
// 驗證成功,重定向到登錄成功的頁面
response.sendRedirect("/cookie_session/index.jsp");
} else {
request.setAttribute("error", "請輸入正確的驗證碼!");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
}

如上圖,驗證碼填錯了會轉發(fā)到登錄界面。
注意是轉發(fā)過去是一次請求,轉發(fā)過去還是剛才的jsp頁面。${requestScope.error}才能收到request.setAttribute("error", "請輸入正確的驗證碼!");的錯誤信息;如果是重定向又重新請求了,重新加載jsp,不會顯示錯誤信息。
購物車例子
商城商品頁面。list.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<h1>商品列表</h1>
<table border="1" >
<tr>
<td>
肥皂<br>
<a href="/cookie_session/Kservlet?name=0" >點擊加入購物車</a>
</td>
<td>
蠟燭<br>
<a href="/cookie_session/Kservlet?name=1" >點擊加入購物車</a>
</td>
</tr>
<tr>
<td>
被罩<br>
<a href="/cookie_session/Kservlet?name=2" >點擊加入購物車</a>
</td>
<td>
枕頭<br>
<a href="/cookie_session/Kservlet?name=3" >點擊加入購物車</a>
</td>
</tr>
</table>
<a href="/cookie_session/cart.jsp" >查看購物車</a>
</body>
</html>
購物車詳情,cart.jsp
<%@page import="java.util.Map.Entry"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'cart.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<h1>購物車</h1>
<table border="1">
<tr>
<th>商品名稱</th>
<th>商品數(shù)量</th>
</tr>
<%
Map<String,Integer> cart = (Map<String,Integer>)session.getAttribute("cart");
if(cart!=null && cart.size()>0){
for(Entry<String,Integer> en : cart.entrySet()){
%>
<tr>
<td><%=en.getKey() %></td>
<td><%=en.getValue() %></td>
</tr>
<% }
}
%>
</table>
</body>
</html>
Kservlet
package session;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Kservlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//0 準備數(shù)組,與頁面商品對應
String[] products = {"肥皂","蠟燭","被罩","枕頭"};
// 1. 獲得當前請求要添加的商品
String indexStr = request.getParameter("name");// 0 ~ 3
String productName = products[Integer.parseInt(indexStr)];
// 2.從Session中取出存放購物車的map
Map<String,Integer> cart = (Map<String, Integer>) request.getSession().getAttribute("cart");
if(cart==null){
// //取不到=>初始化map,LinkedHashMap保證存入和取出的順序相同,因為HashMap是無序的
cart = new LinkedHashMap<String, Integer>();
//并放入session
request.getSession().setAttribute("cart", cart);
}
// 3.使用當前要添加的商品從map中取值,默認數(shù)量為1
Integer count = cart.put(productName, 1);
// 不為空說明值被覆蓋,加一。為空說明上面設置為1是正確的
if(count!=null){
cart.put(productName, count+1);
}
//取不到=> 放入map,設置數(shù)量為1
//取得到=> 將數(shù)量+1放回去
// 4.重定向回商品列表頁面
response.sendRedirect("/cookie_session/list.jsp");
}
}


注意:后退或者刷新,再次選擇物品、購物車依然會累計。但是當瀏覽器關閉后,再次訪問購物車就清零了。因為cookie被銷毀,sessionId已經(jīng)沒有了,再去服務器找的時候是沒有攜帶的,需要新建。
Cookie和Session的區(qū)別
- session 在服務器端,cookie 在客戶端(瀏覽器)
- session 默認被存在在服務器的一個文件里(不是內(nèi)存)
- session 的運行依賴 sessionId,而 sessionId 是存在 cookie 中的,也就是說,如果瀏覽器禁用了 cookie ,同時 session 也會失效(但是可以通過其它方式實現(xiàn),比如在 url 中傳遞 sessionId)
- session 可以放在 文件、數(shù)據(jù)庫、或內(nèi)存中都可以。
- 用戶驗證這種場合一般會用 session
因此,維持一個會話的核心就是客戶端的唯一標識,即 sessionId。
by @sunhaiyu
2017.3.31