简介
Cookie 并不是它的原意“甜饼”的意思, 而是一个保存在客户机中的简单的文本文件, 这个文件与特定的 Web 文档关联`在一起, 保存了该客户机访问这个Web 文档时的信息, 当客户机再次访问这个 Web 文档时这些信息可供该文档使用。由于“Cookie”具有可以保存在客户机上的神奇特性, 因此它可以帮助我们实现记录用户个人信息的功能, 而这一切都不必使用复杂的CGI等程序 。
举例来说, 一个 Web 站点可能会为每一个访问者产生一个唯一的ID, 然后以 Cookie 文件的形式保存在每个用户的机器上。如果使用浏览器访问 Web, 会看到所有保存在硬盘上的 Cookie。在这个文件夹里每一个文件都是一个由“名/值”对组成的文本文件,另外还有一个文件保存有所有对应的 Web 站点的信息。在这里的每个 Cookie 文件都是一个简单而又普通的文本文件。透过文件名, 就可以看到是哪个 Web 站点在机器上放置了Cookie(当然站点信息在文件里也有保存)
Cookie是一段不超过4KB的小型文本数据,由一个名称(Name)、一个值(Value)和其它几个用于控制Cookie有效期、安全性、使用范围的可选属性组成。
以上摘自百度百科:百度百科
Cookie
Cookie的创建
Cookie在创建时只需要指定name,value两个属性。
Cookie cookie = new Cookie("cookie1","1122");
此时Cookie只是在服务端创建,客户端此时还不知道,服务端需要告诉客户端加入这个Cookie。
response.addCookie(cookie);
客户端首先会根据key值,domain属性,path属性判断有没有该cookie,若没有,创建新的cookie,若有就用value覆盖该cookie的value。
服务端获取Cookie
客户端在发送请求时会将cookie一并发给服务器。
刚刚创建好了cookie,这是如果再次向服务器发送请求,就会将cookie一并发给服务器。
在服务器就可以通过以下函数获取所有cookie。
Cookie[] cookies = req.getCookies();
Cookie的重写
- 方案一:用相同的name值,path值,domain值创建cookie,用新cookie覆盖原先的cookie,达到重写的效果。
- 方案二:获取要修改的cookie,然后调用
cookie.setValue(newValue)
方法修改value,要注意的是这里对value进行修改,修改的只是服务端获取的cookie,想让客户端同样需要响应给客户端
即:resp.addCookie(cookie)
所以说这种方法本质也是方案一。
要注意的是,判断两个cookie是否是同一个cookie只要是通过name、path、domain三个属性来判断的,一般情况下web站点可以访问到的cookie和服务器创建时默认的path和domain属性都是相同的。
Cookie的生命周期控制
Cookie的生命周期控制指的是管理Cookie的销毁(删除)时机。
可以通过cookie.setMaxAge(int expiry)
来进行控制,默认情况下expiry为-1
- expiry > 0 表示cookie在expiry秒后删除,在到达指定时间前,是一直存在的。
- expiry = 0 表示cookie立刻删除(可以通过重写该属性达到删除cookie的效果)
- expiry < 0 表示cookie在浏览器被关闭的时候立马会被删除,该cookie是会话级别的
Cookie的path属性
定义了Web站点上可以访问该Cookie的目录。在客户端可以有效的过滤掉访问某一服务器不需要的cookie。
若一个web项目的工程路径为:a/b/
cookie1的path属性:a/
cookie2的path属性:a/b/
cookie2的path属性:a/b/c/
那么在http://localhost:8080/a/b/
web站点下,可以访问到cookie2和cookie3两个属性,访问不到cookie1属性。
Cookie和Session的关系
在上一篇文章中有讲到客户端第一次发请求给服务器,服务器获取尝试session,获取不到,则创建新的,然后响应给客户端。下次客户端发送请求时会将已有的session发送给服务器。那么这个过程是如何实现的呢?
首先我们在服务器获取(创建)session,并获取sessionID。
@WebServlet("/test") public class SessionTestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); String id = session.getId(); System.out.println(id); } }
控制台打印结果如下:
这时我们去查看这个过程中的响应标头:
通过以上实验我们发现,服务器将创建好的session响应给客户端并不是直接将session发给服务器,而是通过创建一个cookie,name = JSESSIONID,value=sessionId,将这个cookie响应给客户端。
此时如果将这个cookie删除,当我们再次获取sessionId时,发现sessionId发生了改变(这里不在演示)。由此说明session域的数据是保存在服务器的,客户端是通过cookie保存的sessionId来访问session域的,如果将cookie删除,服务端就会创建新的sesssion和cookie。
知道了这些我们就可以解释,为什么把浏览器关闭session就会失效,因为将浏览器关闭,他保存的cookie(Expires属性为1的cookie)就会被销毁,客户端就无法再通过cookie保存的sessionId来访问session域了,因此session失效。