JavaEE Cookie的基本使用细节

 更新时间:2022年12月08日 09:41:12   作者:-BoBooY-  
本章我们将学习会话跟踪技术中的Cookie与Session,它在我们整个JavaEE的知识体系中是非常重要的,本节我们先介绍Cookie,废话不多说,直接上正文

1、会话跟踪技术

1.1、概述

会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。

从浏览器发出请求到服务端响应数据给前端之后,一次会话(在浏览器和服务器之间)就被建立了

会话被建立后,如果浏览器或服务端都没有被关闭,则会话就会持续建立着

浏览器和服务器就可以继续使用该会话进行请求发送和响应,上述的整个过程就被称之为会话。

会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。

服务器会收到多个请求,这多个请求可能来自多个浏览器,如上图中的6个请求来自3个浏览器

服务器需要用来识别请求是否来自同一个浏览器

服务器用来识别浏览器的过程,这个过程就是会话跟踪

服务器识别浏览器后就可以在同一个会话中多次请求之间来共享数据

问:为什么一个会话中的多次请求要共享数据?有了这个数据共享功能后能实现哪些功能?

答:

  • 购物车,在选完商品加入购物车后,当点击去结算时显示之前加入购物车的商品信息时就需要用到共享数据;
  • 登录,登录后展示个人信息;
  • 登录页面 ” 记住我 “,在第一次登陆成功后,下次登录会自动填充账号和密码
  • 登录页面的验证码功能,生成验证码和输入验证码点击注册这也是两次请求,这两次请求的数据之间要进行对比

问:为什么现在浏览器和服务器不支持数据共享呢

答:

  • 浏览器和服务器之间使用的是HTTP请求来进行数据传输
  • HTTP协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求
  • HTTP协议设计成无状态的目的是让每次请求之间相互独立,互不影响
  • 请求与请求之间独立后,就无法实现多次请求之间的数据共享

1.2、实现方式

会话跟踪技术的实现方式有:Cookie(客户端会话跟踪技术)、Session(服务端会话跟踪技术)

两者之间的区别:Cookie是存储在浏览器端而Session是存储在服务器端

2、Cookie

2.1、Cookie的基本使用

2.1.1、概念

Cookie:客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问。

2.1.2、Cookie的工作流程

  • 服务端提供了两个Servlet,分别是ServletA和ServletB
  • 浏览器发送HTTP请求1给服务端,服务端ServletA接收请求并进行业务处理
  • 服务端ServletA在处理的过程中可以创建一个Cookie对象并将name=zs的数据存入Cookie
  • 服务端ServletA在响应数据的时候,会把Cookie对象响应给浏览器
  • 浏览器接收到响应数据,会把Cookie对象中的数据存储在浏览器内存中,此时浏览器和服务端就建立了一次会话
  • 在同一次会话中浏览器再次发送HTTP请求2给服务端ServletB,浏览器会携带Cookie对象中的所有数据
  • ServletB接收到请求和数据后,就可以获取到存储在Cookie对象中的数据,这样同一个会话中的多次请求之间就实现了数据共享

2.1.3、Cookie的基本使用

对于Cookie的使用,我们更关注的应该是后台代码如何操作Cookie,对于Cookie的操作主要分两大类,本别是发送Cookie和获取Cookie,对于上面这两块内容,分别该如何实现呢?

1)发送Cookie

创建Cookie对象,并设置数据

Cookie cookie = new Cookie("key","value");

发送Cookie到客户端:使用response对象

response.addCookie(cookie);

《Cookie发送案例》 创建Maven项目cookie-demo,并在pom.xml添加依赖

<!--servlet-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
<!--jsp-->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
</dependency>
<!--jstl-->
<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>

编写Servlet类,名称为AServlet,并在Servlet中创建Cookie对象,存入数据,发送给前端

package com.bby;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/aServlet")
public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //发送Cookie
        //1.创建Cookie对象
        Cookie cookie = new Cookie("username", "bby");
        //2.发送Cookie,response
        response.addCookie(cookie);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request,response);
    }
}

配置Tomcat

启动项目测试,浏览器查看Cookie的值

访问http://localhost:8080/aServlet

方式一:浏览器设置中查看,此处使用 Edge浏览器查看(新版火狐和谷歌浏览器都不能查看具体信息)

方式二:浏览器(此处以谷歌浏览器为例)中按下 F12

2)获取Cookie

获取客户端携带的所有Cookie,使用request对象

Cookie[] cookies = request.getCookies();

遍历数组,获取每一个Cookie对象

使用Cookie对象方法获取数据

for(Cookie cookie : cookies) {
    cookie.getName();
    cookie.getValue();
}

《Cookie获取案例》 编写一个新Servlet类,名称为BServlet

package com.bby;
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;
@WebServlet("/bServlet")
public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取Cookie
        //1. 获取Cookie数组
        Cookie[] cookies = req.getCookies();
        //2. 遍历数组
        for (Cookie cookie : cookies) {
            //3. 获取数据
            String name = cookie.getName();
            if (name.equals("username")) {
                String value = cookie.getValue();
                System.out.println(name + ":" + value);
            }
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

启动项目测试

2.2、Cookie的原理分析

对于Cookie的实现原理是基于HTTP协议的,其中设计到HTTP协议中的两个请求头信息:

  • 响应头:set-cookie
  • 请求头:cookie

  • 前面的案例中已经能够实现,AServlet给前端发送Cookie,BServlet从request中获取Cookie的功能
  • 对于AServlet响应数据的时候,Tomcat服务器都是基于HTTP协议来响应数据
  • 当Tomcat发现后端要返回的是一个Cookie对象之后,Tomcat就会在响应头中添加一行数据Set-Cookie:username=zs
  • 浏览器获取到响应结果后,从响应头中就可以获取到Set-Cookie对应值username=zs,并将数据存储在浏览器的内存中
  • 浏览器再次发送请求给BServlet的时候,浏览器会自动在请求头中添加Cookie: username=zs发送给服务端BServlet
  • Request对象会把请求头中cookie对应的值封装成一个个Cookie对象,最终形成一个数组
  • BServlet通过Request对象获取到Cookie[]后,就可以从中获取自己需要的数据

《验证上述结论》

访问http://localhost:8080/bServlet

从响应头获取到Set-Cookie对应值username=bby

访问http://localhost:8080/bServlet

向请求头中添加Cookie: username=bby

2.3、Cookie的使用细节

在使用Cookie时我们要注意两点:第一个是Cookie的存活时间,第二个是Cookie如何存储中文

2.3.1、Cookie的存活时间

思考:当我们关闭浏览器后再重新打开,AServlet响应存有的username=bby的Cookie对象给浏览器还存在吗?

结论:不存在,当我们关闭浏览器后再通过BServlet访问这个Cookie对象时就获取不到了

原因:默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁

《实际案例分析》 分析

当我们登录的时候在账号和密码下方有一个“记住我”的按钮,这个功能就相当于第一次输入用户名和密码并勾选后进行登录,下次再登陆的时候,用户名和密码就会被自动填充,不需要再重新输入登录。但是我们要是使用默认的Cookie,浏览器一关,Cookie就会从浏览器内存中被删除,这个功能就无法实现了

如何将Cookie持久化存储?

Cookie其实已经为我们提供好了对应的API来完成这件事,这个API就是setMaxAge

设置Cookie存活时间

setMaxAge(int seconds)

参数值为:

1.正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除

2.负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁

3.零:删除对应Cookie

《案例:设置Cookie存活时间》 编写Servlet

package com.bby;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/aServlet")
public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //发送Cookie
        //1.创建Cookie对象
        Cookie cookie = new Cookie("username", "bby");
        cookie.setMaxAge(7*24*60*60); //7天,这样写便于阅读
        //cookie.setMaxAge(604800); //不易阅读(可以使用注解弥补),程序少进行一次计算
        //2.发送Cookie,response
        response.addCookie(cookie);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request,response);
    }
}

运行项目测试

先访问一次http://localhost:8080/aServlet,然后关闭浏览器并重启,访问http://localhost:8080/bServlet,能在控制台打印出username:bby,说明Cookie没有随着浏览器关闭而被销毁

可以看到Cookie的创建时间与到期时间相差一周,如下图

2.3.2、Cookie存储中文

Cookie直接存储中文会发生什么?

修改代码

运行测试

结论:Cookie不能直接存储中文

解决方式:先对中文进行URL编码,采用URLEncoder.encode(),将编码后的值存入Cookie中,再将获取到的值进行解码

编码

String value = "啵啵鱼";
//对中文进行URL编码
value = URLEncoder.encode(value, "UTF-8");
//将编码后的值存入Cookie中
Cookie cookie = new Cookie("username",value);

解码

//将获取的Cookie值进行解码
//URL解码
value = URLDecoder.decode(value,"UTF-8");

这样,我们就可以将中文存入Cookie中进行使用。

下节我们讲解Session

到此这篇关于JavaEE Cookie的基本使用细节的文章就介绍到这了,更多相关Java Cookie内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中使用ConcurrentHashMap实现线程安全的Map

    Java中使用ConcurrentHashMap实现线程安全的Map

    在Java中,ConcurrentHashMap是一种线程安全的哈希表,可用于实现多线程环境下的Map操作。它支持高并发的读写操作,通过分段锁的方式实现线程安全,同时提供了一些高级功能,比如迭代器弱一致性和批量操作等。ConcurrentHashMap在高并发场景中具有重要的应用价值
    2023-04-04
  • maven如何使用profiles多环境配置

    maven如何使用profiles多环境配置

    在软件开发过程中,我们经常需要在不同的环境中部署和运行我们的应用程序,例如开发环境、测试环境和生产环境,为了方便管理和配置不同环境下的参数,我们可以使用Maven的profiles功能,本文给大家介绍maven如何使用profiles多环境配置,感兴趣的的朋友一起看看吧
    2024-02-02
  • Maven项目报错:“ SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder”的解决方案

    Maven项目报错:“ SLF4J: Failed to load class “org.slf4j.imp

    这篇文章主要给大家介绍了关于Maven项目报错:“ SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder ”的解决方案,文中给出详细的解决思路与方法,需要的朋友可以参考下
    2022-03-03
  • Spring Cloud Alibaba Nacos 入门详解

    Spring Cloud Alibaba Nacos 入门详解

    这篇文章主要介绍了Spring Cloud Alibaba Nacos入门详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03
  • springboot集成camunda的实现示例

    springboot集成camunda的实现示例

    本文主要介绍了springboot集成camunda的实现示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 手动部署java项目到k8s中的实现

    手动部署java项目到k8s中的实现

    本文主要介绍了手动部署java项目到k8s中的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • des加密解密JAVA与.NET互通实例

    des加密解密JAVA与.NET互通实例

    这篇文章主要介绍了des加密解密JAVA与.NET互通实例,大家参考使用吧
    2013-12-12
  • spring-boot通过@Scheduled配置定时任务及定时任务@Scheduled注解的方法

    spring-boot通过@Scheduled配置定时任务及定时任务@Scheduled注解的方法

    这篇文章主要介绍了spring-boot通过@Scheduled配置定时任务,文中还给大家介绍了springboot 定时任务@Scheduled注解的方法,需要的朋友可以参考下
    2017-11-11
  • Java实现直接插入排序与折半插入排序的示例详解

    Java实现直接插入排序与折半插入排序的示例详解

    这篇文章主要为大家详细介绍了插入排序中两个常见的排序:直接插入排序与折半插入排序。本文用Java语言实现了这两个排序算法,感兴趣的可以学习一下
    2022-06-06
  • Java如何获取真实请求IP

    Java如何获取真实请求IP

    这篇文章主要介绍了Java如何获取真实请求IP问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08

最新评论