25. 会话技术-Cookie的使用

2021-11-12 09:32:41 浏览数 (1)

25. 会话技术-Cookie的使用

一 、会话概述

1.1 什么是会话?

日常生活中:从拨通电话到挂断电话之间的一连串你问我答的过程就是一个会话。

B/S架构中:从浏览器第一次给服务器发送请求时,建立会话;直到有一方断开,会话结束。

代码语言:javascript复制
一次会话:包含多次请求响应。

1587172413825

1.2 会话技术

**问题:**Http是一个无状态协议,同一个会话的连续两个请求相互独立,彼此并不了解

作用:用于 存储 浏览器与服务器在请求和响应过程中产生的 数据

在一次会话中(多次请求响应), 共享数据

客户端会话技术:cookie

服务器端会话技术:session

1587172824573

二、 Cookie

2.1 概述

Cookie作用:在一次会话的多次请求之间共享数据,将数据保存到客户端(浏览器)

代码语言:javascript复制
#Cookie的特点
1. cookie保存在客户端(浏览器), 往往是由服务器产生发送给浏览器
2. cookie只能保存字符串, 格式是 entry(name : value)
3. cookie的大小有限制: 4k
4. 一般, 同一域名下的cookie限制数量50个

2.2 快速入门

下面我们首先可以以游客的身份访问京东页面,添加商品到购物车上,但是我们并没有登录京东的账号。当我们关闭京东的页面,再次访问的时候,却发现购物车还有我们之前加入购物车的商品。这是为什么呢?

这就是因为 Cookie 的作用了:京东的页面将游客加入购物车的商品信息保存到浏览器下,当使用同一个浏览器在一次会话中再次访问页面,那么商品信息就会自动随着cookie信息请求到 京东服务端,然后由京东服务将你之前选择的商品加入到购物车之中。

1591235563712

1591235580561

下面是谷歌浏览器请求访问京东服务器的示意流程图:

1591235608007

执行伪代码如下:

代码语言:javascript复制
1. 设置数据到cookie中
 // 1.创建cookie对象,设置数据
  Cookie cookie = new Cookie(String name,String value);
 // 2.通过response,响应(返回)cookie
  response.addCookie(cookie);

2. 从cookie中获取数据
 // 1.通过request对象,接收cookie数组
  Cookie[] cookies = request.getCookies();
 // 2.遍历数组
  获取name值:  String name = cookie.getName();
  获取value值:  String value = cookie.getValue();

2.2.1 代码实现:

首先我们需要创建页面 index.html, 模拟添加商品到购物车 和 第二次查看购物车的 操作。

  • 添加商品到购物车:目的在于将添加的商品信息发送给服务器,由服务器返回给浏览器,将商品信息 设置 Cookie 信息 保存在浏览器。
  • 第二次查看购物车:目的在于浏览器请求服务器的时候,会将同一个域名路径下的 Cookie 发送到服务器,然后由服务器将商品信息返回给浏览器显示。
index.html

image-20210216223410324

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
</head>
<body>

    <a href="Cookie01Servlet?product=xiaomi">第一次_添加小米到购物车</a> <br>
    <a href="Cookie02Servlet">第二次_查看购物车</a>  <br>

</body>
</html>

编写好 index.html 页面后,我们启动 tomcat 访问一下页面,如下:

image-20210216223444430

好了,下面我们就要实现 Cookie01Servlet 和 Cookie02Servlet 两个 Servlet 程序,来实现 Cookie 的业务操作。

Cookie01Servlet

创建 Cookie01Servlet 用来处理 添加商品到购物车:目的在于将添加的商品信息发送给服务器,由服务器返回给浏览器,将商品信息 设置 Cookie 信息 保存在浏览器。

image-20210217095805904

代码语言:javascript复制
package com.lijw;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Aron.li
 * @date 2021/2/17 9:49
 */
@javax.servlet.annotation.WebServlet("/Cookie01Servlet")
public class Cookie01Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //1. 接收商品参数的信息
        String product = request.getParameter("product");

        //2. 创建Cookie对象
        Cookie cookie = new Cookie("product", product);

        //3. 返回浏览器添加Cookie
        response.addCookie(cookie);

        //4. 页面重定向回 index.html
        response.sendRedirect("index.html");
    }
}
Cookie02Servlet

创建 Cookie02Servlet 用来处理 第二次查看购物车:目的在于浏览器请求服务器的时候,会将同一个域名路径下的 Cookie 发送到服务器,然后由服务器将商品信息返回给浏览器显示。

image-20210217101143665

代码语言:javascript复制
package com.lijw;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Aron.li
 * @date 2021/2/17 9:59
 */
@WebServlet("/Cookie02Servlet")
public class Cookie02Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置返回的内容为 html
        response.setContentType("text/html;charset=utf-8");

        // 1.获取请求中携带过来的所有 Cookie
        Cookie[] cookies = request.getCookies();
        // 2.遍历Cookies信息,显示到浏览器上
        for (Cookie cookie : cookies) {
            String name = cookie.getName();
            String value = cookie.getValue();
            response.getWriter().write("name: "   name   ", value: "   value   "<br/>");
        }

        // 3. 返回 index.html 页面
        response.getWriter().write("<a href='index.html'>返回index</a>");
    }
}
测试第一次将商品加入购物车

启动 tomcat 服务,然后点击第一次_添加小米到购物车:

image-20210217101441237

image-20210217101509747

可以看到请求到了 Cookie01Servlet ,并且重定向回来了,下面看看添加好的 Cookie 信息,如下:

image-20210217101630401

测试 第二次查看购物车

image-20210217101704689

image-20210217101722464

可以看到成功显示出了所有 cookie 信息。

从上面的两个Servlet中,我们理解了如何添加 Cookie 以及 如何查询 Cookie 信息,下面我们来看看在浏览器如何查看 Cookie

google浏览器中查看Cookie的方式一

image-20210217101905786

image-20210217101932923

google浏览器中查看Cookie的方式二

image-20210217101957329

2.3 工作原理

基于HTTP协议:

1. 服务器发送Cookie给浏览器是通过 : 响应(响应头 set-cookie)

Set-Cookie: phone=xiaomi

Set-Cookie: computer=lenovo

2. 浏览器发送Cookie给服务器是通过: 请求(请求头 cookie)

Cookie: phone=xiaomi; computer=lenovo

1587174808482

2.4 Cookie详情

2.4.1 服务器发送多个Cookie?

代码语言:javascript复制
* 答案: 可以的
 // 1. 创建多个cookie对象
  Cookie cookie1 = new Cookie("name","lucy");
  Cookie cookie2 = new Cookie("age","18");
 // 2. 通过response响应多个
  response.addCookie(cookie1);
  response.addCookie(cookie2);

下面我们写一个简单的示例来看看:

修改之前的 index.html 增加请求 Cookie03Servlet (设置多个Cookie)

image-20210217102853105

Cookie03Servlet :创建多个Cookie

image-20210217105855160

代码语言:javascript复制
package com.lijw;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Aron.li
 * @date 2021/2/17 10:46
 */
@WebServlet("/Cookie03Servlet")
public class Cookie03Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 创建多个Cookie,返回浏览器
        Cookie cookie1 = new Cookie("cookie1", "cookie1value");
        Cookie cookie2 = new Cookie("cookie2", "cookie2value");

        response.addCookie(cookie1);
        response.addCookie(cookie2);

        //2. 重定向回 index.html
        response.sendRedirect("index.html");
    }
}
测试设置多个 Cookie

image-20210217105957270

2.4.2 Cookie是否可以存储中文和非法字符?

代码语言:javascript复制
* tomcat8之前的版本,不支持中文
* tomcat8以后的版本,支持中文...
 但是按照 Rfc6265Cookie规范,在cookie值中不能使用分号(;)、逗号(,)、等号(=)以及空格

我们可以存储,但是要使用url编码,来避开这个规范限制

* 解决
  java.net.URLEncoder.encode(字符串","utf-8") 把字符串使用utf-8进行编码
  java.net.URLDecoder.decode(字符串","utf-8")  把字符串使用utf-8进行解码

下面我们再写一个服务端设置 中文 和 非法字符 的 Cookie。

修改 index.html 请求 Cookie04Servlet(用来设置中文和非法字符)

image-20210217110247192

Cookie04Servlet:先直接存储中文 和 非法字符

image-20210217110549982

代码语言:javascript复制
package com.lijw;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Aron.li
 * @date 2021/2/17 11:03
 */
@WebServlet("/Cookie04Servlet")
public class Cookie04Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 创建存储中文和非法字符的cookie内容(按照 Rfc6265Cookie规范,在cookie值中不能使用分号(;)、逗号(,)、等号(=)以及空格)
        Cookie cookie = new Cookie("cookie04", "中文内容 空格 逗号内容");
        //2. 返回浏览器,以及重定向
        response.addCookie(cookie);
        response.sendRedirect("index.html");
    }
}
测试请求非法内容

image-20210217110618332

image-20210217110639728

Cookie04Servlet:使用 URLEncoder 存储中文 和 非法字符

在上面的测试中,我们已经发现 Cookie 无法直接存储 中文 和 非法字符,为了解决这个问题。我们需要将内容进行 URL 编码。

image-20210217110926586

代码语言:javascript复制
package com.lijw;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

/**
 * @author Aron.li
 * @date 2021/2/17 11:03
 */
@WebServlet("/Cookie04Servlet")
public class Cookie04Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 创建存储中文和非法字符的cookie内容(按照 Rfc6265Cookie规范,在cookie值中不能使用分号(;)、逗号(,)、等号(=)以及空格)
        String str = "中文内容 空格 逗号内容";
        String encode = URLEncoder.encode(str, "utf-8");  //使用URL编码解决Cookie无法存储非法字符的问题
        Cookie cookie = new Cookie("cookie04", encode);
        //2. 返回浏览器,以及重定向
        response.addCookie(cookie);
        response.sendRedirect("index.html");
    }
}
测试请求URL编码后的Cookie内容

image-20210217111032266

下面我们再写一个读取 URL 编码的 Cookie 内容。

修改 index.html 请求 Cookie05Servlet(用来读取 URL 编码的内容)

image-20210217112205049

Cookie05Servlet:使用URL解码读取Cookie的中文以及非法字符内容

image-20210217112247638

代码语言:javascript复制
package com.lijw;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;

/**
 * @author Aron.li
 * @date 2021/2/17 11:15
 */
@WebServlet("/Cookie05Servlet")
public class Cookie05Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8"); // 设置返回的内容为HTML

        //1. 读取全部Cookie的信息
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            String name = cookie.getName();
            String value = cookie.getValue();

            // 如果是cookie04,需要进行URL解码
            if ("cookie04".equalsIgnoreCase(name)) {
                // 对内容进行URL解码
                String decode = URLDecoder.decode(value, "utf-8");
                response.getWriter().write(name   "--"   decode   "<br/>");
            } else {
                // 打印其他Cookie内容
                response.getWriter().write(name   "--"   value   "<br/>");
            }

        }
    }
}
测试请求读取URL解码后的Cookie内容

image-20210217112335728

image-20210217112351152

2.4.3 Cookie的域名作用(domain)

image-20210217112542516

代码语言:javascript复制
1. cookie信息中的域名作用是标记这个cookie的归属
  在我们的浏览器中,既保存了域名为localhost的cookie,又保存域名为baidu的cookie
  那么访问的网站如果是 http://localhost:8080, 浏览器的请求只会携带域名为localhost的cookie
  
2. 默认情况下,cookie的域名是发送此cookie的服务器域名是一致的
 url格式 ->  协议://域名:端口/资源位置

2.4.4 Cookie的路径作用(path)

代码语言:javascript复制
0. 在我们的项目中,cookie的路径默认为项目的虚拟路径
  url->  http://localhost:8080/项目虚拟路径/Servlet的虚拟路径
  比如: 项目虚拟路径 = /  
   
1. 第一个作用: cookie信息中的path和name共同决定了cookie的唯一性
     a. PathServlet被浏览器每访问一次, cookie就会发送一次
        b. 如果服务器再次发送一个同 path name的cookie,会覆盖浏览器的那个cookie
         (新覆盖旧)
        c. 服务器再次发送一个同 path, 异name的cookie , 不会覆盖
        d. 服务器再次发送一个异 path, 同name的cookie, 不会覆盖
        
2. 第二个作用: cookie的path还决定了cookie允许被访问的范围
  特点:Cookie在其设置的有效路径和其子路径下能够被访问到;
  举例: 有一个cookie,路径为 /aaa
          只有访问 http://localhost:8080/aaa 以及其子路径,才会携带这个cookie
                问题:
                1. 访问http://localhost:8080/PathServlet  -> PathServlet
                  会携带这个cookie吗     ->  不会
                2. 访问http://localhost:8080/aaa    -> AaaServlet
                  会携带这个cookie吗     ->  会
                3. 访问http://localhost:8080/aaa/MyServlet -> MyServlet
                  会携带这个cookie吗     ->  会
#API : cookie.setPath(虚拟路径); 
 路径要以 / 开头
第一个作用的示例

下面我们来写一个简单的示例,编写 Cookie06Servlet 保存两个不同path 但是同 name 的cookie

首先修改 index.html 如下:

image-20210217152045596

编写 Cookie06Servlet 如下:

image-20210217152801055

代码语言:javascript复制
package com.lijw;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Aron.li
 * @date 2021/2/17 15:21
 */
@WebServlet("/Cookie06Servlet")
public class Cookie06Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 创建两个Cookie,同name,但是path不一样
        Cookie cookie1 = new Cookie("cookie06", "value01");
        cookie1.setPath("/");
        response.addCookie(cookie1);

        Cookie cookie2 = new Cookie("cookie06", "value02");
        cookie2.setPath("/a");
        response.addCookie(cookie2);

    }
}

测试请求,查看是否存在两个不同的 Cookie,如下:

image-20210217152837509

image-20210217152912147

image-20210217152925825

可以看到具有两个 cookie06,路径不一致。

第二个作用的示例

第二个作用: cookie的path还决定了cookie允许被访问的范围

image-20210217153122515

2.4.5 Cookie的存活时间

代码语言:javascript复制
# 浏览器中cookie的信息
1. 创建时间: 浏览器接收到此cookie的时间
2. 到期时间: cookie销毁的时间

# cookie的存活时间有两种
1. 会话级别(默认,浏览器关闭,cookie销毁 )
 浏览器中的cookie显示(浏览会话结束时: 浏览器关闭)
 原因: 浏览器将cookie保存内存中(临时的)
 
 cookie在一个会话中(浏览器从打开到关闭: 访问服务器)共享数据
 
2. 持久级别(需要手动设置)
 cookie.setMaxAge(int second); -- 单位是秒
  正数:指定存活时间,持久化浏览器的磁盘中,到期后自动销毁
  零:立即销毁
 原因: 浏览器将cookie保存在硬盘上(持久的) 
 
 cookie在可以在多个会话中(浏览器从打开到关闭多次: 访问服务器)共享数据
 

编写一个设置cookie的时长示例。

index.html 增加请求 Cookie07Servlet:

image-20210217153340447

Cookie07Servlet 设置 cookie 的 存活时间

image-20210217153648640

代码语言:javascript复制
package com.lijw;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Aron.li
 * @date 2021/2/17 15:34
 */
@WebServlet("/Cookie07Servlet")
public class Cookie07Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置存活时间为30分钟的cookie
        Cookie cookie07 = new Cookie("cookie07", "30min");
        cookie07.setMaxAge(60*30); // 30分钟
        response.addCookie(cookie07);

        // 重定向回 index.html
        response.sendRedirect("index.html");
    }
}
测试请求生成的 cookie 存活时间

image-20210217153859689

可以看到 cookie07 的存活时间。

2.4.6 Cookie的删除

代码语言:javascript复制
# 目标:删除Cookie
 1. 用户在浏览器中手动删除cookie(清除浏览记录): 用户未必知道或者配合
 2. 从服务端远程操控删除cookie(服务端)
 
# 远程删除实现步骤:
 0. 核心思想: 服务端发送一个同 path name的cookie,cookie的存活时间为0
    原理:  新cookie先覆盖浏览器保存的cookie,但是因为时间0,新cookie马上死掉
              
 1. 创建与要删除的cookie同name的cookie,将其值设置成什么都无所谓;
    2. 设置这个cookie的路径(与原cookie的路径一致);
    3. 将这个cookie的最大存活时间设置成0;
    4. 将这个新的cookie响应给浏览器,置换原来的cookie,新cookie也马上销毁; 

删除 cookie 的 Servlet 示例:

代码语言:javascript复制
@WebServlet("/Cookie08Servlet")
public class Cookie08Servlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //创建一个短命cookie,跟要删除cookie同path name
        Cookie cookie = new Cookie("car", "");
        cookie.setPath("/"); // http://localhost:8080/...
        cookie.setMaxAge(0); // 设置存活时间只有0秒
        response.addCookie(cookie);

    }

}

2.5 Cookie特点

代码语言:javascript复制
1. cookie存储数据在客户端(浏览器)
2. cookie的存储数据(name和value)只能是字符串
3. cookie单个大小不能超过4KB
4. 同一个域名下cookie数量一般不能超过50个
5. 同一域名下, cookie的path和name决定了它的唯一性
6. cookie存储的数据不太安全
  信息保存在用户的电脑上,都相对不安全

三、 综合案例

3.1 商品浏览记录

需求

做一个商品页面,当我们访问后,在页面上点击查看商品浏览记录后,可以查看到以前浏览过的商品信息。

3.1.1 需求分析

  • 编写一个商品列表页面 goods.html ,设置两个请求,可以添加两个商品到购物车中(每个添加都会请求到 GoodsServlet 中)
  • GoodsServlet 程序接收页面发送过来的商品信息,将其商品信息拼接保存为一个 Cookie,重定向至 goods2.html
  • 编写另一个 goods2.html,用于查看保存到购物车中的商品信息(请求至 HistoryServlet)
  • HistoryServlet 程序解析 goods2.html 发送过来的 Cookie 信息,显示商品内容

3.1.2 代码实现

① goods.html

image-20210217155259312

代码语言:javascript复制
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="GoodsServlet?product=huawei">华为手机</a><br>
    <a href="GoodsServlet?product=xiaomi">小米手机</a> <br>
    <a href="GoodsServlet?product=chuizi">锤子手机</a> <br>
</body>
</html>
② goods2.thml

image-20210217155344702

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="goods.html">继续浏览</a> <br>
<a href="HistoryServlet">查看浏览记录</a> <br>
</body>
</html>
③ GoodsServlet

image-20210217160819321

代码语言:javascript复制
package com.lijw;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Aron.li
 * @date 2021/2/17 15:54
 */
@WebServlet("/GoodsServlet")
public class GoodsServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 获取请求参数
        String product = request.getParameter("product");

        //2. 获取请求中的cookie
        Cookie[] cookies = request.getCookies();
        //2.1 判断是否存在 history 的 cookie
        Boolean exist_history = false; // 用于标识history的cookie是否存在
        if (cookies != null && cookies.length > 0){
            for (Cookie cookie : cookies) {
                String name = cookie.getName();
                if("history".equalsIgnoreCase(name)){
                    // 设置标识存在 history cookie
                    exist_history = true;
                    // history的cookie存在
                    String value = cookie.getValue();
                    value = value   "_"   product;
                    cookie.setValue(value);
                    response.addCookie(cookie);
                }
            }

            //判断history如果不存在,则创建新的Cookie
            if (!exist_history) {
                Cookie cookie = new Cookie("history", product);
                cookie.setMaxAge(60*30);//30分钟
                response.addCookie(cookie);
            }

        }

        //3. 重定向到 goods2.html
        response.sendRedirect("goods2.html");
    }
}
④ HistoryServlet

image-20210217155643123

代码语言:javascript复制
package com.lijw;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Aron.li
 * @date 2021/2/17 15:55
 */
@WebServlet("/HistoryServlet")
public class HistoryServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        //1.获取请求中的cookie
        Cookie[] cookies = request.getCookies();
        if(cookies != null && cookies.length > 0){
            for (Cookie cookie : cookies) {
                String name = cookie.getName();
                if("history".equalsIgnoreCase(name)){
                    String value = cookie.getValue();

                    String[] array = value.split("_");
                    response.getWriter().print("<h1>浏览器记录:</h1>");
                    for (String element : array) {
                        response.getWriter().print(element   "<br>");
                    }
                }
            }

        }else{
            response.getWriter().print("无浏览记录");
        }
        response.getWriter().print("<br>");
        response.getWriter().print("<a href='goods.html'>继续浏览</a>");
    }
}

3.1.3 测试功能

image-20210217155801203

image-20210217160740185

image-20210217160752549

0 人点赞