博主简介:
Java领域新星创作者
阿里云开发者社区专家博主、星级博主、技术博主
交流社区:BoBooY(优质编程学习笔记社区)
前言:本章我们将学习会话跟踪技术中的Cookie与Session,它在我们整个JavaEE的知识体系中是非常重要的,本节我们先介绍Cookie,废话不多说,直接上正文!
文章目录
- 1、会话跟踪技术
- 1.1、概述
- 1.2、实现方式
- 2、Cookie
- 2.1、Cookie的基本使用
- 2.1.1、概念
- 2.1.2、Cookie的工作流程
- 2.1.3、Cookie的基本使用
- 2.2、Cookie的原理分析
- 2.3、Cookie的使用细节
- 2.3.1、Cookie的存活时间
- 2.3.2、Cookie存储中文
从浏览器发出请求到服务端响应数据给前端之后,一次会话(在浏览器和服务器之间)就被建立了
会话被建立后,如果浏览器或服务端都没有被关闭,则会话就会持续建立着
浏览器和服务器就可以继续使用该会话进行请求发送和响应,上述的整个过程就被称之为会话。
服务器会收到多个请求,这多个请求可能来自多个浏览器,如上图中的6个请求来自3个浏览器
服务器需要用来识别请求是否来自同一个浏览器
服务器用来识别浏览器的过程,这个过程就是会话跟踪
服务器识别浏览器后就可以在同一个会话中多次请求之间来共享数据
问:为什么一个会话中的多次请求要共享数据?有了这个数据共享功能后能实现哪些功能?
答:
- 购物车,在选完商品加入购物车后,当点击去结算时显示之前加入购物车的商品信息时就需要用到共享数据;
- 登录,登录后展示个人信息;
- 登录页面 ” 记住我 “,在第一次登陆成功后,下次登录会自动填充账号和密码
- 登录页面的验证码功能,生成验证码和输入验证码点击注册这也是两次请求,这两次请求的数据之间要进行对比
问:为什么现在浏览器和服务器不支持数据共享呢
答:
- 浏览器和服务器之间使用的是HTTP请求来进行数据传输
- HTTP协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求
- HTTP协议设计成无状态的目的是让每次请求之间相互独立,互不影响
- 请求与请求之间独立后,就无法实现多次请求之间的数据共享
会话跟踪技术的实现方式有:Cookie(客户端会话跟踪技术)、Session(服务端会话跟踪技术)
两者之间的区别:Cookie是存储在浏览器端而Session是存储在服务器端
Cookie:客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问。
name=zs
的数据存入Cookie对于Cookie的使用,我们更关注的应该是后台代码如何操作Cookie,对于Cookie的操作主要分两大类,本别是发送Cookie和获取Cookie,对于上面这两块内容,分别该如何实现呢?
1)发送Cookie
Cookie cookie = new Cookie("key","value");
response.addCookie(cookie);
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>jsp-apiartifactId>
<version>2.2version>
<scope>providedscope>
dependency>
<dependency>
<groupId>jstlgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>taglibsgroupId>
<artifactId>standardartifactId>
<version>1.1.2version>
dependency>
package com.bby; /**
* @author BoBooY
* @date 2022/11/5 15:21
*/
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);
}
}
访问http://localhost:8080/aServlet
方式一:浏览器设置中查看,此处使用 Edge浏览器查看(新版火狐和谷歌浏览器都不能查看具体信息)
2)获取Cookie
Cookie[] cookies = request.getCookies();
for(Cookie cookie : cookies) {
cookie.getName();
cookie.getValue();
}
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;
/**
* @author BoBooY
* @date 2022/11/5 16:02
*/
@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);
}
}
对于Cookie的实现原理是基于HTTP协议的,其中设计到HTTP协议中的两个请求头信息:
Set-Cookie:username=zs
Set-Cookie
对应值username=zs
,并将数据存储在浏览器的内存中Cookie: username=zs
发送给服务端BServlethttp://localhost:8080/bServlet
从响应头获取到Set-Cookie
对应值username=bby
http://localhost:8080/bServlet
向请求头中添加Cookie: username=bby
在使用Cookie时我们要注意两点:第一个是Cookie的存活时间,第二个是Cookie如何存储中文
思考:当我们关闭浏览器后再重新打开,AServlet响应存有的
username=bby
的Cookie对象给浏览器还存在吗?结论:不存在,当我们关闭浏览器后再通过BServlet访问这个Cookie对象时就获取不到了
原因:默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁
当我们登录的时候在账号和密码下方有一个“记住我”的按钮,这个功能就相当于第一次输入用户名和密码并勾选后进行登录,下次再登陆的时候,用户名和密码就会被自动填充,不需要再重新输入登录。但是我们要是使用默认的Cookie,浏览器一关,Cookie就会从浏览器内存中被删除,这个功能就无法实现了
Cookie其实已经为我们提供好了对应的API来完成这件事,这个API就是setMaxAge
setMaxAge(int seconds)
参数值为:
1.正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
2.负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁
3.零:删除对应Cookie
Servlet
package com.bby;
/**
* @author BoBooY
* @date 2022/11/5 15:21
*/
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的创建时间与到期时间相差一周,如下图
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,To be continued…
尾言:创作不易,如果本文的内容对您有帮助,还望客官可以三连支持一下博主,(点赞)+✏️(评论)+⭐️(收藏)是我创作的巨大动力!