[JavaEE笔记]Cookie

引言

由于 Http 是一种无状态的协议,服务器单从网络连接上无从知道客户身份。

会话跟踪是 Web 程序中常用的技术,用来跟踪用户的整个会话。常用会话跟踪技术是 Cookie 与 Session。

Cookie是什么?

Cookie 实际上是存储在客户端上的文本信息,并保留了各种跟踪的信息。

Cookie工作步骤:

(1)客户端请求服务器,如果服务器需要记录该用户的状态,就是用 response 向客户端浏览器颁发一个 Cookie。

(2)客户端浏览器会把 Cookie 保存下来。

(3)当浏览器再请求该网站时,浏览器把该请求的网址连同 Cookie 一同提交给服务器。服务器检查该 Cookie,以此来辨认用户状态。

注:Cookie功能需要浏览器的支持,如果浏览器不支持Cookie或者Cookie禁用了,Cookie功能就会失效。

Java中把Cookie封装成了javax.servlet.http.Cookie类。

Cookie剖析

Cookies 通常设置在 HTTP 头信息中(虽然 JavaScript 也可以直接在浏览器上设置一个 Cookie)。设置 Cookie 的 Servlet 会发送如下的头信息:

HTTP/1.1 200 OK

Date: Fri, 04 Feb 2000 21:03:38 GMT

Server: Apache/1.3.9 (UNIX) PHP/4.0b3

Set-Cookie: name=xyz; expires=Friday, 04-Feb-07 22:03:38 GMT;

                 path=/; domain=w3cschool.cc

Connection: close

Content-Type: text/html

正如您所看到的,Set-Cookie 头包含了一个名称值对、一个 GMT 日期、一个路径和一个域。名称和值会被 URL 编码。expires 字段是一个指令,告诉浏览器在给定的时间和日期之后"忘记"该 Cookie。

如果浏览器被配置为存储 Cookies,它将会保留此信息直到到期日期。如果用户的浏览器指向任何匹配该 Cookie 的路径和域的页面,它会重新发送 Cookie 到服务器。浏览器的头信息可能如下所示:

GET / HTTP/1.0

Connection: Keep-Alive

User-Agent: Mozilla/4.6 (X11; I; Linux 2.2.6-15apmac ppc)

Host: zink.demon.co.uk:1126

Accept: image/gif, */*

Accept-Encoding: gzip

Accept-Language: en

Accept-Charset: iso-8859-1,*,utf-8

Cookie: name=xyz

Cookie类中的方法

方法

功能

public void setDomain(String pattern)

该方法设置 cookie 适用的域。

public String getDomain()

该方法获取 cookie 适用的域。

public void setMaxAge(int expiry)

该方法设置 cookie 过期的时间(以秒为单位)。如果不这样设置,cookie 只会在当前 session 会话中持续有效。

public int getMaxAge()

该方法返回 cookie 的最大生存周期(以秒为单位),默认情况下,-1 表示 cookie 将持续下去,直到浏览器关闭。

public String getName()

该方法返回 cookie 的名称。名称在创建后不能改变。

public void setValue(String newValue)

该方法设置与 cookie 关联的值。

public String getValue()

该方法获取与 cookie 关联的值。

public void setPath(String uri)

该方法设置 cookie 适用的路径。如果您不指定路径,与当前页面相同目录下的(包括子目录下的)所有 URL 都会返回 cookie。

public String getPath()

该方法获取 cookie 适用的路径。

public void setSecure(boolean flag)

该方法设置布尔值,向浏览器指示,只会在HTTPS和SSL等安全协议中传输此类Cookie。

public void setComment(String purpose)

该方法规定了描述 cookie 目的的注释。该注释在浏览器向用户呈现 cookie 时非常有用。

public String getComment()

该方法返回了描述 cookie 目的的注释,如果 cookie 没有注释则返回 null。

Cookie的有效期

Cookie的maxAge决定着Cookie的有效期,单位为秒。

如果maxAge为0,则表示删除该Cookie;如果为负数,表示该Cookie仅在本浏览器中以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。

Cookie中提供getMaxAge()setMaxAge(int expiry)方法来读写maxAge属性。

Cookie的域名

Cookie是不可以跨域名的。域名www.google.com颁发的Cookie不会被提交到域名www.baidu.com去。这是由Cookie的隐私安全机制决定的。隐私安全机制能够禁止网站非法获取其他网站的Cookie。

正常情况下,同一个一级域名的两个二级域名之间也不能互相使用Cookie。如果想让某域名下的子域名也可以使用该Cookie,需要设置Cookie的domain参数。

Java中使用setDomain(String domain)getDomain()方法来设置、获取domain。

Cookie的路径

Path属性决定允许访问Cookie的路径。

Java中使用setPath(String uri)getPath()方法来设置、获取path。

Cookie的安全属性

HTTP协议不仅是无状态的,而且是不安全的。

使用HTTP协议的数据不经过任何加密就直接在网络上传播,有被截获的可能。如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。

Java中使用setSecure(boolean flag)getSecure ()方法来设置、获取Secure。

实例

添加Cookie

通过 Servlet 添加 Cookies 包括三个步骤:

(1)创建一个 Cookie 对象:您可以调用带有 cookie 名称和 cookie 值的 Cookie 构造函数,cookie 名称和 cookie 值都是字符串。

(2)设置最大生存周期:您可以使用 setMaxAge 方法来指定 cookie 能够保持有效的时间(以秒为单位)。

(3)发送 Cookie 到 HTTP 响应头:您可以使用 response.addCookie 来添加 HTTP 响应头中的 Cookies。

AddCookieDemo.java

package notes.javaee.servlet.cookie;

// 导入必需的 java 库

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

// 扩展 HttpServlet 类

@WebServlet("/servlet/cookie/addCookieDemo")

public class AddCookieDemo extends HttpServlet {

private static final long serialVersionUID = 1L;

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

        Cookie cookieName = new Cookie("name", request.getParameter("name"));

        Cookie cookieAge = new Cookie("age", request.getParameter("age"));

// 为两个Cookie设置有效期

cookieName.setMaxAge(30);

cookieAge.setMaxAge(30);

// 在响应头中添加两个 Cookies

response.addCookie(cookieName);

response.addCookie(cookieAge);

// 设置响应内容类型

response.setContentType("text/html");

response.setCharacterEncoding("utf-8");

        PrintWriter out = response.getWriter();

        String title = "设置 Cookies 实例";

        String docType = "<!doctype html public \"-//w3c//dtd html 4.0 " +

"transitional//en\">\n";

out.println(docType +

"<html>\n" +

"<head><title>" + title + "</title></head>\n" +

"<body bgcolor=\"#f0f0f0\">\n" +

"<h1 align=\"center\">" + title + "</h1>\n" +

"<ul>\n" +

"  <li><b>名字</b>:"

                + request.getParameter("name") + "\n" +

"  <li><b>年龄</b>:"

                + request.getParameter("age") + "\n" +

"</ul>\n" +

"</body></html>");

    }

}

ShowCookieDemo.html

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>显示Cookie</title>

</head>

<body>

<form action="/ServletNotes/servlet/cookie/showCookieDemo"method="GET">

名字:<input type="text" name="name">

<br />

年龄:<input type="text" name="age"/>

<input type="submit"value="提交" />

</form>

</body>

</html>

访问http://localhost:8080/ServletNotes/ShowCookieDemo.html,提交输入文本后,可以看到cookie内容。

显示Cookie

要读取 Cookies,您需要通过调用 HttpServletRequestgetCookies()方法创建一个 javax.servlet.http.Cookie对象的数组。然后循环遍历数组,并使用 getName()getValue() 方法来访问每个 cookie 和关联的值。

ReadCookies.java

package notes.javaee.servlet.cookie;

// 导入必需的 java 库

import java.io.*;

import javax.servlet.*;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.*;

// 扩展 HttpServlet 类

@WebServlet("/servlet/cookie/readCookies")

public class ReadCookies extends HttpServlet {

public void doGet(HttpServletRequest request,

            HttpServletResponse response)

throws ServletException, IOException {

        Cookie cookie = null;

        Cookie[] cookies = null;

// 获取与该域相关的 Cookies 的数组

cookies = request.getCookies();

// 设置响应内容类型

response.setContentType("text/html;charset=UTF-8");

        PrintWriter out = response.getWriter();

        String title = "Reading Cookies Example";

        String docType = "<!doctype html public \"-//w3c//dtd html 4.0 " +

"transitional//en\">\n";

out.println(docType +

"<html>\n" +

"<head><title>" + title + "</title></head>\n" +

"<body bgcolor=\"#f0f0f0\">\n");

if (cookies != null) {

out.println("<h2>查找 Cookies 名称和值</h2>");

for (int i = 0; i < cookies.length; i++) {

cookie = cookies[i];

out.print("名称:" + cookie.getName() + ",");

out.print("值:" + cookie.getValue() + " <br/>");

            }

        } else {

out.println("<h2>未找到 Cookies</h2>");

        }

out.println("</body>");

out.println("</html>");

    }

}

删除Cookie

Java中并没有提供直接删除Cookie的方法,如果想要删除一个Cookie,直接将这个Cookie的有效期设为0就可以了。步骤如下:

(1)读取一个现有的 cookie,并把它存储在 Cookie 对象中。

(2)使用 setMaxAge() 方法设置 cookie 的年龄为零,来删除现有的 cookie。

(3)把这个 cookie 添加到响应头。

DeleteCookieDemo.java

package notes.javaee.servlet.cookie;

// 导入必需的 java 库

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

// 扩展 HttpServlet 类

@WebServlet("/servlet/cookie/deleteCookieDemo")

public class DeleteCookieDemoextends HttpServlet {

private static final long serialVersionUID = 1L;

public void doGet(HttpServletRequest request,

            HttpServletResponse response)

throws ServletException, IOException {

        Cookie cookie = null;

        Cookie[] cookies = null;

// 获取与该域相关的 Cookies 的数组

cookies = request.getCookies();

// 设置响应内容类型

response.setContentType("text/html");

response.setCharacterEncoding("utf-8");

        PrintWriter out = response.getWriter();

        String title = "Delete Cookies Example";

        String docType = "<!doctype html public \"-//w3c//dtd html 4.0 " +

"transitional//en\">\n";

out.println(docType +

"<html>\n" +

"<head><title>" + title + "</title></head>\n" +

"<body bgcolor=\"#f0f0f0\">\n");

if (cookies != null) {

out.println("<h2>Cookies 名称和值</h2>");

for (int i = 0; i < cookies.length; i++) {

cookie = cookies[i];

if ((cookie.getName()).compareTo("name") == 0) {

cookie.setMaxAge(0);

response.addCookie(cookie);

out.print("已删除的 cookie:" + cookie.getName() + "<br/>");

                }

out.print("名称:" + cookie.getName() + ",");

out.print("值:" + cookie.getValue() + " <br/>");

            }

        } else {

out.println(

"<h2 class=\"tutheader\">No cookies founds</h2>");

        }

out.println("</body>");

out.println("</html>");

    }

}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [设计模式]创建型模式

    定义 创建型模式抽象了实例化的过程。它将系统与它的对象创建、结合、表示的方式分离。 创建型模式都会将关于该系统使用哪些具体的类的信息封装起来。 在软件工程中,创...

    静默虚空
  • 排序四 希尔排序

    要点 希尔(Shell)排序又称为缩小增量排序,它是一种插入排序。它是直接插入排序算法的一种威力加强版。 该方法因DL.Shell于1959年提出而得名。 希尔...

    静默虚空
  • Lombok 使用小结

    Lombok 简介 Lombok 是一种 Java 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO)。它通过注释...

    静默虚空
  • HTML5 SVG+CSS3霓虹灯文字边框动画特效

    AlexTao
  • nodejs直接调用grunt(非调用批处理)

    用户1258909
  • 利用jquery实现当前时间动态显示

    菲宇
  • 一文解决韦恩图(零代码版本、R语言、python版本)

    http://bioinformatics.psb.ugent.be/webtools/Venn/

    用户1359560
  • 探秘VB.net中的shared与static

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

    DannyHoo
  • 谁干的?暗网最大网络托管商被黑,6500个网站遭彻底删除

    2017年,“匿名者”组织攻击并拿下了暗网托管商Freedom Hosting II后,Daniel's Hosting一跃成为最大的暗网托管商。

    FB客服
  • 那些容易被遗忘的 Redis 功能

    Redis 的 SORT 命令可以对列表(List)、集合(Set)和有序集合(Sorted Set)的元素值进行排序(快排算法)。

    happyJared

扫码关注云+社区

领取腾讯云代金券