前言
Cookie、Session和Token是面试常考知识点。由于HTTP协议是无状态的,服务器无法判断用户身份,即引入Cookie、Session和Token用来进行身份识别,其中Session还有缓存的作用。本文主要讲述Cookie和Session的联系与区别,为此有必要再回顾Cookie和Session的基础知识。
Cookie
概要
Cookie是服务器通知客户端保存键值对的一种技术。客户端只有了Cookie,把其放入请求头中,每次请求都发送给服务器,并且每个Cookie的大小不超过4kb,其存放的数据类型为字符串。
增改查
创建Cookie
Cookie的创建,先定义一个Cookie对象,接着把其放入response响应中返回给前端即可。
//创建cookie
public String addCookie(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException{
Cookie cookie=new Cookie("key","value");
resp.addCookie(cookie);
return "";
}
获取Cookie
Cookie的获取,request请求头有个getCookies()即可获取全部的cookie信息。
//获取cookie
public String getCookie(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException{
Cookie[] cookies = req.getCookies();
//对cookies进行操作(TODO)
return "";
}
更新Cookie
对于Cookie的更新,有两种方式,第一种方式是创建一个同名的Cookie对象,给它赋新值后加入response响应返回;第二种方式是比较常规的修改思路,先找到对应的cookie后再对其进行修改。
//更新或者设置cookie
public String updateCookie(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException{
//方式一
Cookie cx=new Cookie("key","value1");
resp.addCookie(cx);
//方式二
Cookie[] cookies = req.getCookies();
//对cookies进行操作
Cookie cookie=null;
for (Cookie c:cookies) {
//TODO,找到想要操作的cookie
if ("key".equals(c.getName())){
cookie=c;
break;
}
}
if (cookie!=null) {
cookie.setValue("value1");
resp.addCookie(cookie);
}
return "";
}
生命周期
Cookie的生命周期有三种状态,Cookie的setMaxAge设置为整数,表示在指定的秒数后过期,设置为负数,表示浏览器一关,Cookie 就会被删除,设置为零,表示马上删除Cookie,其中Cookie的默认值为-1。
//设置cookie生命周期
public String cookieLife(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException{
Cookie cookie=new Cookie("life","life");
cookie.setMaxAge(3600);//一个小时之后过期
resp.addCookie(cookie);
return "";
}
有效路径
Cookie 的 path 属性可以有效的过滤哪些 Cookie 可以发送给服务器。哪些不发。path 属性是通过请求的地址来进行有效的过滤。
//设置cookie有效路径
public String cookiePath(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException{
Cookie cookie=new Cookie("path","path");
cookie.setPath( req.getContextPath() + "/book");
resp.addCookie(cookie);
return "";
}
Session
概要
Session,是用来维护一个客户端和服务端之间关联的一种技术。每个客户端都有自己的一个Session会话,这句话很重要,后期在谈Cookie和Session联系的时候有所体现。Session可以存储的数据结构是一个对象。
增改查
创建Session
Session 的创建,使用request的getSession()方法,若是第一次调用,则创建Session会话,若非第一次调用,则获取前面已经创建好的Session会话。
//增加session
public String addSession(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException{
//有则返回,无则创建
HttpSession session = req.getSession();
return "";
}
获取Session
Session 的获取,使用HttpSession类中的getAttribute()方法即可完成操作。
//获取session
public String getSession(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException{
//有则返回,无则创建
HttpSession session = req.getSession();
Object key = session.getAttribute("key");
//TODO,对key对象进行操作
return "";
}
更新Session
Session的更新,使用HttpSession类中的setAttribute()方法即可完成操作。
//更新或者设置session
public String updateSession(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException{
//有则返回,无则创建
HttpSession session = req.getSession();
session.setAttribute("key",new ArrayList<>());
return "";
}
生命周期
Session的生命周期,值为正数的时候,设定 Session 的超时时长,值为负数的时候,表示永不超时。
//session生命周期
public String sessionLife(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException{
//有则返回,无则创建
HttpSession session = req.getSession();
session.setMaxInactiveInterval(3600);//一个小时后过期
return "";
}
两者区别与联系
区别
上述讲解了两者的基础知识,为了方便记忆,使用表格的形式对比其两者的区别。
存放位置 | 占用空间 | 安全性 | 应用场景 | |
---|---|---|---|---|
Cookie | 客户端浏览器 | 小 | 较低 | 一般存放配置信息 |
Session | 服务器 | 大 | 较高 | 存放较为重要的信息 |
联系
Session是通过Cookie实现的,和Cookie不同的是,Session是存在服务端的。当客户端浏览器第一次访问服务器时,服务器会为浏览器创建一个sessionid,将sessionid放到Cookie中,存在客户端浏览器。为了更多的理解上面那句话的作用,举一个课程实验的例子,当某个用户访问一个购物网站,将一本《xxx》的图书放到购物车,购物车的实现方式是使用map集合,再将其放入session对象中,sessionid信息又会存在于Cookie中,当某个用户再次访问服务器时,浏览器会带上Cookie对象放在请求头发送给服务器,服务器就可以取出Cookie中的sessionid,后拿到该用户对应的购物车对象,对其进行操作,达到用户购物车数据的存储。
本文最后,再谈谈有关Cookie和Session的常见问题,如果客户端禁用Cookie,能Session还能使用嘛?
对于这个问题要回答"可以"这个答案,其约束条件还是挺多的,Session的作用是在服务端来保持状态,通过sessionid来进行确认身份,但sessionid一般是通过Cookie来进行传递的,若Cookie被禁用了,那么肯定无法通过Cookie的形式来获取sessionid,这时还可以拿到sessionid的前提条件,一是sessionid已经被提前存储起来,二是服务器的session还在服务时间内(即未过期),这时可以通过在URL地址栏中传递sessionid。
本文若有不足之处,读者可以在评论区谈谈你们的看法。