首页 > 编程笔记 > Java笔记 阅读:18

Cookie是什么,Java Cookie基本用法(附带实例)

Cookie 是一种客户端的会话技术,实际上是服务器端保存在浏览器上的一段信息,浏览器每次访问该服务器端的时候,都会携带 Cookie。

由于 HTTP 是无状态协议,服务器端不能记录浏览器的访问状态,也就是说服务器端不能区分两次请求是否由一个客户端发出。Cookie 的出现完美解决了这个问题,浏览器访问服务器端时,可以将其访问状态记录在携带的 Cookie 中,从而根据 Cookie 就可以判断不同请求是否为同一客户端发出的。

Cookie 的主要作用就是在浏览器中存放数据。浏览器有了 Cookie 后,每次向服务器端发送请求时都会同时将该信息发送给服务器端,服务器端收到请求后,就可以根据该消息处理请求。

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 的作用就是在服务器端保存一些用户的数据。

相关文章