【愚公系列】2023年03月 Java教学课程 092-Servlet服务器的Cookie

文章目录

  • 前言
  • 一、会话技术
    • 1.话管理概述
      • 1.1 什么是会话
      • 1.2 会话管理作用
      • 1.3 会话管理分类
    • 2.客户端会话管理技术(Cookie)
      • 2.1 Cookie概述
        • 1)什么是Cookie
        • 2)Cookie的API详解
        • 3)Cookie涉及的常用方法
      • 2.2 Cookie的Path细节:浏览器什么时候带给服务器,什么时候不带
        • 1)需求说明
        • 2)案例目的
        • 3)案例步骤
        • 4)测试结果
        • 5)路径问题的分析及总结

前言

一、会话技术

1.话管理概述

1.1 什么是会话

网页会话是指在用户与网站进行交互时,服务器会为每个用户创建一个会话,用于存储用户的信息和状态,以便在用户浏览网站的不同页面时能够保持用户的登录状态和其他相关信息。会话通常使用 cookie 或 URL 重写来实现。

1.2 会话管理作用

网页会话管理的作用是维护用户在网站上的登录状态和用户的个性化设置,以及在用户与网站之间的交互过程中保持数据的一致性。例如,当用户登录网站时,网站会创建一个会话并将会话 ID 存储在用户的浏览器 cookie 中,以便在用户浏览网站的不同页面时保持其登录状态。另外,网页会话管理还可以用于实现购物车、表单数据的保存等功能。

举例来说,当用户在购物网站上添加商品到购物车时,网站会将商品信息存储在用户的会话中,以便用户在结账时可以查看其购物车中的商品。如果用户在浏览网站的过程中关闭了浏览器或者会话过期,网站会自动清除用户的会话数据,以确保用户的数据安全性。

1.3 会话管理分类

网页的会话技术主要包括 Cookie 和 Session。Cookie 是一种在客户端保存数据的技术,可以在客户端保存一些用户信息,比如登录状态、购物车信息等。而 Session 则是一种在服务器端保存数据的技术,可以在服务器端保存用户的登录状态、权限等信息。两者的区别在于数据存储的位置不同,Cookie 存储在客户端,Session 存储在服务器端。

在JavaEE的项目中,会话管理分为两类。分别是:Cookie 和 Session

Cookie

​ 它是把要共享的数据保存到了客户端(也就是浏览器端)。每次请求时,把会话信息带到服务器,从而实现多次请求的数据共享。

Session

​ 它本质仍是采用客户端会话管理技术,只不过保存到客户端的是一个特殊的标识,并且把要共享的数据保存到了服务端的内存对象中。每次请求时,把这个标识带到服务器端,然后使用这个标识,找到对应的内存空间,从而实现数据共享。

本文主要是介绍Cookie,Session将在下一篇文章介绍。

2.客户端会话管理技术(Cookie)

2.1 Cookie概述

1)什么是Cookie

它是客户端浏览器的缓存文件,里面记录了客户浏览器访问网站的一些内容。同时,也是HTTP协议请求和响应消息头的一部分(在HTTP协议课程中,我们备注了它很重要)。

2)Cookie的API详解

作用

它可以保存客户浏览器访问网站的相关内容(需要客户端不禁用Cookie)。从而在每次访问需要同一个内容时,先从本地缓存获取,使资源共享,提高效率。

Cookie的属性

属性名称

属性作用

是否重要

name

cookie的名称

必要属性

value

cookie的值(不能是中文)

必要属性

path

cookie的路径

重要

domain

cookie的域名

重要

maxAge

cookie的生存时间。

重要

version

cookie的版本号。

不重要

comment

cookie的说明。

不重要

细节

Cookie有大小,个数限制。每个网站最多只能存20个cookie,且大小不能超过4kb。同时,所有网站的cookie总数不超过300个。

当删除Cookie时,设置maxAge值为0。当不设置maxAge时,使用的是浏览器的内存,当关闭浏览器之后,cookie将丢失。设置了此值,就会保存成缓存文件(值必须是大于0的,以秒为单位)。

3)Cookie涉及的常用方法

创建Cookie

代码语言:javascript
复制
/**
 * 通过指定的名称和值构造一个Cookie
 *
 * Cookie的名称必须遵循RFC 2109规范。这就意味着,它只能包含ASCII字母数字字符,
 * 不能包含逗号、分号或空格或以$字符开头。
 * 创建后无法更改cookie的名称。
 *
 * 该值可以是服务器选择发送的任何内容。
 * 它的价值可能只有服务器才感兴趣。
 * 创建之后,可以使用setValue方法更改cookie的值。
 */
public Cookie(String name, String value) {
	validation.validate(name);
	this.name = name;
	this.value = value;
}

向浏览器添加Cookie

代码语言:javascript
复制
/**
 * 添加Cookie到响应中。此方法可以多次调用,用以添加多个Cookie。
 */
public void addCookie(Cookie cookie);

从服务器端获取Cookie

代码语言:javascript
复制
/**
 * 这是HttpServletRequest中的方法。
 * 它返回一个Cookie的数组,包含客户端随此请求发送的所有Cookie对象。
 * 如果没有符合规则的cookie,则此方法返回null。
 */
 public Cookie[] getCookies();

2.2 Cookie的Path细节:浏览器什么时候带给服务器,什么时候不带

1)需求说明

创建一个Cookie,设置Cookie的path,通过不同的路径访问,从而查看请求携带Cookie的情况。

2)案例目的

通过此案例的讲解客户浏览器何时带cookie到服务器端,何时不带。

3)案例步骤

第一步:创建JavaWeb工程

沿用第一个案例中的工程即可。

第二步:编写Servlet

代码语言:javascript
复制
/**
 * Cookie的路径问题
 *
 * 	1.在demo1中写一个cookie到客户端
 *  2.在demo2和demo3中分别去获取cookie
 *  	demo1的Servlet映射是   /servlet/PathQuestionDemo1
 *  	demo2的Servlet映射是   /servlet/PathQuestionDemo2
 *  	demo3的Servlet映射是   /PathQuestionDemo3
 *
 */
public class PathQuestionDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
	//1.创建一个Cookie
	Cookie cookie = new Cookie("pathquestion","CookiePathQuestion");
	//2.设置cookie的最大存活时间
	cookie.setMaxAge(Integer.MAX_VALUE);
	//3.把cookie发送到客户端
	response.addCookie(cookie);//setHeader("Set-Cookie","cookie的值")
}

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

}

代码语言:javascript
复制
/**

  • 获取Cookie,名称是pathquestion
    */
    public class PathQuestionDemo2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //1.获取所有的cookie
    Cookie[] cs = request.getCookies();
    //2.遍历cookie的数组
    for(int i=0;cs!=null && i<cs.length;i++){
    if("pathquestion".equals(cs[i].getName())){
    //找到了我们想要的cookie,输出cookie的值
    response.getWriter().write(cs[i].getValue());
    return;
    }
    }
    }

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

代码语言:javascript
复制
/**

  • 获取Cookie,名称是pathquestion
    */
    public class PathQuestionDemo3 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //1.获取所有的cookie
    Cookie[] cs = request.getCookies();
    //2.遍历cookie的数组
    for(int i=0;cs!=null && i<cs.length;i++){
    if("pathquestion".equals(cs[i].getName())){
    //找到了我们想要的cookie,输出cookie的值
    response.getWriter().write(cs[i].getValue());
    return;
    }
    }
    }

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

  • 第三步:配置Servlet

    代码语言:javascript
    复制
    <servlet>
    <servlet-name>PathQuestionDemo1servlet-name>
    <servlet-class>com.itheima.web.servlet.pathquestion.PathQuestionDemo1servlet-class>
    servlet>
    <servlet-mapping>
    <servlet-name>PathQuestionDemo1servlet-name>
    <url-pattern>/servlet/PathQuestionDemo1url-pattern>
    servlet-mapping>

    <servlet>
    <servlet-name>PathQuestionDemo2servlet-name>
    <servlet-class>com.itheima.web.servlet.pathquestion.PathQuestionDemo2servlet-class>
    servlet>
    <servlet-mapping>
    <servlet-name>PathQuestionDemo2servlet-name>
    <url-pattern>/servlet/PathQuestionDemo2url-pattern>
    servlet-mapping>

    <servlet>
    <servlet-name>PathQuestionDemo3servlet-name>
    <servlet-class>com.itheima.web.servlet.pathquestion.PathQuestionDemo3servlet-class>
    servlet>
    <servlet-mapping>
    <servlet-name>PathQuestionDemo3servlet-name>
    <url-pattern>/PathQuestionDemo3url-pattern>
    servlet-mapping>

    第四步:部署工程

    沿用第一个案例中的工程部署即可。

    4)测试结果

    通过分别运行PathQuestionDemo1,2和3这3个Servlet,我们发现由demo1写Cookie,在demo2中可以取到,但是到了demo3中就无法获取了。

    5)路径问题的分析及总结

    问题:
    demo2和demo3谁能取到cookie?
    答案:
    demo2能取到,demo3取不到
    分析:

    我们是通过demo1写的cookie,demo1的访问路径是: http://localhost:9090/servlet/PathQuestionDemo1
    通过比较两个路径:请求资源地址和cookie的path,可以看出:cookie的path默认值是:请求资源URI,没有资源的部分(在我们的案例中,就是没有PathQuestionDemo1)。

    客户端什么时候带cookie到服务器,什么时候不带?
    ​ 就是看请求资源URI和cookie的path比较。

    ​ 请求资源URI.startWith(cookie的path) 如果返回的是true就带,如果返回的是false就不带。

    ​ 简单的说: 就是看谁的地址更精细

    ​ 比如:Cookie的path: /国家 /省份 /城市

    代码语言:javascript
    复制
    	 	 请求资源URI	:   	  /国家			/省份														  不带
    请求资源URI : /国家 /省份 /城市 /区县 带

    在我们的案例中:

    访问URL

    URI部分

    Cookie的Path

    是否携带Cookie

    能否取到Cookie

    PathQuestionDemo2

    /servlet/PathQuestionDemo2

    /servlet/

    能取到

    PathQuestionDemo3

    /PathQuestionDemo3

    /servlet/

    不带

    不能取到