springbootDay03 cookie和session 購物車技術


一、會話技術

1. 什么是會話

在計算機術語中,會話指的是客戶端和服務器交互通訊的過程。簡單的理解,大家可以看成是兩個普通的人在打電話。一次電話從通話開始到掛斷,可以看成是會話。

  • 會話的特征
    • 會話能夠把同一用戶發出的不同請求之間關聯起來。不同用戶的會話應當是相互獨立的
    • 會話一旦建立就一直存在,直到用戶空閑時間超過了某一個時間界限,會話才會中斷。 好比大家打電話,超過了某一定時間就會自動斷開。

2. 什么是會話技術

HTTP是一種無狀態協議,每當用戶發出請求時,服務器就會做出響應,客戶端與服務器之間的聯系是離散的、非連續的。當用戶在同一網站的多個頁面之間轉換時,根本無法確定是否是同一個客戶。

舉例如下:

  1. 我們在電商網站上選購商品,即便沒有登錄,假如購物車。下一次我們再打開網站,還是能夠看到上一次添加到購物車的商品
  2. 我們在一些網站登錄了之后,過了幾天我們在打開這個網站,還能認識我們,還能在右上角顯示 歡迎您 xxx
  3. 當我們再次登錄一些論壇時,總會顯示上一次我們訪問論壇的時間。

3. 會話技術的分類

會話技術主要常用的有兩種, 一種是Cookie , 另一種是 Session .

1. 什么是cookie

Cookie 可以翻譯為“小甜品,小餅干” ,  Cookie 實際上是指小量信息,是由 Web 服務器創建的,將信息存儲在用戶計算機上的文件。當用戶通過瀏覽器訪問服務器的時候,瀏覽器會自動攜帶早前存儲的cookie ,傳遞給服務器。

2. Cookie的應用場景

所有服務器想要讓客戶端幫忙存儲一些數據,以便下次訪問能夠識別客戶的情形,都可以使用cookie,如:

  1. 商品瀏覽記錄

  2. 購物車信息

  3. 記住賬號密碼

    ...

3. Cookie的基本使用

大家要記住一個核心,cookie是服務器生成,然后寄存在客戶端的一小份數據。 那么服務器如何把這一小份數據給客戶端呢? 只能依靠前面講過的response對象了。

Cookie cookie = new Cookie("key" ,"value");
response.addCookie(cookie);

4. Cookie的分類

cookie有分臨時性(也稱之為會話級別cookie),也有持久性。

  • 臨時性Cookie

默認情況下,關閉瀏覽器后,cookie就銷毀掉了。

  • 持久性Cookie

可以設置保存時長

5. 獲取上次訪問時間

img01

  • 頁面准備
 <form action="user_login" method="post">
        用戶名:<input type="text" name="username"/></br>
        密  碼:<input type="password" name="password"/></br>
        <input type="submit" value="登錄"/>
    </form>
  • controller
@RestController
public class UserController {
    private static final String TAG = "UserController";

    @RequestMapping("user_login")
    public String login(HttpServletRequest request , HttpServletResponse response ,  String username , String password){

        System.out.println(username + " : " + password);
        HttpSession session = request.getSession();
      //  session.setAttribute("name","zhangsan");

        String id = session.getId();
        System.out.println("id=" + id);

        //1. 判斷賬號密碼
        if("admin".equals(username) &&  "123".equals(password)){

            String result = "歡迎您 , "+ username;

            //2.要獲取cookies
            Cookie[] cookies = request.getCookies();

            //有cookie
            if(cookies != null){

                //就想看cookie里面有沒有帶上次的時間
                for(Cookie cookie : cookies){
                    //如果能成立,就表示找到了上一次訪問的時間。
                    if("last".equals(cookie.getName())){

                        long time = Long.parseLong(cookie.getValue());

                        Date date = new Date();
                        date.setTime(time);

                        result += "\r\n 上一次訪問時間是:"+date.toLocaleString();
                    }
                }
            }
            //只要有登錄成功,就必須返回最新的登錄時間。
            String time = System.currentTimeMillis()+"";
            Cookie cookie = new Cookie("last" , time);
            cookie.setMaxAge(60*60*24*7);
            response.addCookie(cookie);

            return result;
        }
        
        return "登錄失敗";
    }
}

6. Cookie的問題

  1. cookie 大小有限制,每個服務器在最多不能超過20個。
  2. cookie 是存放在客戶端上,信息不安全,有被截獲的可能

三、 Session

1. 什么是session

Session是基於Cookie的一種會話機制。 Session服務器上的一段內存空間 , 可以用來存儲數據。

Cookie是服務器返回一小份數據給客戶端,並且存放在客戶端上。 Session是,數據存放在服務器端。

cookie

數據存放在客戶端

數據不安全

減輕服務器壓力, 用戶磁盤占用比較多。 

存放的數據有限

session

數據存放在服務器端

數據相對比較安全。

服務器壓力大一點。

存放的數據 依賴服務器的內存空間。 

3. Session的簡單使用

  1. 獲取session

    HttpSession session = request.getSession()

  2. 存值

    session.setAttribute(name ,value);

  3. 取值:

    session.getAttribute(name);

  4. 移除值

    session.removeAttribute(name);

  5. 讓session失效 作廢

    session.invalidate();

  6. 獲取id值

    session的id值就是這一塊內存空間的唯一標識符。 session.getId() .

4. Session的背后細節

  • 第一次訪問

那么session都沒有創建,並且咱們的請求對象里面也不帶任何的cookie過來。 那么這個時候會在內存中給你創建一個新的session區域,並且把這個session的id值放到cookie里面給我們的瀏覽器返回。 注意這些事情都是服務器端自己做的。所以cookie是一個臨時性的cookie。 關閉瀏覽器就銷毀cookie了

  • 第二次訪問

如果是第二次訪問,那么瀏覽器會把之前的那個cookie給帶過來, 服務器收到了cookie,里面有我們上一次給的sessionid 值, 那么這個時候再調用request.getSesion() , 它先會拿我們待過來的id ,到內存里面去找有沒有session的 id值跟這個cookie帶過來的一樣 ,如果有,就直接返回這個內存空間, 否則就創建新的session空間

img03

5. session 銷毀的細節!

img04

  1. 關閉瀏覽器並不能讓session銷毀。 因為session是服務器的一塊內存空間, 它的銷毀不依賴客戶端的瀏覽器關閉還是不關閉。
  2. 再次訪問的時候,我們的瀏覽器已經沒有了那個sessionid值,所以就找不到了以前的那一塊空間。所以打開瀏覽器重新訪問,會拿到的是全新的session空間。 但是原來的那個session還存在,只不過我們無法操作它而已。
  3. 如果真的項操作以前的session,我們要手動往cookie里面存session id 值,並且設置成持久性cookie

注意: cookie的那個name不能亂寫。 JSESSIONID

  • 銷毀session
  1. invaidate()
  2. 自動失效。 有效期。 默認30分鍾

6. Session的作用范圍 & 生命周期

  • 作用范圍

    sesison 作用范圍: 一次會話范圍內有效。

  • 生命周期

    何時創建

    第一次調用request.getSession()就創建。 
    

    何時銷毀

    關閉服務器 
    
    session超時了。默認30分鍾。 從最后一次請求開始計時。
    
    調用invalidate . 讓空間失效、作廢
    

7. 購物車案例

日常生活中,大家都是有過購物的經驗,喜歡什么商品,先把它添加到購物車中,后續再付款。 那么購物車是如何實現的呢? 其實購物車可以使用cookie來實現,也可以使用session來實現。真正的企業的購物車要實現起來還得配合緩存數據庫來實現。咱們接下來使用session來實現一個簡易的購物車即可

img02

  • 准備工作

需要在項目的build.gradle 中添加 thymeleaf依賴

compile("org.thymeleaf:thymeleaf-spring4:2.1.4.RELEASE")
  • 在模板頁面上,要記得引入命名空間
 <html xmlns:th="http://www.thymeleaf.org" >

1. 顯示商品列表

  • index.html
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2><a href="list">開始購物</a></h2>
</body>
</html>
  • 商品實體類
public class Product {
   

    private int id; // 商品的編號
    private String name; //商品名字
    private double price ; //商品價格
    
    get & set 方法
    ...
}
  • 商品controller
@Controller
public class ProductController {
    private static final String TAG = "ProductController";

    //准備商品數據
    private static List<Product> list;
    static{
        list = new ArrayList<Product>();

        list.add(new Product(1,"iphone6s" ,3788));
        list.add(new Product(2,"小米8" ,2788));
        list.add(new Product(3,"vivo20" ,4788));
        list.add(new Product(4,"meizu6" ,3690));
        list.add(new Product(5,"諾基亞200" ,188));
    }


    @RequestMapping("list")
    public ModelAndView list(){

        //1. 構建商品集合
        
        //2. 存儲數據到model
        ModelAndView modelAndView  =new ModelAndView();

        //設置模型數據
        modelAndView.addObject("list" , list);

        //設置跳轉的目標是哪里。 list.html
        modelAndView.setViewName("list");

        return modelAndView;
    }
}
  • 商品列表 list.html 位於 /resources/templates/下
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" >
<head>
    <meta charset="UTF-8"/>
    <title>商品列表頁面</title>
</head>
<body>

    <h2>商品列表</h2><br/>

    <table>

        <thead>
            <td width="100px">編號</td>
            <td width="100px">名稱</td>
            <td width="100px">價格</td>
            <td width="100px">操作</td>
        </thead>

        <!--從這里開始就是真正的商品數據顯示了
            p 遍歷 list集合的出來的每一個元素對象, 其實好就是商品對象。
            aa: 表示遍歷的狀態信息
                ${aa.index} :遍歷的索引
        -->
        <tr th:each="p,status:${list}">
            <td th:text="${p.id}">100</td>
            <td th:text="${p.name}">蘋果筆記本</td>
            <td th:text="${p.price}">9999</td>
            <!--<td ><a href="addToCart?index=1">加入購物車</a></td>-->
            <td ><a th:href="@{addToCart(index=${status.index})}">加入購物車</a></td>
        </tr>
    </table>


</body>
</html>

2. 加入購物車

點擊加入購物車需要跳轉到controller , 根據提供的索引下標,獲取到對應的商品,添加到購物車 Map

  • 添加購物車方法
 //添加商品到購物車, 現在拿到的是商品的索引
    @RequestMapping("addToCart")
    public String addToCart(HttpServletRequest request , int index){

        System.out.println("要添加商品到購物車了~");

        HttpSession session = request.getSession();

        //1. 根據索引,獲取到要添加到購物車的商品
        Product product  = list.get(index);

        //2. 加入購物車 購物車其實就是商品和數量的對應關系。
        Map<Product , Integer> map = (Map<Product , Integer>)session.getAttribute("cartMap");
        //第一次來,連購物車都沒有
        if(map == null){
            map = new HashMap<Product , Integer>();
        }

        //判斷購物車里面是否有該商品 ,如果有  數量 + 1  ,如果沒有,數量-1
        if(map.containsKey(product)){
            map.put(product , map.get(product) +1 );
        }else{
            map.put(product , 1 );
        }

        //3. 存儲到session中。
        request.getSession().setAttribute("cartMap" , map);

        //當前的跳轉是基於template/list.html ,所以需要重定向跳轉到中轉頁面
        return "redirect:transfer.html";
    }
  • 中轉頁面

該頁面只是一個簡單的靜態頁面,所以位於 resource/static下

<body>

    <a href="list"><h2>繼續購物</h2></a><br>
    <a href="toCart"><h2>去購物車查看</h2></a><br>

</body>

3. 顯示購物車

通過點擊去購物車查看, 即可跳轉到購物車頁面,顯示商品。

  • cart.html

該頁面是用於顯示動態數據,所以需要放到模板 templates下。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" >
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>

    <h2>購物車列表</h2>

    <table>
       <thead>
            <td  width="100px">商品名稱</td>
            <td  width="100px">商品價格</td>
            <td  width="100px">購買數量</td>
            <td  width="100px">小計</td>
       </thead>

        <!--把session里面的購物車拿出來遍歷顯示。 購物車是一個map集合
            map集合的遍歷出來,其實就是一個key 和 一個value 的組合 。
            這種組合entry
            m就是entry
            map<Product , Integer>
        -->
        <tbody>
            <tr th:each="m:${session.cartMap}">
                <td th:text="${m.key.name}">聯想鼠標墊</td>
                <td th:text="${m.key.price}">10.0</td>
                <td th:text="${m.value}">1</td>
                <td th:text="${m.key.price * m.value}">1</td>
            </tr>

        </tbody>


    </table>

</body>
</html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM