B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa 十天免登录的功能

B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa 十天免登录的功能

在这里插入图片描述


每博一文案

嘿,大风扬起的沉沙中,每一粒都有它的必然性,而每个人的命运都有自己的因果,
为自己的选择负责承担或好或坏的结果。是成年人的必修课。
有人请教索罗斯投资的指导,我的父亲一直追随你炒股却总是不断亏欠,这是为什么?
索罗斯回答,因为我不断犯错误,但我改正得很快,没有一劳永逸的选择,人生就是一个不断试错的过程,
吸取教训就不会再犯同样的错。
美国作家布莱克克劳奇的小说人生副本中,为了家庭放弃事业的主人公贾森偶然地闯入了另一个平行世界。体验
了一把选择事业的人生。平行世界里的贾森二号说,每个时刻每次呼吸都包含了一个选择,可是人生是不完美的,我们
会做错选择,所以最后总会,活在无尽的懊悔中。还有什么比这个更糟糕的吗?
事实上,我建造的这样东西能将懊悔连根拔除,让我们找到做出正确选择的时间。
而贾森的妻子答道:人生不是这样运作的,你要承担自己的选择,从中学到教训,而不是投机取巧。
人生没有如果只有结果,每个人都要为自己的选择承担责任,人独生独死,独来独去,苦乐自当,无有待着。
不管结果怎样,都只能由我们自己去承受,学会看待每一种选择,也学会承担选择后的结果。
人不是因为成长了才去承担,而是因为承担了,才会成长,不对既成的事情,自怨自艾,坦诚的接受结果,
并从遗憾中吸取教训,往后余生更谨慎地对待每一条人生分叉路。
审慎地走好未来的每一步,如今我们自己的人生,纵使有着遗憾,也是谁都不可以更改的人生。即便是我们自己。
愿你一身清醒,一身坚强,做好选择,承担后果,无畏无惧,无怨无悔。
                                ——————  《一禅心灵庙语》 

1. Cookie 的概述

在这里插入图片描述

Cookie 并不是它的原意“甜饼”的意思, 而是一个保存在客户机中的简单的文本文件, 这个文件与特定的 Web 文档关联在一起, 保存了该客户机访问这个Web 文档时的信息, 当客户机再次访问这个 Web 文档时这些信息可供该文档使用。由于“Cookie”具有可以保存在客户机上的神奇特性, 因此它可以帮助我们实现记录用户个人信息的功能, 而这一切都不必使用复杂的CGI等程序 。

举例来说, 一个 Web 站点可能会为每一个访问者产生一个唯一的ID, 然后以 Cookie 文件的形式保存在每个用户的机器上。如果使用浏览器访问 Web, 会看到所有保存在硬盘上的 Cookie。在这个文件夹里每一个文件都是一个由“名/值”对组成的文本文件,另外还有一个文件保存有所有对应的 Web 站点的信息。在这里的每个 Cookie 文件都是一个简单而又普通的文本文件。透过文件名, 就可以看到是哪个 Web 站点在机器上放置了Cookie(当然站点信息在文件里也有保存) [2] 。

所谓“cookie”数据是指某些网站为了辨别用户身份,储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。

通俗来讲就是指缓存数据,包括用户名、密码、注册账户、手机号等公民个人信息。

在这里插入图片描述

Cookie 存在两种类型:

  • 第一种:你浏览的当前网站设置的cookie。
  • 第二种: 来自网页上嵌入广告或图片等其他域来源的第三方cookie(网站通过使用这些cookie可以跟踪你的使用信息)

2. session 与 Cookie 之间的联系:

关于 session 会话机制的内容想要了解更多的详细内容,大家可以移步至 : 🔜🔜🔜 B/S结构系统的会话机制(session)_ChinaRainbowSea的博客-CSDN博客

我们知道在 session的实现原理中,每一个 session 对象都会关联一个 sessionid,例如:JSESSIONID=41C481F0224664BDB28E95081D23D5B8 以上的这个 JSESSIONID 的 sessionID 标签也就是 session 列表当中的键值对数据其实就是 cookie对象。 因为服务器发送给客户端的 这个 JSEESIIONID ,当客户端接受到以后,就会将其存储到我们浏览器(客户端)的 Cookie 当中。

  • 对于session关联的cookie来说,这个cookie是被保存在浏览器的“运行内存(可以理解为是 Cookie 缓存)”当中。
  • 只要浏览器不关闭,用户再次发送请求的时候,会自动将运行内存Cookie 中的cookie信息发送给服务器。
  • 例如,这个Cookie: JSESSIONID=41C481F0224664BDB28E95081D23D5B8就会再次发送给服务器。
  • 服务器就是根据41C481F0224664BDB28E95081D23D5B8这个值来找到对应的session对象的。
  • 这部分内容是 对于 sesion 会话机制的原理的简单剖析。想要了解更多有关 session 会话机制的内容,可以移步至上面的有关 session 的跳转链接。

cookie怎么生成?cookie保存在什么地方?cookie有啥用?浏览器什么时候会发送cookie,发送哪些cookie给服务器???????

Cookie 是将会话的状态保存在浏览器客户端上的。注意:cookie 的数据信息是存储在浏览器客户端上的,不是存储在服务器当中的。

cookie最终是保存在浏览器客户端上的。

  • 可以保存在运行内存中。(浏览器只要关闭cookie就消失了。)
  • 也可以保存在硬盘文件中。(永久保存。)

3. Cookie 的作用:

  • cookie和session机制其实都是为了保存会话的状态。

  • cookie是将会话的状态保存在浏览器客户端上。(cookie数据存储在浏览器客户端上的。)

  • session是将会话的状态保存在服务器端上。(session对象是存储在服务器上。)

  • 为什么要有cookie和session机制呢 ?因为HTTP协议是无状态 无连接协议

  • 注意 Cookie 和 session 的区别:

4. Cookie 的生成机理的原理:

HTTP Cookie,通常直接叫做cookie,标准要求服务器将Set-Cookie作为响应的一部分,其中包含会话信息,这种服务器响应报文的首部字段可能如下,其中以name为名称、以value为值,这是要求客户端发送name这个键名的cookie值,如下:

HTTP/1.1 200 OK
Content-type: Text/html
Set-Cookie: name=value
Other-header: other-header-value

在这里插入图片描述

具体代码实现如下:这里只是简单的提示一下,该文章后面会详细说明其中的 Cookie 方法的使用:

package com.RainbowSea.cookie;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;


@WebServlet("/cookie")
public class TestCookie extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Cookie cookie = new Cookie("user","123");

        // cookie 信息数据是从服务器产生的,服务器将cookie 信息响应给客户端,客户端存储到Cookie(缓存当中)
        response.addCookie(cookie);


    }
}

在这里插入图片描述

5. Cookie 经典案例

京东商城,在未登录的情况下,向购物车中放几件商品。然后关闭商城,再次打开浏览器,访问京东商城的时候,购物车中的商品还在,这是怎么做的?我没有登录,为什么购物车中还有商品呢?

将购物车中的商品编号放到cookie当中,cookie保存在硬盘文件当中。这样即使关闭浏览器。硬盘上的cookie还在。下一次再打开京东商城的时候,查看购物车的时候,会自动读取本地硬盘中存储的cookie,拿到商品编号,动态展示购物车中的商品。

  • 京东存储购物车中商品的cookie可能是这样的:productIds=xxxxx,yyyy,zzz,kkkk
  • 注意:cookie如果清除掉,购物车中的商品就消失了。

126邮箱中有一个功能:30 天内免登录

在这里插入图片描述

  • 这个功能也是需要cookie来实现的。怎么实现的呢?

用户输入正确的用户名和密码,并且同时选择十天内免登录。登录成功后。浏览器客户端会保存一个cookie,这个cookie中保存了用户名和密码等信息,这个cookie是保存在硬盘文件当中的,十天有效。在十天内用户再次访问126的时候,浏览器自动提交126的关联的cookie给服务器,服务器接收到cookie之后,获取用户名和密码,验证,通过之后,自动登录成功。

怎么让cookie失效 ?

  • 十天过后自动失效。
  • 或者改密码。
  • 或者在客户端浏览器上清除cookie。

6. Cookie 的配置的常用方法

cookie 机制和session机制其实都不属于java中的机制,实际上cookie 机制和 session 机制都是HTTP协议的一部分。php开发中也有cookie和session机制,只要是你是做web开发,不管是什么编程语言,cookie和session机制都是需要的。

6.1 创建 Cookie 对象

在这里插入图片描述

在这里插入图片描述

  • HTTP协议中规定:任何一个cookie都是由 namevalue组成的。name和value都是 字符串类型的。

  • 在java的servlet中,对cookie提供了哪些支持呢?

    • 提供了一个Cookie类来专门表示cookie数据。jakarta.servlet.http.Cookie; 我们可以查看其 Tomcat 提供的文档:D:\dev\apache-tomcat-10.0.12-fulldocs\tomcat-10.0-doc\servletapi\jakarta\servlet\http

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

public Cookie(java.lang.String name,
              java.lang.String value);  // 创建 Cookie 对象,形参都是字符串类型的。表示在服务器当中拆创建了一个 cookie 对象。注意了我们这里创建的 cookie 对象是在服务器当中的,我们需要将其发送,响应给客户端,让客户端保存起来。
// 注意点:我们的 value 值不应包含 ”空格,括号,圆括号,等号,逗号,双引号,斜杆,问号,@号,冒号和分号。空值在所有的浏览器上的表现可能不一样。“
  • java程序怎么把cookie数据发送给浏览器呢?使用:response.addCookie(cookie); 注意: 客户端当中的 Cookie 存储的数据是来源于:服务的,所以是 response 响应 ,服务器创建封装好 cookie 数据信息好后,响应给浏览器(客户端) ,客户端接受到该服务器发送过来的 cookie 数据信息,并将其存储到自身客户端的Cookie(缓存)当中。
void addCookie(Cookie cookie);  // 将指定的 cookie 添加到响应(响应给客户端),这个方法可以被多次调用来设置多个 cookie 。 形参参数为: Cookie 返回给客户端的 cookie 对象。

重点: 在HTTP协议中是这样规定的:当浏览器发送请求的时候,会自动携带该path下的 cookie数据给服务器(URL),任何以 Cookie 形式存储的值,无论服务器端是否需要,每一个 HTTP 请求都会把这些数据 (cookie 数据)传输到服务器端。 简单的说就是:只有客户端当中的 Cookie 缓存当中存在数据信息(无论是何种信息),无论服务器是否需要,只有是在 cookie 设置的 path(映射路径下)的服务器,都会将其 Cookie 缓存当中的数据信息发送给服务器,没有为什么这是 HTTP协议强制规定的。

举例:代码如下:

package com.RainbowSea.cookie;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;


@WebServlet("/cookie")
public class TestCookie extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 创建cookie 对象,注意:Cookie 没有无参构造器,必须传参数,分别为: name, value
        Cookie cookie = new Cookie("user","123");

        // cookie 信息数据是从服务器产生的,服务器将cookie 信息响应给客户端,客户端存储到Cookie(缓存当中)
        response.addCookie(cookie);
        
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

注意点:我们的 value 值不应包含 “空格,括号,圆括号,等号,逗号,双引号,斜杆,问号,@号,冒号和分号”如果包含了这些特殊值可能会报 500 一般 以5开头的是 服务器内部的错误。空值在所有的浏览器上的表现可能不一样。

在这里插入图片描述

6.2 获取到 Cookie 当中存储的信息

浏览器(客户端)发送cookie给服务器了,服务器中的java程序怎么接收?

因为是从客户端通过请求的方式,将 cookie 存储的数据发送给服务器的,所以服务器要使用 request (请求)对象,获取到客户端发送过来的 cookie 数据信息。使用如下方法:

Cookie[] getCookies(); // 返回一个有关Cookie类型的数组,其中包含客户端此请求发送的所以 Cookie 对象。如果客户端没有发送 cookie 信息,则返回的 null,不是返回一个为 0 的数组。
public java.lang.String getName();  // 返回当前Cookie的名称,也就是我们创建 cookie 对象时的参数为 name 的值。注意了: Cookie 当中的 name 值一旦设置好以后,就无法修改了。Cookie 没有提供 setName()的方法
public java.lang.String getValue();  // 返回当前Cookie 当中的 value 值,
public void setValue​(java.lang.String newValue);  // 修改当前Cookie 当中的 value 值。。 如果使用二进制值,则可能需要使用BASE64编码。

举例:我们这里创建三个 Cookie 对象,响应给客户端,服务器读取到该Cookie 信息

创建Cookie 对象的Servlet类,创建三个 cookie 对象。

package com.RainbowSea.cookie;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;


@WebServlet("/cookie")
public class TestCookie extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 创建cookie 对象,注意:Cookie 没有无参构造器,必须传参数,分别为: name, value
        Cookie cookie = new Cookie("test","01");
        Cookie cookie2 = new Cookie("test02","02");
        Cookie cookie3 = new Cookie("test03","03");

        // cookie 信息数据是从服务器产生的,服务器将cookie 信息响应给客户端,客户端存储到Cookie(缓存当中)
        response.addCookie(cookie);   // 将cookie 响应到浏览器的客户端
        response.addCookie(cookie2);  // 将cookie2 响应到浏览器客户端
        response.addCookie(cookie3);  // 将cookie3 响应到浏览器客户端

    }
}

获取到客户端发送过来的 cookie 数据信息的 Servlet

package com.RainbowSea.cookie;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;


@WebServlet("/cookie02")
public class TestCookie2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {

        // 获取到该Cookie path 映射路径下的客户端发送过来的所有的Cookie 对象
        // 因为是客户端通过 request(请求)的方式发送过来的,所有需要使用 request 来获取信息
        Cookie[] cookies = request.getCookies();  // 如果客户端没有发送cookie信息过来,则返回null

        // 遍历Cookie 数组信息
        for (Cookie cookie : cookies) {
            String name = cookie.getName();  // 获取到 Cookie 当中的 name 值
            String value = cookie.getValue();  // 获取到Cookie 当中的value 值

            System.out.println(name = "-->" + value);

        }

        System.out.println("****************************************");

        // 可以通过数组下标的方式遍历:
        for (int i = 0; i < cookies.length; i++) {
            String name = cookies[i].getName();  // 获取到对于Cookie下标的name值
            String value = cookies[i].getValue(); // 获取到对于Cookie 下标的value值

            System.out.println(name = "==>" + value);
        }

    }
}

测试效果:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

6.3 设置 Cookie 的有效时间

怎么用java设置cookie的有效时间 ? 我们可以使用如下 Cookie 类当中的 如下方法,设置 cookie 的有效时间

/**
     * Sets the maximum age of the cookie in seconds.
     * <p>
     * A positive value indicates that the cookie will expire after that many
     * seconds have passed. Note that the value is the <i>maximum</i> age when
     * the cookie will expire, not the cookie's current age.
     * <p>
     * A negative value means that the cookie is not stored persistently and
     * will be deleted when the Web browser exits. A zero value causes the
     * cookie to be deleted.
     *
     * @param expiry
     *            an integer specifying the maximum age of the cookie in
     *            seconds; if negative, means the cookie is not stored; if zero,
     *            deletes the cookie
     * @see #getMaxAge
     */

public void setMaxAge(int expiry) {  // 设置cookie 的有效时间:单位是 s 秒
        maxAge = expiry;
 }
cookie.setMaxAge(int )

注意:cookie.setMaxAge(int ) 参数有三个取值的范围:不同的取值对应 cookie 不同的时间效果:

cookie.setMaxAge() 设置 cookie 的有效时间其中参数的单位是 ,不是毫秒。

  • 参数:cookie的有效时间(参数) < 0, 如果默认不设置 cookie 的有效时间,默认也是 < 0 的。这个是默认的。作用效果: cookie 的信息是保存在浏览器的运行内存中,浏览器关闭则cookie消失。

测试:

package com.RainbowSea.cookie;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;


@WebServlet("/method")
public class CookieMethod extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {

        // 创建 cookie 对象,并封装信息
        Cookie cookie = new Cookie("test","time");

        // 设置 cookie 的有效时间: < 0 ,表示cookie 信息保存在浏览器运行内存当中,浏览器关闭cookie消失
        // 默认没有配置 cookie 有效时间,也是 < 0 的,这个是默认的配置
        cookie.setMaxAge(-1);  // 设置有效时间: 单位是 s(秒)

        // 将cookie 的信息响应给客户端,客户端接受到以后,存储起来,这里cookie 设置的是 < 0 ,
        // 则客户端接受到的cookie 信息会存储到,浏览器运行内存当中,浏览器关闭 cookie 消失
        response.addCookie(cookie);




    }
}

在这里插入图片描述

  • 参数:cookie的有效时间(参数) > 0, 作用效果: 这个cookie信息是一定会存储到客户端的硬盘文件当中,就不是存在在浏览器的运行内存当中了,这里就算是浏览器关闭了,只要该 cookie 的有效时间没有到,则 cookie 信息是存储到硬盘文件当中的,还是存在的,并且是可以获取到也是有效的。

测试:

package com.RainbowSea.cookie;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;


@WebServlet("/method")
public class CookieMethod extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {

        // 创建 cookie 对象,并封装信息
        Cookie cookie = new Cookie("test", "time");

        // 设置cookie 的有效时间为:  2 分钟.并且是将cookie信息存储到硬盘文件当中的。不是浏览器的运行内存
        cookie.setMaxAge(60 * 2);  // 设置有效时间: 单位是 s(秒)

        // 将cookie 的信息响应给客户端,客户端接受到以后,存储起来,这里cookie 设置的是 < 0 ,
        // 则客户端接受到的cookie 信息会存储到,浏览器运行内存当中,浏览器关闭 cookie 消失
        response.addCookie(cookie);


    }
}

在这里插入图片描述

  • 参数:cookie的有效时间(参数) = 0 , 作用效果: cookie被删除,同名cookie被删除。 表示的就是: cookie 有效时间是为 1970年1月1日 0 时 0 分 10秒 。现在都是 21 世纪了 2023 年,cookie 已经失效了

测试:

package com.RainbowSea.cookie;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;


@WebServlet("/method")
public class CookieMethod extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {

        // 创建 cookie 对象,并封装信息
        Cookie cookie = new Cookie("test", "time");

        // 设置cookie 的有效时间为: 0 表示:删除同名的 cookie 信息,删除 cookie 信息,
        // 实际上表示 cookie 的有效时间为 1970年1月1日 0 时 0 分 10秒
        cookie.setMaxAge(0);  // 设置有效时间: 单位是 s(秒)

        // 将cookie 的信息响应给客户端,客户端接受到以后,存储起来,这里cookie 设置的是 < 0 ,
        // 则客户端接受到的cookie 信息会存储到,浏览器运行内存当中,浏览器关闭 cookie 消失
        response.addCookie(cookie);


    }
}

在这里插入图片描述

6.4 设置Cookie 的 path 映射/关联路径

在了解:Cookie 的 path 映射/关联路径的的设置方法之前,我们需要知道什么时 path 映射 或者说时 cookie 的关联路径是一个什么意思:

所谓的 Cookie 的 path 映射/关联路径: 说的就是,我们客户端浏览器,发送一个什么样( cookie对象所设置的 Path 路径)的请求路径的时候,客户端才会将自身存储到的 cookie 信息发送给服务器。前面我们有提到一件十分重要的事情就是:在HTTP协议中是这样规定的:当浏览器发送请求的时候,会自动携带该path下的 cookie数据给服务器(URL),任何以 Cookie 形式存储的值,无论服务器端是否需要,每一个 HTTP 请求都会把这些数据 (cookie 数据)传输到服务器端。其中所提到的 path 映射的 URL路径,就是这里我们现在所说的这个 path 映射/关联路径。它们是所指的都是同一个东西。

关于如何设置 Cookie 对象的 path 映射/关联路径,我们先不着急解释,我们先来,了解一下关于,如果我们 Cookie 对象没有设置 path 映射/关联路径的时候,默认的 path 映射/关联路径又是什么?

测试实验验证:不设置 cookie 的 path 映射/关联路径。默认 path 是哪个路径:

在这里插入图片描述

假设现在我们发送的请求路径是:“http://127.0.0.1:8080/servlet14/method”就是本地存在的 Servlet (就是创建 Cookie 对象的 Servlet) 。我们查看其 Request Headers 的请求头,可以看到客户端(浏览器) 将 Cookie 当中存储的信息发给了 服务器:
在这里插入图片描述

我们再访问该 Servlet/method/test 的一个不存在的路径服务器,客户端依旧会发送 cookie 信息给服务器,就是该服务器不存在。http://127.0.0.1:8080/servlet14/method/test

在这里插入图片描述

  • http://127.0.0.1:8080/servlet14/method/test/test2 该路径虽然不存在,但是 客户端依旧会将 cookie 信息发送给服务器的。

在这里插入图片描述

  • http://127.0.0.1:8080/servlet14/test3 同样依旧会发送 cookie 信息给服务器

在这里插入图片描述

  • http://127.0.0.1:8080/servlet14/test3/test4 cookie 信息还是会发送给 服务器的。

在这里插入图片描述

  • http://127.0.0.1:8080/test5 注意了: 该路径下访问,客户端是不会将 cookie 信息发送给服务器的。

在这里插入图片描述

从上述的测试实验的结果:我们可以得出一个结论就是:默认没有设置 path 的情况下,默认是:http://127.0.0.1:8080/web项目的根目录/以及它的子路径。 比如:http://127.0.0.1:8080/servlet14/method

也就是说,以后只要浏览器的请求路径是:http://127.0.0.1:8080/servlet14/method这个路径以及这个路径下的子路径,cookie都会被发送到服务器。

现在我们知道了,没有设置 path 的情况下,默认是设置是什么了。

下面我们现在就来看看,如何手动设置 cookie 的 path 。我们可以使用如下方法:

需要注意的是:不同的 cookie 的对象都需要各自独立的设置对应的 path 映射路径/ 关联路径

 /**
     * Specifies a path for the cookie to which the client should return the
     * cookie.
     * <p>
     * The cookie is visible to all the pages in the directory you specify, and
     * all the pages in that directory's subdirectories. A cookie's path must
     * include the servlet that set the cookie, for example, <i>/catalog</i>,
     * which makes the cookie visible to all directories on the server under
     * <i>/catalog</i>.
     * <p>
     * Consult RFC 2109 (available on the Internet) for more information on
     * setting path names for cookies.
     *
     * @param uri
     *            a <code>String</code> specifying a path
     * @see #getPath
     */
public void setPath(String uri) {
   path = uri;
}

cookie.setPath("/servlet14");  // 表示只要是这个servlet14项目的请求路径,都会提交这个cookie给服务器
// request.getContextPath() 返回项目的根路径,注意是: 该返回的路径是带有 "/" 的,所有不用多写 / 了
cookie.setPath(request.getContextPath()); // 将项目的根路径作为 cookie 的path 映射/关联路径
// 表示只要是这个web项目的请求路径,都会提交这个cookie给服务器

测试:

package com.RainbowSea.cookie;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;


@WebServlet("/method")
public class CookieMethod extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {

        // 创建 cookie 对象,并封装信息
        Cookie cookie = new Cookie("test", "time");

        // 设置cookie 的有效时间为: 0 表示:删除同名的 cookie 信息,删除 cookie 信息,
        // 实际上表示 cookie 的有效时间为 1970年1月1日 0 时 0 分 10秒
        cookie.setMaxAge(-1);  // 设置有效时间: 单位是 s(秒)

        // 将cookie 的信息响应给客户端,客户端接受到以后,存储起来,这里cookie 设置的是 < 0 ,
        // 则客户端接受到的cookie 信息会存储到,浏览器运行内存当中,浏览器关闭 cookie 消失
        response.addCookie(cookie);


        // request.getContextPath() 返回项目的根路径,注意是: 该返回的路径是带有 "/" 的,所有不用多写 / 了
        cookie.setPath(request.getContextPath()); // 将项目的根路径作为 cookie 的path 映射/关联路径
        // 表示只要是这个web项目的请求路径,都会提交这个cookie给服务器
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

注意: 不同的 cookie 的对象可以各自独立的设置对应的 path 映射路径/ 关联路径

package com.RainbowSea.cookie;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;


@WebServlet("/cookie")
public class TestCookie extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 创建cookie 对象,注意:Cookie 没有无参构造器,必须传参数,分别为: name, value
        Cookie cookie = new Cookie("test","01");
        Cookie cookie2 = new Cookie("test02","02");
        Cookie cookie3 = new Cookie("test03","03");

        // cookie 信息数据是从服务器产生的,服务器将cookie 信息响应给客户端,客户端存储到Cookie(缓存当中)
        response.addCookie(cookie);   // 将cookie 响应到浏览器的客户端
        response.addCookie(cookie2);  // 将cookie2 响应到浏览器客户端
        response.addCookie(cookie3);  // 将cookie3 响应到浏览器客户端
        
        cookie.setPath("/test1");  // 该 cookie 对象的 path 映射路径是 /test1,只有访问的是这个 /test1的以及子路径才会
                                   // 将该当前的 cookie 信息发送给服务器。其他路径不会将 cookie 发送给服务器
        cookie2.setPath("/test2");  
        cookie3.setPath("/test3"); // 同理: 只有访问的路径为 /test3路径以及其子路径,才会将当前cookie3的信息发送给服务器

    }
}

6.5 使用 https 安全协议发送 cookie 信息

如果访问的是https网页,还需要调用setSecure(true),否则浏览器不会发送该Cookie。

cookie.setSercute(boolean) 表示:参数为 boolean 值:

  • true 表示:如果你访问的是 https 网页,需要设置为 true ,不然浏览器不会发送 cookie 信息
  • false 表示:在任何协议下都会发送 cookie 信息,这个设置是默认的。
/**
     * Indicates to the browser whether the cookie should only be sent using a
     * secure protocol, such as HTTPS or SSL.
     * <p>
     * The default value is <code>false</code>.
     *
     * @param flag
     *            if <code>true</code>, sends the cookie from the browser to the
     *            server only when using a secure protocol; if
     *            <code>false</code>, sent on any protocol
     * @see #getSecure
     */
    public void setSecure(boolean flag) {
        secure = flag;
    }
 cookie.setSecure(true);
 cookie.setSecure(false);

7. session 与 Cookie 之间的区别:

Session是存在于服务器端的。当浏览器第一次发送请求时,服务器自动生成一个Session和一个Session ID作为账号,并通过响应发送到服务器。浏览器第二次发送请求的时候,就可以直接找到相对于的Seesion(但是一旦服务器关闭过了,那么先前所有的Session都会被销毁)

Session 的生成是由服务器生成的,并将其 session 对象对应的 ID 发送给客户端,所有是使用 request的对象获取和设置的。

session.setAttribute(String name, Object obj)	//将信息保存在session范围内
session.getAttribute(String name)		//获取保存在session范围内的信息
session.getAttributeNames(); 	//返回Session对象中存储的每一个属性对象,枚举型
session.isNew()			//判断session对象是不是新的
getCreationTime();		//返回Session被创建的时间.单位毫秒
invalidate();			//设置session无效,一般用在[安全退出]
removeAttribute("key");	//删除属性
1234567

Cookie是存在于客户端的容器。Cookie的数据来自于服务器的,客户端接受了该数据存储到 Cookie缓存当中,存储到Cookie 客户端容器到当中以后,再发送到服务器,而是保存在浏览器当中,如果你没有设置存活时间,那么在你重启浏览器后,你的Cookie是不会保存的。相比于Session来说,Cookie不会占用电脑的运行内存,存储的数据大小也比Session要小,安全性也小于Session。但是一般的自动登录,就是由Cookie来实现完成的。

**注意:**在HTTP协议中是这样规定的:当浏览器发送请求的时候,会自动携带该path下的 cookie数据给服务器(URL),任何以 Cookie 形式存储的值,无论服务器端是否需要,每一个 HTTP 请求都会把这些数据 (cookie 数据)传输到服务器端。 简单的说就是:只有客户端当中的 Cookie 缓存当中存在数据信息(无论是何种信息),无论服务器是否需要,只有是在 cookie 设置的 path(映射路径下)的服务器,都会将其 Cookie 缓存当中的数据信息发送给服务器,没有为什么这是 HTTP协议强制规定的。

有关cookie 的数据是从服务器端响应给客户端的所以,这里我们使用的是 response

在这里插入图片描述
该图片来自于百度图片

8. 运用 Cookie 实现 oa 十天免登录的效果

建议可以先移步至:🔜🔜🔜 B/S结构系统的会话机制(session)_ChinaRainbowSea的博客-CSDN博客 看看 session 实现 oa 的效果,再回到这里来看,cookie 实现 oa 十天免登录的效果,更有助于:阅读理解。

使用cookie实现一下十天内免登录功能。

  • 先实现登录功能
    • 登录成功
      • 跳转到部门列表页面
    • 登录失败
      • 跳转到登录失败页面
  • 修改前端页面
    • 在登录页面给一个复选框,复选框后面给一句话:十天内免登录。
    • 用户选择了复选框:表示要支持十天内免登录。
    • 用户没有选择复选框:表示用户不想使用十天内免登录功能。
  • 修改Servlet中的login方法
    • 如果用户登录成功了,并且用户登录时选择了十天内免登录功能,这个时候应该在Servlet的login方法中创建cookie,用来存储用户名和密码,并且设置路径,设置有效期,将cookie响应给浏览器。(浏览器将其自动保存在硬盘文件当中10天)
  • 用户再次访问该网站的时候,访问这个网站的首页的时候,有两个走向:
    • 要么跳转到部门列表页面:勾选了 10 天免登录的操作,并登录成功
    • 要么跳转到登录页面:登录成功了,但是没有勾选 10 天免登录的操作,或者是勾选了 10 天免登录的操作,但是并没有登录成功。
    • 以上分别有两个走向,这显然是需要编写java程序进行控制的。

在这里插入图片描述

  1. 首先:登录功能上页面的十天免登录的展示:并设置为 该 web 项目的 欢迎页面,想要了解 web 项目如何设置 欢迎页面的操作,可以移步至:🔜🔜🔜 关于Web的欢迎页面的开发设置_web欢迎页面_ChinaRainbowSea的博客-CSDN博客

思路:

通过一个单选框,让用户选择是否 免十天登录的设置。为该 单选框的 value = “true”

当用户提交登录表单给服务器的时候,服务器逻辑判断,获取到该单选框的 value 值,如果成功获取到了,并且值是为 true 的,则进行一个 十条免登录的操作配置。

具体代码实现如下:

<%@page contentType="text/html; charset=UTF-8" %>
<%--表示访问 jsp 的时候不生成 session 对象--%>
<%@page session="false" %>  <%--该指令不是警用jsp内置对象当中的 session--%>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>欢迎使用OA系统</title>
</head>
<body>
<%--<!--注意:对应前端的资源获取基本上都是要加项目名的,并且要"/"开始-->--%>
<%--这种方式不好,将 项目名写死了,--%>
<%--<a href="/servlet09/dept/list/">查看部门列表</a>--%>
<%--使用request.getContextPath() 动态获取项目名的根路径带 / 的,
注意哪里可以加 空格,哪里不能加空格--%>
<%--<a href="<%=request.getContextPath()          %>/dept/list">查看部门列表</a>--%>

<%--<%=request.getContextPath()%> &lt;%&ndash;out.print(request.getContextPath()) 获取到该项目的根路径带有/的&ndash;%&gt;--%>


    <h1>Login in</h1>
    <hr>
    <form action="<%=request.getContextPath()%>/user/login" method="post">
        username: <input type="text" name="username" /><br>
        password: <input type="password" name="password" /> <br>
        免十天登录 <input type="checkbox" name="exempt" value="true" /> <br>
        <input type="submit" value="login" />
    </form>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">

    <!--    配置欢迎页面,局部优先-->
    <welcome-file-list>
        <!--        注意不要加 / 不然报 404 错误无法找到-->
        <welcome-file>welcome</welcome-file>
    </welcome-file-list>
</web-app>
  1. 后端服务器:判断用户是否选择了 十条免登录的选择,并对如果选择了 10 天免登录操作,对应使用 cookie 存储到用户名和用户的密码。

思路:

  1. 首先判断用户是否登录成功。
    1. 登录成功,延续 session 会话机制,将其用户名存储到 session 会话当中,判断用户是否选择了 10 天免登录的设置。
      1. 如果选择了10天免登录的话,则将用户的用户名和密码存储到 cookie 对象当中,定义两个 cookie 对象一个是用户名的 cookie 信息,一个是用户名的密码的 cookie 信息。设置分别对这两个 cookie 设置有效时间为 10 天,以及设置这两个 cookie 的 path 关联路径,以及 cookie 都响应给客户端,让客户端接收到。并跳转至 列表页面。
      2. 没有选择 10 天免登录,跳转至登录页面。
    2. 登录失败,重定向至重新登录页面。
  2. 登录失败,重定向至重新登录页面。
protected void doLogin(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {

        // 一个用户登录验证的方式:验证用户名和密码是否正确
        // 获取用户名和密码
        // 前端提交是数据是:username=111&password=fads
        // 注意:post 提交的数据是在请求体当中,而get提交的数据是在请求行当中

        boolean success = false;  // 标识登录成功

        String username = request.getParameter("username");
        String password = request.getParameter("password");

        String exempt = request.getParameter("exempt");

        // 连接数据库验证用户名和密码
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            // 1. 获取连接,注册驱动
            connection = DBUtil.getConnection();

            // 2. 获取操作数据对象,预编译sql语句, ? 占位符不要加,“”,'' 单双引号,成了字符串了,无法识别成占位符了。
            String sql = "select username,password from t_user where username = ? and password = ?";
            preparedStatement = connection.prepareStatement(sql);

            // 3. 填充占位符,真正执行sql语句
            preparedStatement.setString(1, username);
            preparedStatement.setString(2, password);

            resultSet = preparedStatement.executeQuery();

            // 4. 处理查询结果集
            // 只有一条结果集
            if (resultSet.next()) {
                // 登录成功
                success = true;
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            // 5. 关闭资源,最后使用的最先关闭,
            DBUtil.close(connection, preparedStatement, resultSet);
        }


        // 登录成功与否
        // 设置登录成功十天的免登录
        if (success) {
            // 成功,跳转到用户列表页面
            // 这里使用重定向(没有资源的共享):重定向需要加/项目名 +

            // 获取session 对象(这里的要求是: 必须获取到 session ,没有session 也要新建一个 session 对象)
            // 注意:我们下面的这个会话是不能删除的,因为上面我们虽然通过 welcome Servlet 进行了一个会话
            // 但是 welcome 当中是当我们cookie 当中存在并且用户名和密码正确的时候才会进行一个 session 的
            HttpSession session = request.getSession();  // 服务器当中没有 session 会话域自动创建
            session.setAttribute("username", username);  // 将用户名存储到 session 会话域当中

            // 判断用户是否选择了免十天登录的选择
            // 通过创建 Cookie 缓存机制:
            /*
            将登录成功后,将用户名和密码都存储都 Cookie当中(服务器创建 cookie 信息)。客户端接收该cookie信息并存储起来。
            注意:每一个对应的 cookie 信息都需要进行 (new Cookie() , setMaxAge() ,和 setPath() 响应到客户端)
             */
            if ("true".equals(exempt)) {
                // 创建 Cookie 对象存储登录名
                Cookie cookie = new Cookie("username", username);
                // 创建Cookie 对象存储登录密码
                Cookie cookie2 = new Cookie("password", password);

                // 设置 cookie 的有效期为 10 天
                cookie.setMaxAge(60 * 60 * 24 * 10);// 单位时 s 秒
                cookie2.setMaxAge(60 * 60 * 24 * 10);

                // 设置Cookie 关联的path(只要访问时这个应用,这个项目,浏览器一定要携带两个 cookie信息发送给服务器)
                cookie.setPath(request.getContextPath());
                cookie2.setPath(request.getContextPath());  // 动态获取到项目名,的根路径


                // 将服务器生成的 cookie 信息 响应到浏览器端
                response.addCookie(cookie);
                response.addCookie(cookie2);  // 注意是 response 服务器端将 cookie的信息响应到客户端,客户端接收并存储起来
                // session 会话时,服务器创建的 ,客户端发送request  请求获取到该 session 对象的 sessionID

            }

            response.sendRedirect(request.getContextPath() + "/dept/list");
        } else {
            // 失败,跳转到失败页面
            response.sendRedirect(request.getContextPath() + "/error.jsp");
        }


    }

具体完整代码实现:

package com.RainbowSea.servlet;

import com.RainbowSea.DBUtil.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


@WebServlet({"/user/login", "/user/exit"})
public class UserServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {

        // 获取到浏览器地址栏上的URL路径
        String servletPath = request.getServletPath();

        if ("/user/login".equals(servletPath)) {
            doLogin(request, response);
        } else if ("/user/exit".equals(servletPath)) {
            doExit(request, response);
        }


    }

    private void doExit(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取到客户端发送过来的 sessoin
        HttpSession session = request.getSession();

        if (session != null) {
            // 手动销毁 session 对象
            // 注意:会话销毁的了,自然需要重写登录了,没有登录过,无法进行一个路径的访问的
            session.invalidate();


            // 跳转会登录的页面
            response.sendRedirect(request.getContextPath() + "/index.jsp");  // 项目名路径默认就是访问的index.html 的欢迎页面
            // 注意:这里修改了,需要指明index.jsp登录页面了,因为局部优先
        }
    }

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

        // 一个用户登录验证的方式:验证用户名和密码是否正确
        // 获取用户名和密码
        // 前端提交是数据是:username=111&password=fads
        // 注意:post 提交的数据是在请求体当中,而get提交的数据是在请求行当中

        boolean success = false;  // 标识登录成功

        String username = request.getParameter("username");
        String password = request.getParameter("password");

        String exempt = request.getParameter("exempt");

        // 连接数据库验证用户名和密码
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            // 1. 获取连接,注册驱动
            connection = DBUtil.getConnection();

            // 2. 获取操作数据对象,预编译sql语句, ? 占位符不要加,“”,'' 单双引号,成了字符串了,无法识别成占位符了。
            String sql = "select username,password from t_user where username = ? and password = ?";
            preparedStatement = connection.prepareStatement(sql);

            // 3. 填充占位符,真正执行sql语句
            preparedStatement.setString(1, username);
            preparedStatement.setString(2, password);

            resultSet = preparedStatement.executeQuery();

            // 4. 处理查询结果集
            // 只有一条结果集
            if (resultSet.next()) {
                // 登录成功
                success = true;
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            // 5. 关闭资源,最后使用的最先关闭,
            DBUtil.close(connection, preparedStatement, resultSet);
        }


        // 登录成功与否
        // 设置登录成功十天的免登录
        if (success) {
            // 成功,跳转到用户列表页面
            // 这里使用重定向(没有资源的共享):重定向需要加/项目名 +

            // 获取session 对象(这里的要求是: 必须获取到 session ,没有session 也要新建一个 session 对象)
            // 注意:我们下面的这个会话是不能删除的,因为上面我们虽然通过 welcome Servlet 进行了一个会话
            // 但是 welcome 当中是当我们cookie 当中存在并且用户名和密码正确的时候才会进行一个 session 的
            HttpSession session = request.getSession();  // 服务器当中没有 session 会话域自动创建
            session.setAttribute("username", username);  // 将用户名存储到 session 会话域当中

            // 判断用户是否选择了免十天登录的选择
            // 通过创建 Cookie 缓存机制:
            /*
            将登录成功后,将用户名和密码都存储都 Cookie当中(服务器创建 cookie 信息)。客户端接收该cookie信息并存储起来。
            注意:每一个对应的 cookie 信息都需要进行 (new Cookie() , setMaxAge() ,和 setPath() 响应到客户端)
             */
            if ("true".equals(exempt)) {
                // 创建 Cookie 对象存储登录名
                Cookie cookie = new Cookie("username", username);
                // 创建Cookie 对象存储登录密码
                Cookie cookie2 = new Cookie("password", password);

                // 设置 cookie 的有效期为 10 天
                cookie.setMaxAge(60 * 60 * 24 * 10);// 单位时 s 秒
                cookie2.setMaxAge(60 * 60 * 24 * 10);

                // 设置Cookie 关联的path(只要访问时这个应用,这个项目,浏览器一定要携带两个 cookie信息发送给服务器)
                cookie.setPath(request.getContextPath());
                cookie2.setPath(request.getContextPath());  // 动态获取到项目名,的根路径


                // 将服务器生成的 cookie 信息 响应到浏览器端
                response.addCookie(cookie);
                response.addCookie(cookie2);  // 注意是 response 服务器端将 cookie的信息响应到客户端,客户端接收并存储起来
                // session 会话时,服务器创建的 ,客户端发送request  请求获取到该 session 对象的 sessionID

            }

            response.sendRedirect(request.getContextPath() + "/dept/list");
        } else {
            // 失败,跳转到失败页面
            response.sendRedirect(request.getContextPath() + "/error.jsp");
        }


    }
}

  1. 实现用户在 10 天内,用户再次方法该 oa 项目的首页的时候。跳转至列表页面

思路:

  1. 首先获取到 客户端发送过来的所有的 cookie 信息,存储到数组当中,判断该数组是否为 null,
    1. 为 null : 表示客户端没有发送 cookie信息,用户没有勾选 10 天免登录操作。并重定向至用户登录页面
    2. 不为 null: 表示客户端发送了 cookie 信息,用户勾选 10 天免登录操作。
      1. 遍历 cookie 的所有值,获取到 cookie name = username,password (用户名和密码) 的 value 值。
        获取到以后,并判断其中 cookie 存储的 用户名和密码是否正确(连接数据库,查询)。
      2. 用户名和密码正确,重定向至 列表用户页面
      3. 用户名和密码错误,重定向至用户登录页面,重新登录。
      4. 没有 获取到对应 cookie name = username,password (用户名和密码) 的 value 值。说明用户并没有登录成功过,重定向至用户登录页面,重新登录。
  2. 也说明用户并没有登录成功过,重定向至用户登录页面,重新登录。

需要注意点就是:我们仅仅对用户再次访问该 oa 的欢迎页面的时候,才会进行一个 10 天免登录的操作,如果用户访问其他的资源路径的话,是没有一个进行一个 10 天的免登录判断的操作的,如果访问其他资源的路径的话,是需要重新登录的

核心代码:

package com.RainbowSea.servlet;

import com.RainbowSea.DBUtil.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


/**
 * 注意一点就是;我们这里的免十天登录,是访问对应 oa/ 这个登录的欢迎页面,我们web.xml 当中,
 * 只有当oa/根项目的根路径的时候,才可以免10天登录的。其他是无法跳转到免登录的。
 */
@WebServlet("/welcome")
public class Welcome extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {
        // 获取到 客户端发送的 Cookie 信息
        Cookie[] cookies = request.getCookies();

        boolean success = false;

        // 注意如果为客户端没有发送 cookie 信息,返回的是 null ,不是数组为 0
        String userName = null;
        String userPasswrod = null;
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                // Cookie 是一个Map集合类似
                String name = cookie.getName();

                // 获取到Cookie 当中存储的用户名信息
                if ("username".equals(name)) {  // username 服务器创建 Cookie 是的 name key值
                    userName = cookie.getValue();
                } else if ("password".equals(name)) {
                    userPasswrod = cookie.getValue(); // 获取到 Cookie 当中存储用户名密码
                }
            }
        }


        // 判断从 Cookie 当中获取到用户名和密码是否正确
        // 首先判断是获取到该存储到 Cookie 当中的用户名和密码信息,
        // 注意可能用户根本就没有登录过,所以无法获取到是为 null的
        if (userName != null && userPasswrod != null) {
            // 验证用户名和密码是否正确 ,连接数据库
            Connection connection = null;
            PreparedStatement preparedStatement = null;
            ResultSet resultSet = null;

            try {
                // 1. 注册数据库驱动,连接数据库
                connection = DBUtil.getConnection();
                // 2. 获取到操作数据库的对象,预编译SQL语句 sql测试
                // ? 占位符,不要用 "" '' 单双引号括起来,不然就不是占位符了而是字符或字符串了
                String sql = "select * from t_user where username = ? and password = ?";
                preparedStatement = connection.prepareStatement(sql);

                // 3. 填充占位符 执行sql 语句
                preparedStatement.setString(1,userName);
                preparedStatement.setString(2,userPasswrod);
                resultSet = preparedStatement.executeQuery();

                // 4. 处理查询结果集
                if (resultSet.next()) {
                    // 登录成功
                    success = true;

                }
            } catch (SQLException e) {
                throw new RuntimeException(e);
            } finally {
                // 5. 关闭资源:最后使用的最先关闭:
                DBUtil.close(connection, preparedStatement, resultSet);
            }

            if (success) {
                // 存储到cookie当中的用户名和密码正确
                // 获取session ,主要是为了,防止用户没有通过路径就直接访问了。(在DeptServlet 存在一个会话的判断)
                HttpSession session = request.getSession();
                session.setAttribute("username", userName);
                // 重定向到用户列表当中
                response.sendRedirect(request.getContextPath() + "/dept/list");
            } else {   // Cookie 当中存储的用户名和密码错误
                // 跳转到登录页面 (重定向)
                response.sendRedirect(request.getContextPath() + "/index.jsp");
            }

        } else {  // 用户压根就没有登录过,所以Cookie 当中没有数据 更没有存储到用户名和用户的密码
            // 重定向
            response.sendRedirect(request.getContextPath() + "/index.jsp");
        }

    }
}

9. Cookie 的销毁(Cookie 信息失效)的四种方式:

  • 第一种方式:通过浏览器自身的 设置 中手动清除本地 Cookie 信息。如下是 Goole Chrome 浏览器的清除 Cookie 的操作:

在这里插入图片描述

  • 第二种方式:还是通过浏览器自身的设置中禁用 Cookie 的存储机制。需要注意的是:如果禁用了 cookie 的话有可能导致某些网页无法正常运行,具体是是一个怎样的一个效果,在 session 博客一文中我有所提及到的。大家可以移步至:🔜🔜🔜 B/S结构系统的会话机制(session)_ChinaRainbowSea的博客-CSDN博客

在这里插入图片描述

  • 第三种方式:通过 cookie.setMaxAge(0)设置 cookie 的有效器,如果设置为 0 表示,cookie 有效的时间点是:1970年1月1日 0 时0 分 1秒。 现在都是 21 世纪了 , cookie 早就失效了。
  • 第四种方式:如果 Cookie 当中存储了你的用户名和密码的一些重要的信息,你可以通过修改其中用户名和密码,当存储到Cookie 当中的用户名和密码是错误的。无效的。比如:如果你在网吧当中的其中一台电脑,并使用了其中的浏览器登录了京东网站,当你离开的时候,忘记了,将该登录京东的用户退出来,更没有将电脑关机。当你回到家中才发觉你,没有将其中的用户安全退出,那么你为了防止其他人,使用了你网吧登录过京东的电脑,恶意操作你的京东信息。你又不可能重回到网吧,将用户安全退出,那么你就可以使用自家的电脑,登录京东的网站,修改其中的用户名和密码的信息,这样网吧当中的那台记录着你用户名和密码的 Cookie 信息,就是无效的了,因为你修改了密码信息。还有一点就是在这里提醒广大读者,如果你去网吧上网,打游戏,登录过敏感信息,在离开的时候,请一定记住,把你是使用过的电脑关机(关机后,电脑会自动清理其中的一些临时的重要信息),而不是锁屏,网吧中的待机锁屏,其实就是在桌面上使用了一个壁纸替换了,让你看不见,但是当任何一个人再次登录该电脑的时候,就是把壁纸移开了,其中电脑显示的信息还是你使用该电脑的信息。

10. 总结:

  1. Cookie 的作用:cookie和session机制其实都是为了保存会话的状态。

  2. Cookie 是存储在客户端当中的。

  3. session 服务器发送的JSESSIONID 是存储在客户端的 Cookie 当中的。

  4. Cookie 是将会话的状态保存在浏览器客户端上的。注意:cookie 的数据信息是存储在浏览器客户端上的,不是存储在服务器当中的。

    cookie最终是保存在浏览器客户端上的。

    • 可以保存在运行内存中。(浏览器只要关闭cookie就消失了。)
    • 也可以保存在硬盘文件中。(永久保存。)
  5. HTTP Cookie,通常直接叫做cookie,标准要求服务器将Set-Cookie作为响应的一部分,其中包含会话信息,这种服务器响应报文的首部字段可能如下,其中以name为名称、以value为值,这是要求客户端发送name这个键名的cookie值,如下:

    HTTP/1.1 200 OK
    Content-type: Text/html
    Set-Cookie: name=value
    Other-header: other-header-value
    
  6. 重点: 在HTTP协议中是这样规定的:当浏览器发送请求的时候,会自动携带该path下的 cookie数据给服务器(URL),任何以 Cookie 形式存储的值,无论服务器端是否需要,每一个 HTTP 请求都会把这些数据 (cookie 数据)传输到服务器端。 简单的说就是:只有客户端当中的 Cookie 缓存当中存在数据信息(无论是何种信息),无论服务器是否需要,只有是在 cookie 设置的 path(映射路径下)的服务器,都会将其 Cookie 缓存当中的数据信息发送给服务器,没有为什么这是 HTTP协议强制规定的

  7. session 与 Cookie 之间的区别:

  8. Cookie 的配置方法:cookie 的有效时间,cookie 的path 映射/关联路径。

  9. Cookie 的销毁(Cookie 信息失效) 的四种方式。

  10. 结合 Cookie 机制 实现 oa 十天免登录的功能:当用户再次方法该 oa 项目的欢迎页面的时候,可以有一个 10 天免登录的操作。

11. 最后:

限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵——多多益善,谢谢大家,江湖再见,后悔有期

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值