cookie和session
1、概念
1.1、什么是会话
用户打开浏览器,浏览不同的网页(资源),发出多个请求,直到关闭浏览器的过程,称为一次会话(多次请求). 如同打电话. 我们在会话的过程(多次请求)之中,用户可能会产生一些数据,这些数据话有的需要保存起来的,我们就可以通过会话技术来保存用户各自的数据
1.2、为什么需要会话
保存用户各自(以浏览器为单位)的数据。
1.3、常见会话技术
cookie
cookie是客户端(浏览器)端的技术,用户浏览的信息以键值对(key=value)的形式保存在浏览器上。如果没有关闭浏览器,再次访问服务器,会把cookie带到服务端,服务端就可以做响应的处理。
session
session是服务器端的技术。服务器为每一个浏览器开辟一块内存空间,即session。由于内存空间是每一个浏览器独享的,所有用户在访问的时候,可以把信息保存在session对象中。同时,每一个session对象都对应一个sessionId,服务器把sessionId写到cookie中,再次访问的时候,浏览器会把cookie(sessionId)带过来,找到对应的session对象。
2、Cookie
注意:图片中的红色片段信息
2.1、cookie的应用场景
1.记住用户名
当我们在用户名的输入框中输入完用户名后,浏览器记录用户名,下一次再访问登录页面时,用户名自动填充到用户名的输入框.
2.自动登录(记住用户名和密码)
当用户在淘宝网站登录成功后,浏览器会记录登录成功的用户名和密码,下次再访问该网站时,自动完成登录功能.
以上这些场景都是使用会话cookie实现的,将上次的信息保存到了cookie中,下次直接从cookie中获取数据信息
3.保存网站的上次访问时间
我们访问网站的时候,通常会看到网站上显示上次访问时间,这些信息就是在用户访问网站的时候保存在cookie中的
4.保存电影的播放进度
在网页上播放电影的时候,如果中途退出浏览器了,下载再打开浏览器播放同一部电影的时候,会自动跳转到上次退出时候的进度,因为在播放的时候会将播放进度保存到cookie中
2.2、cookie的API
- 创建一个Cookie对象(cookie只能保存字符串数据。且不能保存中文)
new Cookie(String name,String value);
- 把cookie写回浏览器
response.addCookie(cookie);
- 获得浏览器带过来的所有Cookie:
request.getCookies() ; //得到所有的cookie对象。是一个数组,开发中根据key得到目标cookie
- cookie的 API
cookie.getName() ; //返回cookie中设置的key
cookie.getValue(); //返回cookie中设置的value
对应的案例demo:
//第一次是服务器通过response 响应给客户端
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获得所有的cookie
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
//获得name是akey的cookie对象, 以及它的value
if("akey".equals(cookie.getName())){
System.out.println(cookie.getValue());
}
//获得cookie的name和value
//System.out.println(cookie.getName() + "=" + cookie.getValue());
}
}
//创建Cookie
Cookie aCookie = new Cookie("akey", "aaa");
Cookie bCookie = new Cookie("bkey", "bbb");
//写给浏览器
response.addCookie(aCookie);
response.addCookie(bCookie);
response.getWriter().print("ServletDemo01");
}
2.3、cookie的特点
cookie特点
- Cookie保存在客户端(浏览器端的)
- 第一次请求的时候, 没有Cookie的, 先由服务器写给浏览器.
- Cookie里面只能保存字符串, 大小有限制
- Cookie本质是请求头,响应头
- 在默认的情况下,当浏览器进程结束(浏览器关闭,会话结束)的时候,cookie就会消失。
2.4、cookie持久性
上面提到过,cookie在默认的情况下,在浏览器进程关闭之后,cookie就会消失
那么要想在浏览器进程关闭之后,cookie还要存在,那么应该设置cookie的有效时间。
为了达到的效果就是在浏览器进程关闭之后,再次打开浏览器访问服务器的时候,仍然携带着cookie数据去进行访问服务器,从而服务器拿到对应的信息之后,来获取得到数据。
给cookie设置有效期.
cookie.setMaxAge(int expiry) // 单位是秒
-1:默认。代表Cookie数据存到浏览器关闭(保存在浏览器文件中)。
正整数:以秒为单位保存数据有有效时间(把缓存数据保存到磁盘中)
0:代表删除Cookie.如果要删除Cookie要确保路径一致。
2.5、cookie有效路径
setPath(String url) ; // 设置路径
有效路径作用 :
- 保证不会携带别的网站/项目里面的cookie到我们自己的项目
- 如果路径不一样, cookie的key可以相同
- 保证自己的项目可以合理的利用自己项目的cookie
-
默认路径,例如:
- 访问http://localhost:8080/web18A_Cookie/demo01; cookie默认路径 /web18A_Cookie
-
访问http://localhost:8080/web18A_Cookie/aaa/demo01; cookie默认路径 /web18A_Cookie/aaa
-
访问http://localhost:8080/web18A_Cookie/aaa/bbb/demo01; cookie默认路径 /web18A_Cookie/aaa/bbb
-
随带Cookie需要的条件: 只有当访问资源的url包含此cookie的有效path的时候,才会携带这个cookie;反之不会.
-
eg: 设置cookie的路径 /demo02
下次访问路径:http://localhost:8080/day30a-cookie/demo02/ccc; cookie是可以带过来
下次访问路径:http://localhost:8080/day30a-cookie/demo03; cookie带不过来
-
-
cookie的路径通常设置 / 或者 /发布项目名设置的有效是 /day30a-cookie. 当前项目下的Servlet都可以使用该cookie. 一般这么设置: cookie.setPath(request.getContextPath());
只要是当前项目里面的资源 路径必须包含项目名路径.
2.6、cookie弊端
1、cookie的弊端 cookie的大小(个数和自身大小)和格式(只能存字符串)有限制;
2、默认不支持中文,解决中文办法;
URLEncode.encode(value,"utf-8");//存入的时候(先通过utf-8编码)URLDecode.decode(value,"utf-8");//取出 (通过utf-8解码)
2.7、记录用户上次的访问时间
对应的案例如下所示:
/** * 用来记录用户上次的访问时间 */@WebServlet(name = "LastLoginServlet", value = "/LastLoginServlet")public class LastLoginServlet extends HttpServlet { private static final String LASTLOGIN = "lastLogin"; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie[] cookies = request.getCookies(); Cookie targetCookie = CookieUtil.getTargetCookie(cookies, LASTLOGIN); response.setContentType("text/html;charset=UTF-8"); if (Objects.isNull(targetCookie)){ response.getWriter().println("您是第一次登录!"); }else { String value = targetCookie.getValue(); Date date = new Date(Long.parseLong(value)); String toLocaleString = date.toLocaleString(); response.getWriter().println("您上次的登录时间为:"+toLocaleString); } // 时间不能每次都不回去变化,下次登录的时候一定要发生变化,所以在这里来进行设置即可 Cookie cookie = new Cookie(LASTLOGIN,String.valueOf(System.currentTimeMillis())); // 设置cookie的路径和时间 cookie.setMaxAge(60*60*24); cookie.setPath(request.getContextPath()); response.addCookie(cookie); }}
上面需要使用到一个工具类:
public class CookieUtil { public static Cookie getTargetCookie(Cookie[] cookies, String cookiekey) { Objects.requireNonNull(cookiekey, "cookie的key为null"); if (Objects.isNull(cookies)) { return null; } for (Cookie cookie : cookies) { String name = cookie.getName(); if (cookiekey.equals(name)) { return cookie; } } return null; }}
3、session
3.1、简单概念
session是服务器端的技术。服务器为每一个浏览器开辟一块内存空间,即session对象。由于session对象是每一个浏览器特有的,所有用户的记录可以存放在session对象中。同时,每一个session对象都对应一个sessionId,服务器把sessionId写到cookie中,再次访问的时候,浏览器把sessionId带过来,找到对应的session对象
3.2、session和cookie的不同
- cookie是保存在浏览器端的,大小和个数都有限制。session是保存在服务器端的, 原则上大小是没有限制(实际开发里面也不会存很大大小), 安全一些。
- cookie不支持中文,并且只能存储字符串;session可以存储基本数据类型,集合,对象等
3.3、session的执行原理
1、获得浏览器端发送过来的cookie,从cookie中获取得到SessionId(cookie);
2、如果Cookie中没有sessionid,则创建session对象;
3、如果Cookie中有sessionid,找指定的session对象;
如果有sessionid并且session对象存在,则直接使用;
如果有sessionid,但session对象销毁了,则执行第二步;
那么来画个图表示:
3.4、session特点
- session是服务器端的技术, 数据保存在服务器端的
- 只有在服务器端调用了requet.getSession()的时候, 才有session产生
- session基于cookie的
- 创建session的同时 生成sessionId, 服务器自动通过Cookie的方式写给浏览器, 浏览器自己保存
- 下次的话 浏览器携带cookie(SessionId)找到对应的session使用了
3.5、sessionAPI
范围: 会话(多次请求)保存用户各自的数据(以浏览器为单位)
-
Session基本使用: 作为域对象存取数据 范围: 一次会话(多次请求, 用户各自的) 不同的浏览器session不一样
-
Object getAttribute(String name) ;获取值
-
void setAttribute(String name, Object value) ;存储值
-
void removeAttribute(String name) ;移除
-
-
浏览器关闭了, session使用不了, 是session销毁了吗?
session没有销毁.
session基于cookie, sessionId保存到cookie里面的, 默认情况下cookie是会话级别,浏览器关闭了cookie就是消失了,也就是说sessionId消失了, 从而找不到对应的session对象了, 就不能使用了.
解决: 自己获得sessionId, 自己写给浏览器 设置Cookie的有效时长, 这个Cookie的key必须:
JSESSIONID
-
session的默认有效期是30分钟,调用invalidate()方法/服务器异常关闭
-
如果是正常关闭服务器,把session钝化到服务器磁盘上,再次启动,把磁盘上的文件活化到内存里面,Session钝化:把内存中的session序列化到硬盘上,Session活化:从硬盘上读取序列化的session到内存中
3.6、使用
经常将用户数据保存到session中,然后利用从session中获取得到有用的数据。
因为可以存放集合、对象等数据,使用起来比较方便。
来举一个例子说明:
@WebServlet(name = "SessionServlet", value = "/SessionServlet")
public class SessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
Object hello = session.getAttribute("hello");
if (Objects.nonNull(hello)){
System.out.println(hello);
}else {
List<String> stringList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
stringList.add(String.valueOf(i));
}
session.setAttribute("hello",stringList);
}
}
}
当第一次来进行访问的时候,客户端的cookie没有对应的sessionid,那么首先会在服务器端新建一个session对象,然后将sessionid存入到cookie中,在响应的时候会将cookie响应给客户端,session是会话技术,肯定会来存入数据。那么以浏览器为单位,session的唯一标识就是浏览器携带的sessionid,每个浏览器都有一个sessionid,然后会从服务器端获取之前存入的数据。
当浏览器未关闭时,再次发起请求,浏览器会携带sessionid向浏览器发起请求,在服务端接收到了之后,可以拿到对应的数据来进行操作。
3.7、综合案例
看一下这里的使用方式:
@WebServlet(name = "DotFogetServlet", value = "/DotFogetServlet")
public class DotFogetServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//0.处理乱码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//1.获得用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//2.使用DBUtils根据用户名和密码查询数据库 封装成User对象
QueryRunner queryRunner = new QueryRunner(C3p0Util.getDataSource());
String sql = "SELECT * FROM t_user WHERE username = ? AND password =?";
User02 user = queryRunner.query(sql, new BeanHandler<User02>(User02.class), username, password);
//3.判断是否登录成功(判断User是否为null)
if (user != null){
//3.1 user!= null 响应登录成功
//****************记住用户名*********************
//判断用户是否勾选了记住用户名
String rem = request.getParameter("check");
if(rem != null && "checked".equals(rem)){
//勾选了, 把用户名存到Cookie
Cookie cookie = new Cookie("username", username);
cookie.setMaxAge(60*60*24*7);
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
}else {
//没有勾选 删除cookie
Cookie cookie = new Cookie("username", "");
cookie.setMaxAge(0);
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
}
//***********************************************
//把user保存到session里面
request.getSession().setAttribute("user",user);
//重定向到首页
response.sendRedirect(request.getContextPath()+"/index.html");
}else{
//3.2 user== null 响应登录失败
response.getWriter().print("登录失败!");
}
} catch (Exception e) {
e.printStackTrace();
response.getWriter().print("登录失败!");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
这里有两个注意的点:
1、
Cookie cookie = new Cookie("username", username);
cookie.setMaxAge(60*60*24*7);
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
设置cookie持久化时间,在浏览器进程关闭之后,再次访问相同路径的时候(这里是在整个项目下都可以使用这个cookie,因为路径是是整个项目路径),浏览器会从本地系统中来加载文件获取得到cookie信息,携带至客户端,客户端根据cookie携带的sessionid,来获取得到用户在客户端保存的数据。
2、
//没有勾选 删除cookie
Cookie cookie = new Cookie("username", "");
cookie.setMaxAge(0);
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
在退出的时候,删除掉cookie,因为设置的cookie的时间是0,又是相同路径,表示的是来对cookie来进行删除。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~