12、Cookie & Session

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。都不能直接使用中文。

  1. 使用 URLEncoder 對中文進行url編碼。URLEncoder.encode("中文", "UTF-8")
  2. 在獲取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 /> ![](/cookie_session/Iservlet)
        <!-- 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

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容