一.Cookie简介
-
Cookie的作用
想象一个场景,假如我们在浏览器中登陆过一次bilibili,在我们下次打开bilibili想要登陆时,浏览器会自动保存你之前登陆过的账号。
cookie就是实现这种功能的技术,当我们使用浏览器与服务器进行会话时会不可避免的产生一些数据,而服务器端想要浏览器保存这些数据,这些数据就是以cookie的形式保存,在我们下次访问该Web资源时服务器可以读取存储在浏览器中的cookie,进行相关操作
cookie保存在浏览器端 -
Cookie的存储结构
cookie是以一对键值对的方式进行存储key和value都是字符串类型,cookie存放的数据大小是有限制的(大约几kb)所以该数据适用于存放较小的数据
二.Cookie的基本理解
服务器创建cookie后以HTTP响应的方式发送给浏览器,浏览器就会保存该cookie,此后每一次访问该服务器的相关资源时,浏览器都会以HTTP请求的方式携带该cookie,直到该cookie被销毁
三.Cookie的基本使用
- 创建Cookie(在服务器端)
Cookie cookie = new Cookie("username", "root");
cookie是以字符串键值对的方式进行初始化的
- 发送Cookie
cookie是在服务器端创建但希望在浏览器端保存,所以我们就要以HTTP响应的方式发送给浏览器
response.addCookie(cookie);
我们可以通过抓包来验证
我们可以发现在响应头中Set-Cookie这一字段就是通知浏览器保存该cookie
- 读取cookie
当浏览器保存了cookie后,每次再向访问Web资源时服务器发送的HTTP请求头中都会携带与该Web路径匹配的cookie
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
System.out.println(cookie.getName() + " " + cookie.getValue());
}
这时服务器就会以cookie数组的方式得到该浏览器携带过来的cookie,服务器就可以对这些数据进行操作后,响应浏览器
- 修改cookie
修改cookie和Hashmap底层原理类似,cookie的key不能重复,只会做value的替换,当我们做如下操作
Cookie cookie = new Cookie("username", "jbc");
response.addCookie(cookie);
通过抓包
可知一个浏览器对应服务器的cookie key是唯一的,修改时只是做value的替换
- 删除cookie
通过设置cookie的MaxAge为0来通知浏览器销毁该cookie,在下次浏览器发送HTTP请求后就不会携带该cookie
Cookie cookie = new Cookie("username","jbcshibaba");
cookie.setMaxAge(0);
response.addCookie(cookie);
四.Cookie的生命周期
cookie的生命周期是指在cookie浏览器端保存的时间,我们可以在创建cookie调用setMaxAge(int)的方法设置cookie的生命周期
- 默认值为-1即关闭浏览器时cookie才会被销毁
- 正数为在浏览器端保存的时间(以秒为单位)
- 0为通知浏览器立即销毁该cookie
Cookie cookie = new Cookie("cookie", "myCookie");
cookie.setMaxAge(60);
response.addCookie(cookie);
上述代码解释:
在60秒内服务器仍能读取到该cookie,即浏览器HTTP请求体中仍会携带该cookie,生命周期结束后,服务器就读取不到该cookie,即浏览器发送的HTTP请求体中就不会携带该cookie,但是要注意的是浏览器端可能还持有该cookie数据
抓包分析
在cookie的生命周期内浏览器发送的HTTP请求仍持有该cookie
生命周期结束后HTTP请求就不再携带该cookie但需要注意的是此时浏览器内存中仍保存此cookie
五.Cookie的有效路径
- cookie的有效路径起到一种过滤作用
我们可以通过设置有效路径来选择让浏览器携带哪些cookie到服务器,哪些不发到服务器,这个需求可以通过设置cookie的path属性来实现
假设我们的工程路径(application context)为/cookie
设置两个cookie路径
- cookie1.setPath = /cookie
- cookie2.setPath = /cookie/aaa
请求地址http://ip:port/cookie/资源
- cookie1发给服务器
- cookie2不会发给服务器
请求地址http://ip:port/cookie/aaa/资源
- cookie1会发给服务器
- cookie2会发给服务器
六.cookie注意事项
- 一个cookie只能标识一直信息,即一个key对应一个value
- 每个域名的cookie数量,和cookie存储数据的大小是有限制的,每个浏览器情况不同,所以cookie不适宜存放较大的数据
- 删除cookie时path必须一致
- 设置cookie时尽量不要使用中文会产生乱码,若必须使用,可以通过UrlEncoder进行编码通过UrlDecoder进行解码
七.Cookie简单应用实例
这里我们举一个简单的例子来加深对cookie的理解
1.如果用户名是 jbcshibaba, 密码是 123456, 则认为该用户合法, 登录成功,否则登录失败
2.如果登录成功,则该用户,在 3 天内登录,可以自动填写其登录名(不关闭此浏览器)
3.还没有学jsp只能用servlet静态返回(原谅我太菜)
LoginCheck该servlet用于用户的校验工作,如果登陆成功就会创建一个cookie,响应给浏览器,让浏览器进行保存
package login;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "LoginCheck", value = "/lc")
public class LoginCheck extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//得到HTTP请求的参数
String username = request.getParameter("username");
String pwd = request.getParameter("pwd");
//对用户名和密码进行校验
if ("jbcshibaba".equals(username) && "123456".equals(pwd)) {
//校验成功就会返回该存放用户名的cookie返回给浏览器
Cookie cookie = new Cookie("username", "jbcshibaba");
cookie.setMaxAge(3600 * 24 * 3);
response.addCookie(cookie);
//并显示登陆成功
request.getRequestDispatcher("/success.html").forward(request, response);
} else {
//登陆失败返回静态页面显示
request.getRequestDispatcher("/error.html").forward(request, response);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
ReturnUI(我是渣渣,还不会动态页面,只能返回静态页面) 是浏览器请求登陆页面的servlet
如果浏览器携带的cookie中有(username,jbcshibaba)这一键值对,就会把jbcshibaba自动填入用户名中
package login;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "ReturnUI", value = "/ru")
public class ReturnUI extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
if (cookies == null || cookies.length == 0) {
response.sendRedirect("/cookie/login.html");
return;
}
for (Cookie cookie : cookies) {
if ("username".equals(cookie.getName()) &&
"jbcshibaba".equals(cookie.getValue())) {
response.sendRedirect("/cookie/login2.html");
return;
}
}
response.sendRedirect("/cookie/login.html");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}