什么是Cookie?
Cookie翻译过来的意思是饼干。
Cookie是指一种在用户计算机上存储的小型文本文件,通常用于跟踪和存储有关用户的信息。当用户访问一个网站时,网站会将一个包含有关用户信息的Cookie发送到用户的浏览器。浏览器将该Cookie存储在用户的计算机上,并在以后的请求中将该Cookie发送回服务器。
Cookie通常用于记录用户的偏好设置、登录状态、购物车内容等信息,以提供个性化的用户体验。通过使用Cookie,网站可以识别用户身份以及记录用户的历史操作,例如将商品放入购物车后,网站可以利用Cookie改写浏览器本地的Cookie,添加购物车里的商品数据,这样,当用户关闭网页或者隔几天再来访问时,就会发现购物车中依然保留了之前挑选的商品。
需要注意的是,Cookie并不能用于执行恶意代码或访问用户的计算机文件。另外,由于Cookie包含有关用户的信息,因此用户需要注意保护自己的隐私安全,避免将包含敏感信息的Cookie泄露给未经授权的第三方。
- Cookie是服务器通知客户端保存用户信息的一种技术,使用key-value格式保存用户信息。
- 每个Cookie的大小不超过4KB
Cookie的大小限制因浏览器而异,但通常来说,每个Cookie的大小限制在4KB左右。因此,一个Web站点通常可以发送大约20个Cookie,而一个浏览器可以保存的总Cookie数量通常限制在300个左右。因此,Cookie的大小限制可能会影响网站的性能和用户体验,因为过多的Cookie可能会导致浏览器在处理请求时需要花费更多的时间和带宽。因此,在设计Cookie时应该遵循最佳实践,并尽量减小Cookie的大小,以确保网站的性能和安全性。
在Java Web开发中,Cookie的使用可以通过Java的内置类库来实现。以下是一些常见的使用方法:
- 创建Cookie:使用javax.servlet.http.Cookie类创建一个Cookie对象,并设置其名称和值。例如:
Cookie cookie = new Cookie("cookieName", "cookieValue");
- 设置Cookie属性:可以通过设置Cookie的属性来控制Cookie的行为。例如,可以设置Cookie的有效期、路径、域名等。例如:
cookie.setMaxAge(60 * 60 * 24 * 7); // 设置有效期为一周(以秒为单位)
cookie.setPath("/"); // 设置Cookie的路径为根目录
cookie.setDomain(".example.com"); // 设置Cookie的域名
- 将Cookie添加到响应中:在处理请求时,可以将创建的Cookie对象添加到响应中,以便将其发送给客户端。例如:
response.addCookie(cookie);
- 读取客户端发送的Cookie:在处理请求时,可以从请求中读取客户端发送的Cookie。例如:
Cookie[] cookies = request.getCookies(); // 获取所有Cookie数组
for (Cookie cookie : cookies) {
String name = cookie.getName();
String value = cookie.getValue();
// 处理每个Cookie的逻辑
}
- 删除Cookie:如果要删除一个已经存在的Cookie,可以将其有效期设置为一个过去的时间点。例如:
cookie.setMaxAge(0); // 设置有效期为立即过期
response.addCookie(cookie); // 将修改后的Cookie添加到响应中
需要注意的是,使用Cookie时应该遵循最佳实践,如限制Cookie的大小、设置安全的Cookie属性、使用HttpOnly属性等,以确保安全性和性能。同时,应该注意保护用户的隐私和数据安全,避免将敏感信息存储在Cookie中。
案例实操
- 客户端第一次发送请求没有Cookie,服务器会给客户端创建一个Cookie对象后响应给客户端
- 客户端有了Cookie后,每次请求都会发送给服务器
Cookie的创建
public class CookieServlet extends HttpServlet {
//服务器创建Cookie对象并通知客户端保存
//该方式基于JDK17,局部变量类型推断
protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
//1. 创建cookie对象
var cookie = new Cookie("key1","value1");
//2. 响应cookie对象给客户端(通知客户端保存Cookie)
resp.addCookie(cookie);
//通知客户端Cookie创建成功
resp.getWriter().write("Cookie创建成功!");
}
}
服务器获取 Cookie
public class CookieServlet extends HttpServlet {
//服务器获取客户端发送的Cookie
protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 获取客户端发送的Cookie
Cookie[] cookies = req.getCookies();
//2. 遍历Cookie
for (var c: cookies) {
resp.getWriter().write("Cookie[" + c.getName() + "," + c.getValue() + "]<br/>");
}
//3. 获取指定的Cookie
Cookie isNullCookie = CookieUtils .findCookie("key1",cookies);
if (isNullCookie != null) {
response.getWriter.write("获取到了指定Cookie");
}
}
}
Cookie工具类
自定义Cookie工具类CookieUtils
,编写获取指定Cookie的方法。
public void CookieUtils {
//获取指定的Cookie
public static Cookie findCookie(String cookieName, Cookie[] cookies) {
if (cookieName != null || cookies.length > 0 || cookies != null) {
for (var c : cookies) {
if (cookieName.equals(c.getName())) {
return c;
}
}
}
return null;
}
}
Cookie值的修改
//Cookie的修改方式1
protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 创建一个要修改的同名的Cookie对象,同时通过构造器方法赋予新的Cookie值
var cookie = new Cookie("key1","updateCookie");
//2. 然后再调用addCookie(Cookie cookie)方法,将Cookie通知给客户端修改同名的Cookie值
resp.addCookie(cookie);
resp.getWriter().write("Cookie的名为key1的值被修改成功");
}
//Cookie的修改方式2
protected void setCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 查找指定要修改的Cookie对象
var cookie = findCookie("key1",req.getCookies());
//判断cookie是否存在
if (cookie != null) {
//2. 调用setValue()赋予新的Cookie值
cookie.setValue("setCookie");
//通知客户端保存(覆盖)修改后的Cookie值
resp.addCookie(cookie);
resp.getWriter().write("Cookie的名为key1的值被修改成功");
}
}
Cookie的生命周期控制
Cookie 的生命周期控制指的是如何管理Cookie有效时长。即Cookie什么时候被销毁(删除)
- setMaxAge(参数) 设置Cookie有效时长。
参数说明:
setMaxAge(正数) ,表示在指定的秒数后过期
setMaxAge(-1),表示浏览器一关,Cookie 就会被删除(默认值是-1)
setMaxAge(0),表示马上删除 Cookie
public class CookieServlet extends HttpServlet {
//Cookie的生命控制设置(存活时间设置)
public void lifeCookie(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
//1. 创建Cookie对象
var cookie = new Cookie("key1","LifeCookie");
//2. 设置Cookie的有效时长(单位:秒)
cookie.setMaxAge(60 * 60 * 24 * 10); //有效时长10天
response.addCookie(cookie);
response.getWriter().write("Cookie十天后将被删除");
}
//设置立即删除Cookie
public void deleteNowCookie(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
//1. 创建Cookie对象
var cookie = new Cookie("key1","deleteCookie");
//2. 设置Cookie的有效时长(单位:秒)
cookie.setMaxAge(0); //立即删除
response.addCookie(cookie);
response.getWriter().write("Cookie已被删除");
}
}
//默认Session级别删除Cookie
public void defaultDelCookie(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
//1. 创建Cookie对象
var cookie = new Cookie("key1","deleteCookie");
//2. 设置Cookie的有效时长(单位:秒)
cookie.setMaxAge(-1); //seesion级别删除,即:浏览器关闭删除
response.addCookie(cookie);
response.getWriter().write("Cookie已被删除");
}
}
设置Cookie的有效请求
Cookie 的 path 属性可以有效的过滤哪些 Cookie 可以发送给服务器。哪些不发。
path 属性是通过请求的地址来进行有效的过滤。
如设置有效路径:
CookieA path=/工程路径
CookieB path=/工程路径/abc
请求地址如下:
http://ip:port/工程路径/a.html
CookieA 发送
CookieB 不发送
http://ip:port/工程路径/abc/a.html
CookieA 发送
CookieB 发送
protected void testPath(HttpServletRequest req, HttpServletResponse resp) throws
ServletException,IOException {
Cookie cookie = new Cookie("path1", "path1");
// getContextPath() ===>>>> 得到工程路径
cookie.setPath( req.getContextPath() + "/abc" ); // ===>>>> /工程路径/abc
resp.addCookie(cookie);
resp.getWriter().write("创建了一个带有 Path 路径的 Cookie");
}
综合练习
场景:实现用户免登陆(10天免登):
- 记住用户名和密码十天 setMaxAge(60 * 60 * 24 * 10)
- 十天免登录
<body>
<form action="http://localhost:8080/pro03/login" method="get">
<input type="text" name="username" value="${ cookie.username.value }" maxlength="10"/><br/>
<input type="password" name="pwd" maxlength="8"/><br/>
<input type="submit" value="登录"/>
<input type="reset" value="重置">
</form>
</body>
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("pwd");
String uname = "lisi";
String pwd = "123456";
if(uname.equalsIgnoreCase(username) && pwd.equalsIgnoreCase(password)){
Cookie cookie = new Cookie(username, password);
cookie.setMaxAge(60*60*24*10); //设置cookie内十天有效
resp.addCookie(cookie);
System.out.println("登录成功!");
} else {
System.out.println("登录失败!");
}
}
}
<servlet>
<servlet-name>loginServlet</servlet-name>
<servlet-class>cn.evan.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>