Cookie是什么,Java Cookie基本用法(附带实例)
Cookie 是一种客户端的会话技术,实际上是服务器端保存在浏览器上的一段信息,浏览器每次访问该服务器端的时候,都会携带 Cookie。
由于 HTTP 是无状态协议,服务器端不能记录浏览器的访问状态,也就是说服务器端不能区分两次请求是否由一个客户端发出。Cookie 的出现完美解决了这个问题,浏览器访问服务器端时,可以将其访问状态记录在携带的 Cookie 中,从而根据 Cookie 就可以判断不同请求是否为同一客户端发出的。
Cookie 的主要作用就是在浏览器中存放数据。浏览器有了 Cookie 后,每次向服务器端发送请求时都会同时将该信息发送给服务器端,服务器端收到请求后,就可以根据该消息处理请求。
Cookie 可以用于保持用户的登录状态、记住用户名,以及保存电影的播放进度等方面:
Cookie 实际上是在浏览器端存储的一小段数据。当浏览器首次访问服务器端时,服务器端可以在响应头中添加 Set-Cookie 字段来设置 Cookie 的值,并将其发送给浏览器,浏览器接收到该头信息后,会将 Cookie 的信息保存,接下来浏览器每次访问服务器端时,会以请求头的形式再将该 Cookie 发送给服务器端,服务器端便可以通过不同的 Cookie 来区分不同的用户。
常用方法包括 Cookie 对象的创建、获取 Cookie 的值等。另外,还涉及 HttpServletRequest 和 HttpServletResponse 对象对 Cookie 对象的相关操作。
创建一个 Cookie 对象,代码如下所示:
通过 HttpServletResponse 对象将 Cookie 写回给浏览器端,代码如下:
通过 HttpServletRequest 对象获取浏览器携带的所有 Cookie,代码如下:
获取 Cookie 的名称、value 值,代码如下:
创建 chapter09_cookie 模块,添加 Web 框架,并创建 ServletDemo01 类和 ServletDemo02 类,借助 Cookie 对象实现在会话域范围内共享数据。
创建 ServletDemo01 类继承 HttpServlet,重写 doGet() 和 doPost() 方法,创建 Cookie 数据并响应给客户端,示例代码如下:
创建 ServletDemo02 类继承 HttpServlet,重写 doGet() 和 doPost() 方法,获取 Cookie 数据,示例代码如下:
然后在 index.html 文件中编写超链接,访问 ServletDemo01 和 ServletDemo02 类,实现两类之间共享数据:

图 1 查看响应头携带的Cookie信息
浏览器发送请求携带 Cookie,这里不需要我们手动操作,浏览器会在给服务器端发送请求时,将 Cookie 通过请求头自动携带到服务器端。返回到首页,在 F12 开启的情况下,然后单击访问 ServletDemo02,如下图所示:

图 2 查看请求头中Cookie信息
可以发现请求头中包含了 cookie-message 的信息。查看控制台,如下图所示,成功获取 Cookie 信息:

图 3 查看控制台ServletDemo02类的输出结果
对于会话级别的 Cookie,服务器端并没有明确指定 Cookie 的存在时间。在浏览器端,Cookie 数据存在于内存中,只要浏览器处于打开状态,Cookie 数据就会一直都存在,当浏览器关闭时,内存中的 Cookie 数据就会被释放。
而持久化后的 Cookie,服务器端明确设置了其存在的时间。在浏览器端,Cookie 数据会被保存到硬盘上,Cookie 在硬盘上存在的时间根据服务器端限定的时间来管控,不受浏览器关闭的影响,直到持久化 Cookie 到达预设的时间才会被释放。
设置 Cookie 持久化的代码格式如下:
例如,创建 CookieTestServlet 类继承 HttpServlet,在该类中创建 Cookie 对象,并为该 Cookie 对象设置有效时间,示例代码如下:
在 index.html 文件中创建超链接访问类,示例代码如下:

图 4 查看Cookie对象的有效时间
可知 "username=xiaoShang" 的 Cookie 对象设置成功,在请求头中包含该 Cookie 对象,且该对象的有效时间设置为 60 秒。60 秒后,再次单击超链接,访问 CookiePathTestServlet,查看请求头信息,如下图所示:

图 5 60秒后,再次访问CookiePathTestServlet
可知 "username=xiaoShang" 的 Cookie 对象已失效。
那么如何区分需要携带的数据呢?浏览器会使用 Cookie 的 path 属性值来和当前访问的地址进行比较,从而决定是否携带 Cookie。
我们可以通过调用 Cookie 的 setPath() 方法来设置 Cookie 的 path 属性,代码格式如下:
例如,创建 CookiePathTestServlet 类继承 HttpServlet,然后在该类中创建 Cookie 对象,并为其设置 path 路径,示例代码如下:

图 6 查看响应头中Cookie的Path属性和Max-Age属性
可知 "password=atguigu" 的 Cookie 对象对应的 path 路径设置成功,并且由于当前访问该 path 路径,可以看到请求头中只携带了 "password=atguigu" 的 Cookie 对象。
另外,Cookie 是通过明文传送的,安全性较差,作为请求或响应报文发送,无形中也增加了网络流量。并且 Cookie 信息存储在浏览器中,数量也是有局限的。
由于 Cookie 的限制性,注定不能在 Cookie 中保存过多的信息,于是 Session 出现了。Session 是服务器端的技术,服务器端为每一个浏览器开辟一块内存空间,存放 Session 对象。Session 的作用就是在服务器端保存一些用户的数据。
由于 HTTP 是无状态协议,服务器端不能记录浏览器的访问状态,也就是说服务器端不能区分两次请求是否由一个客户端发出。Cookie 的出现完美解决了这个问题,浏览器访问服务器端时,可以将其访问状态记录在携带的 Cookie 中,从而根据 Cookie 就可以判断不同请求是否为同一客户端发出的。
Cookie 的主要作用就是在浏览器中存放数据。浏览器有了 Cookie 后,每次向服务器端发送请求时都会同时将该信息发送给服务器端,服务器端收到请求后,就可以根据该消息处理请求。
Cookie 可以用于保持用户的登录状态、记住用户名,以及保存电影的播放进度等方面:
- 保持用户登录状态就是当用户在登录后,会在服务器端中保存该用户的登录状态,当该用户后续访问该项目中的其他动态资源(Servlet 或 Thymeleaf)时,能够判断当前是否是已经登录过的。而从用户登录到用户退出登录这个过程中所发生的所有请求,其实都属于在一次会话范围内。
- 记住用户名是指当用户在登录页面输入完用户名后,浏览器会记录此用户名,下一次再访问登录页面时,用户名会自动填充到用户名的输入框中。
- 保存电影的播放进度是指在网页上播放电影时,如果中途退出浏览器了,下一次再打开浏览器播放同一部电影时,会自动跳转到上次退出时的进度,因为在播放的时候会将播放进度保存到 Cookie 中。
Cookie 实际上是在浏览器端存储的一小段数据。当浏览器首次访问服务器端时,服务器端可以在响应头中添加 Set-Cookie 字段来设置 Cookie 的值,并将其发送给浏览器,浏览器接收到该头信息后,会将 Cookie 的信息保存,接下来浏览器每次访问服务器端时,会以请求头的形式再将该 Cookie 发送给服务器端,服务器端便可以通过不同的 Cookie 来区分不同的用户。
Cookie常用方法
了解了 Cookie 的作用和工作原理后,接下来继续介绍 Cookie 如何进行应用。常用方法包括 Cookie 对象的创建、获取 Cookie 的值等。另外,还涉及 HttpServletRequest 和 HttpServletResponse 对象对 Cookie 对象的相关操作。
创建一个 Cookie 对象,代码如下所示:
Cookie cookie = new Cookie(String name,String value);注意,Cookie 存储的是键值对,只能保存字符串数据。
通过 HttpServletResponse 对象将 Cookie 写回给浏览器端,代码如下:
response.addCookie(cookie);
通过 HttpServletRequest 对象获取浏览器携带的所有 Cookie,代码如下:
Cookie[] cookies = request.getCookies();注意,得到所有的 Cookie 对象是一个数组,可以根据不同 key 值得到目标 Cookie 对象。
获取 Cookie 的名称、value 值,代码如下:
String name = cookie.getName(); // 获取 cookie 名称 String value = cookie.getValue(); // 获取 cookie 的 value 值
Cookie入门实例
下面通过案例演示 Cookie 的具体应用。创建 chapter09_cookie 模块,添加 Web 框架,并创建 ServletDemo01 类和 ServletDemo02 类,借助 Cookie 对象实现在会话域范围内共享数据。
创建 ServletDemo01 类继承 HttpServlet,重写 doGet() 和 doPost() 方法,创建 Cookie 数据并响应给客户端,示例代码如下:
//省略 import 语句 @WebServlet("/servletDemo01") public class ServletDemo01 extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 创建一个 cookie 对象,用于存放键值对 Cookie cookie = new Cookie("cookie-message","hello-cookie"); // 2. 将 cookie 添加到 response 中 // 底层是通过一个名为"Set-Cookie"的响应头携带到浏览器的 response.addCookie(cookie); } }
创建 ServletDemo02 类继承 HttpServlet,重写 doGet() 和 doPost() 方法,获取 Cookie 数据,示例代码如下:
//省略 import 语句 @WebServlet("/servletDemo02") public class ServletDemo02 extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 从请求中取出 cookie // 底层是由名为"Cookie"的请求头携带的 Cookie[] cookies = request.getCookies(); // 2. 遍历出每一个 cookie if (cookies != null) { for (Cookie cookie : cookies) { // 匹配 cookie 的 name if (cookie.getName().equals("cookie-message")) { // 它就是我们想要的那个 cookie // 我们就获取它的 value String value = cookie.getValue(); System.out.println("在 ServletDemo02 中获取 str 的值为:" + value); } } } } }
然后在 index.html 文件中编写超链接,访问 ServletDemo01 和 ServletDemo02 类,实现两类之间共享数据:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <a href="servletDemo01">单击访问 ServletDemo01</a><br/> <a href="servletDemo02">单击访问 ServletDemo02</a> </body> </html>启动项目后,先打开 F12,再单击访问 ServletDemo01,由于没有设置响应内容,浏览器是一个空白页面,主要查看响应头携带的 Cookie 信息,如下图所示。

图 1 查看响应头携带的Cookie信息
浏览器发送请求携带 Cookie,这里不需要我们手动操作,浏览器会在给服务器端发送请求时,将 Cookie 通过请求头自动携带到服务器端。返回到首页,在 F12 开启的情况下,然后单击访问 ServletDemo02,如下图所示:

图 2 查看请求头中Cookie信息
可以发现请求头中包含了 cookie-message 的信息。查看控制台,如下图所示,成功获取 Cookie 信息:

图 3 查看控制台ServletDemo02类的输出结果
Cookie有效时间
默认情况下,Cookie 的有效期是一次会话范围内,我们还可以通过 Cookie 的 setMaxAge() 方法设置其时效性,保证 Cookie 持久化保存到浏览器上。对于会话级别的 Cookie,服务器端并没有明确指定 Cookie 的存在时间。在浏览器端,Cookie 数据存在于内存中,只要浏览器处于打开状态,Cookie 数据就会一直都存在,当浏览器关闭时,内存中的 Cookie 数据就会被释放。
而持久化后的 Cookie,服务器端明确设置了其存在的时间。在浏览器端,Cookie 数据会被保存到硬盘上,Cookie 在硬盘上存在的时间根据服务器端限定的时间来管控,不受浏览器关闭的影响,直到持久化 Cookie 到达预设的时间才会被释放。
设置 Cookie 持久化的代码格式如下:
cookie.setMaxAge(int expiry); // 设置 cookie 的最长有效时间参数单位是秒,表示 Cookie 的持久化时间。一旦设置了有效时间,时间一到 Cookie 就会自动消失,与浏览器是否关闭无关。值得注意的是,如果参数设置为 0,表示删除浏览器中保存的 Cookie 数据。
例如,创建 CookieTestServlet 类继承 HttpServlet,在该类中创建 Cookie 对象,并为该 Cookie 对象设置有效时间,示例代码如下:
//省略 import 语句 @WebServlet("/cookieTestServlet") public class CookieTestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 新建 Cookie 对象 Cookie cookie = new Cookie("username", "xiaoShang"); // 2. 设置 cookie 对象的有效期 cookie.setMaxAge(60); // 单位是秒 // 3. 将 cookie 对象添加到 response 内 response.addCookie(cookie); // 4. 给出响应内容 response.getWriter().write("success"); } }
在 index.html 文件中创建超链接访问类,示例代码如下:
<a href="cookieTestServlet">单击访问 CookieTestServlet</a>启动项目,在首页单击 F12 键,并单击访问 CookiePathTestServlet,查看响应头信息,如图下所示:

图 4 查看Cookie对象的有效时间
可知 "username=xiaoShang" 的 Cookie 对象设置成功,在请求头中包含该 Cookie 对象,且该对象的有效时间设置为 60 秒。60 秒后,再次单击超链接,访问 CookiePathTestServlet,查看请求头信息,如下图所示:

图 5 60秒后,再次访问CookiePathTestServlet
可知 "username=xiaoShang" 的 Cookie 对象已失效。
Cookie路径
一般情况下,上网时间长了,本地会自动保存很多 Cookie 数据。但对浏览器来说,不可能每次访问互联网资源时,都携带所有 Cookie 数据。那么如何区分需要携带的数据呢?浏览器会使用 Cookie 的 path 属性值来和当前访问的地址进行比较,从而决定是否携带 Cookie。
我们可以通过调用 Cookie 的 setPath() 方法来设置 Cookie 的 path 属性,代码格式如下:
cookie.setPath(String uri); // 设置 cookie 的路径其中,浏览器发送请求时,会根据 path 路径判断需要携带哪些 Cookie 给服务器端。
例如,创建 CookiePathTestServlet 类继承 HttpServlet,然后在该类中创建 Cookie 对象,并为其设置 path 路径,示例代码如下:
//省略 import 语句 @WebServlet("/cookiePathTestServlet") public class CookiePathTestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 创建 Cookie 对象 Cookie cookie = new Cookie("password", "atguigu"); // 2. 设置有效路径 cookie.setPath(request.getContextPath()+"/cookiePathTestServlet"); // 3. 将 cookie 对象添加到 response response.addCookie(cookie); // 4. 给出响应内容 response.getWriter().write("success"); } }在 index.html 文件中,创建超链接,访问 CookiePathTestServlet 类,示例代码如下:
<a href="cookiePathTestServlet">单击访问 CookiePathTestServlet</a>启动项目,在首页单击 F12 键,并单击访问 CookiePathTestServlet,查看响应头信息,如下图所示:

图 6 查看响应头中Cookie的Path属性和Max-Age属性
可知 "password=atguigu" 的 Cookie 对象对应的 path 路径设置成功,并且由于当前访问该 path 路径,可以看到请求头中只携带了 "password=atguigu" 的 Cookie 对象。
另外,Cookie 是通过明文传送的,安全性较差,作为请求或响应报文发送,无形中也增加了网络流量。并且 Cookie 信息存储在浏览器中,数量也是有局限的。
由于 Cookie 的限制性,注定不能在 Cookie 中保存过多的信息,于是 Session 出现了。Session 是服务器端的技术,服务器端为每一个浏览器开辟一块内存空间,存放 Session 对象。Session 的作用就是在服务器端保存一些用户的数据。