「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」
前景知识
会话:用户打开一个浏览器,点了很多超链接,访问了多个web资源,这个过程可称为会话
有状态会话:用户访问了一个web资源,下次再访问的时候,web资源知道用户曾经访问过,称为有状态会话
保存会话的两种技术:
- Cookie:客户端第一次访问服务端到时候,服务端给客户端一个信件,下次再访问的时候带上信件就可以了(客户端技术)
- Seesion:客户端第一次访问服务端到时候,服务端给客户端做好登记,下次由服务端来匹配客户端是否来过(服务端技术)
Cookie概述
Cookie是一个==保存在客户机==中的简单的文本文件, 这个文件与特定的 Web资源关联在一起, 保存了该客户机访问这个Web 资源时的信息, 当客户机再次访问这个 Web 资源时这些信息可供该文档使用。
Cookie 以名(键)/值对形式存储
Cookie 的作用就是用于解决 "如何记录客户端的用户信息":
- 当用户访问 web 页面时,他的名字或其他信息可以记录在 cookie 中。
- 在用户下一次访问该页面时,可以在 cookie 中读取用户访问记录。
一个cookie只能存放一个信息
一个Web站点可以给浏览器发送多个cookie,最多20个
浏览器存放cookie的上限为300
cookie大小限制为4kb
Cookie在客户机存放的路径:
Cookie常用的方法
Cookie[] cookies = req.getCookies();//获取Cookie
cookie.getName()//获得Cookie的键
cookie.getValue()//获得Cookie的值
new Cookie("lastLoginTime", System.currentTimeMillis()+"");//新建一个cookie
cookie.setMaxAge(24*60*60);//设置cookie的保存时间为一天
resp.addCookie(cookie);//响应给客户端一个Cookie
Cookie认证过程
Cookie的认证过程,主要由以下三个阶段组成:
(1)发布Cookie。当用户试图访问某Web站点中需要认证的资源时,Web服务器会检查用户是否提供了认证Cookie,如果没有,则将用户重定向到登录页面。在用户成功登录后,Web服务器会产生认证Cookie,并通过HTTP响应中的Set-Cookie头发送给客户端,用于对用户随后的请求进行检查和验证,接着将用户重定向到初始请求的资源 [5] 。
(2)检索Cookie。在用户随后的访问请求中,客户端浏览器检索Path和Domain等属性与用户请求资源相匹配的Cookie,并将找到的Cookie通过HTTP请求中的Cookie头提交给Web服务器 。
(3)验证Cookie。Web服务器提取客户端浏览器递交的Cookie,验证其中的访问令牌。若合法,则将访问请求的资源发送给客户端浏览器;反之则拒绝用户的访问请求。
Cookie 认证技术简化了用户访问 Web 网站资源的过程,即用户只需在初次登录网站时输入身份信息进行认证,随后便可以访问被授权的所有站点资源,不再需要重复手工提交身份信息 。
获取Cookie
测试:用Cookie保存用户上一次访问的时间
实现原理:服务器告诉浏览器你访问我的时间,我把这个时间封装成一个“信件”,下次浏览器再次访问的时候,在请求里放入这个信件,服务端收到后,在响应里面把新的时间再封装成一个“信件”返回给浏览器。
package com.cheng.cookie;
import com.sun.xml.internal.bind.v2.model.util.ArrayInfoUtil;
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;
import java.io.PrintWriter;
import java.util.Date;
public class CookieDemon01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=utf-8");
req.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
//服务器端从客户端的请求中获取Cookie
Cookie[] cookies = req.getCookies();
//判断Cookie是否存在
if (cookies!=null){
//如果Cookie存在
out.write("您上次访问的时间是");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];//通过for循环取出每一个cookie
//获得Cookie的名字,判断当和第一次的Cookie的键(名)相等时
if (cookie.getName().equals("lastLoginTime")){
//获取出cookie的值,因为值为String类型,我们要把它变为Date类型
long parseLong = Long.parseLong(cookie.getValue());//先转化为时间戳
Date date = new Date(parseLong);//再把时间戳转化为date
out.print(date.toLocaleString());
}
}
}else{//如果Cookie不存在,则说明是第一次访问
out.write("这是您第一次访问本网站");
}
//客户端第一次访问,服务端给客户端响应一个cookies
// 键 值(时间)
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");//String类型
cookie.setMaxAge(24*60*60);//设置cookie的保存时间为一天
resp.addCookie(cookie);//把cookie放入响应,返回给客户端
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
注册Servlet
<servlet>
<servlet-name>CookieDemon01</servlet-name>
<servlet-class>com.cheng.cookie.CookieDemon01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieDemon01</servlet-name>
<url-pattern>/coo1</url-pattern>
</servlet-mapping>
启动Tomcat测试
刷新一次
如图所示:第一次访问的请求时间为1612931362528,响应时间为1612931394676
刷新一次后:请求时间1612931394676,响应时间为1612931452498 ==所以第二次请求里包含了上次服务器响应给浏览器的时间==
证明了实现原理:服务器告诉浏览器你访问我的时间,我把这个时间封装成一个“信件”,下次浏览器再次访问的时候,在请求里放入这个信件,服务端收到后,在响应里面把新的时间再封装成一个“信件”返回给浏览器。
删除Cookie
1.不设置有效期,关闭浏览器,cookie自动失效
2.设置有效期时间为0
//创建一个cookie,名字必须和要删除的cookie名一样
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
cookie.setMaxAge(0);//设置有效期时间为0
resp.addCookie(cookie);