1、什么是Cookie(饼干)
Cookie是由服务器通知客户端保存键值对的一种技术
客户端有了Cookie之后,每次请求都发送给服务器,并且每个Cookie的大小不能超过4kb
2、Cookie的创建
Cookie创建流程图
服务器创建了Cookie对象,Cookie是以键值对的方式创建的,所以,在服务器方new Cookie(key,value)
response.addCookie(cookie);添加一个cookie到响应头,通知客户端保存
通过Set-Cookie通知客户端保存Cookie
客户端收到通知后,发现有Set-Cookie响应头,就会去查看客户端有没有Cookie,没有就创建,有就修改客户端的Cookie
html代码示例:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<base href="http://localhost:8080/Cookie_Session/">
<title>Cookie</title>
<style type="text/css">
ul li {
list-style: none;
}
</style>
</head>
<body>
<iframe name="target" width="500" height="500" style="float: left;"></iframe>
<div style="float: left;">
<ul>
<li><a href="cookieServlet?action=createCookie" target="target">Cookie的创建</a></li>
<li><a href="" target="target">Cookie的获取</a></li>
<li><a href="" target="target">Cookie值的修改</a></li>
<li>Cookie的存活周期</li>
<li>
<ul>
<li><a href="" target="target">Cookie的默认存活时间(会话)</a></li>
<li><a href="" target="target">Cookie立即删除</a></li>
<li><a href="" target="target">Cookie存活3600秒(1小时)</a></li>
</ul>
</li>
<li><a href="" target="target">Cookie的路径设置</a></li>
</ul>
</div>
</body>
</html>
CookieServlet代码示例:
package com.eastwind.servlet;
/*
@author zhangJH
@create 2023-06-25-16:38
*/
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CookieServlet extends BaseServlet{
protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1、创建一个Cookie对象
Cookie cookie = new Cookie("key1", "value1");
// 2、创建多个Cookie对象
Cookie cookie2 = new Cookie("key2", "value2");
Cookie cookie3 = new Cookie("key3", "value3");
// resp.setContentType("");
// 2、服务器响应头添加Cookie对象
resp.addCookie(cookie);
// 3、响应头写入内容
resp.getWriter().write("Cookie创建成功");
}
}
BaseServlet代码示例:
package com.eastwind.servlet;
/*
@author zhangJH
@create 2023-06-13-16:34
*/
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
// 它可以作为被其他类实现的一个抽象类,具有相同的功能,还可以在基础上添加其他功能
public abstract class BaseServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解决post请求中文乱码问题
// 要在获取请求参数之前添加编码格式
// 解决请求端的中文乱码问题
req.setCharacterEncoding("UTF-8");
// 解决响应端的中文乱码问题
resp.setContentType("text/html; charset=UTF-8");
// 获取属性对象
String action = req.getParameter("action");
try {
// 获得当前类的action的方法,getDeclaredMethod(方法名,参数列表)
Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
//由于报错,是因为该method是受保护的,所以设置为允许访问
method.setAccessible(true);
// 调用这个类的method方法
method.invoke(this, req,resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
web.xml注意这里对于CookieServlet的路径配置,不要完全按照我这个来
web.xml代码示例:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>cookie的类名</servlet-name>
<servlet-class>cookie的类名的路径</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cookie的类名</servlet-name>
<!-- url-pattern配置Cookie的路径访问地址-->
<url-pattern>/cookieServlet</url-pattern>
</servlet-mapping>
</web-app>
cookie设置成功后效果如下:
之所以key2和key3没有进来,是因为响应头没有对Cookie对象进行添加(response.addCookie(cookie))
3、服务器获取客户端的Cookie
request.getCookies():返回一个Cookie
request.getName():获得Cookie对象的键
request.getValue():获得Cookie对象的值
html只需要修改一下html代码中的a标签,改变action,就是替换为其他的方法
protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
if ("key2".equals(cookie.getName())) {
resp.getWriter().write("找到key2了,键为:" + cookie.getName() + "它的值是" + cookie.getValue());
}
}
}
这个方法很常用,可以编写成一个工具类中的方法
4、Cookie值的修改
方法1:
1、创建一个与之前同名的cookie对象
2、在构造器上,赋予新的cookie值
3、调用response.addCookie(Cookie);
相当于覆盖原数据
protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 创建一个新的cookie,用来覆盖原数据
Cookie cookie = new Cookie("key1", "newValue1");
// 响应头覆盖原数据
resp.addCookie(cookie);
}
方法2:
1、查找到需要修改的Cookie对象
2、调用setValue()方法赋予新的Cookie值
3、调用response.addCookie()通知客户端保存修改
但这个方法有一个弊端,如果要支持以下内容的话,需要Base64的编码
protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// findCookie(),这是前文提到的cookie工具类方法
Cookie cookie = CookieUtils.findCookie("key1", req.getCookies());
if (cookie != null) {
// 调用setValue()方法赋予新的Cookie值
cookie.setValue("newValue11");
}
// 通知客户端保存修改,利用response.addCookie(cookie)方法
resp.addCookie(cookie);
}
对key1的value做出了修改
5、谷歌浏览器如何查看和使用Cookie
在谷歌页面按下F12
如果是英文就去Application下找
6、Cookie的生命控制
Cookie的生命控制指的是如何管理Cookie
由setMaxAge方法决定
正数表示在若干秒后Cookie将会过期(注意,是最大生存时间,而不是从当前开始算起)
负数说明Cookie将在Web浏览器退出后删除
0说明立刻删除Cookie
如果你不设置该值,默认是-1,也就是退出浏览器后删除Cookie,所以这里就不测试负数了
当负数时,这里会是Session
立即删除指定cookie的代码演示:
protected void deleteCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie = CookieUtils.findCookie("key1",req.getCookies());
// 如果cookie不为空
if (cookie != null) {
// 立即删除指定cookie
cookie.setMaxAge(0);
resp.addCookie(cookie);
resp.getWriter().write("删除成功");
}
}
指定时间删除cookie的代码演示:
由于时区不同,会导致上面看着的时间不同,你需要将cookie上的时间+8小时才是正常时间
protected void liftLive(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie = CookieUtils.findCookie("key1",req.getCookies());
if (cookie != null) {
// 存活指定秒数后删除
// 这里是10秒
cookie.setMaxAge(10);
resp.addCookie(cookie);
resp.getWriter().write("10秒的删除成功");
}
}
7、Cookie有效路径Path的设置
Cookie的Path属性可以有效的过滤哪些Cookie可以发送给服务器。哪些不发。
path属性是通过请求的地址来进行有效的过滤。
符合地址条件的就会可以被发送
如果满足/工程路径/的话,那么只有/工程路径/会被发送
而满足/工程路径/abc/的话,那么两个都可以发送
例如:/工程路径/和/工程路径/abc/
protected void testPath(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie = new Cookie("path", "path1");
// getContextPath():获取工程路径
// 意为需要在/工程目录/abc目录下的文件才可以访问这个cookie
cookie.setPath(req.getContextPath() + "/abc");
resp.addCookie(cookie);
resp.getWriter().write("创建了一个带有条件的cookie");
}