引言

由于 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>");

}

}

[JavaEE笔记]Cookie的更多相关文章

  1. 笔记-cookie参数

    笔记-cookie参数 cookie各个参数详解 定义和用法 setcookie()函数向客户端发送一个 HTTP cookie. cookie是由服务器发送到浏览器的变量.cookie 通常是服务器 ...

  2. JavaEE笔记(十四)

    #SSH配置文件整合笔记实例 spring-BaseBean.xml <?xml version="1.0" encoding="UTF-8"?> ...

  3. 【读书笔记--cookie】JavaScript权威指南 第六版

    遇到一些问题需要用cookie处理,正好读了一下犀牛书关于cookie的介绍,整理了一些笔记. cookie是指web浏览器存储的少量数据,同时它是与具体的web页面或者站点相关的. cookie数据 ...

  4. 重温Servlet学习笔记--Cookie对象

    首先要了解cookie必须得先了解http协议,,Cookie是http协议指定的,先由服务器保存cookie到浏览器,在下次浏览器请求服务器时把上次请求得到的cookie归还给服务器,cookie以 ...

  5. Web客户端数据存储学习笔记——Cookie

    今天对登录访问的安全以及web客户端存储做了一些大致的学习,决定在这方面加深理解,记录在博客里.第一个接触到的是Cookie... WHAT? WHY? HOW? 在学习cookie的使用时发现其名称 ...

  6. Web安全测试学习笔记(Cookie&Session)

    一,Session:含义:有始有终的一系列动作\消息1, 隐含了“面向连接” 和“保持状态”两种含义2, 一种用来在客户端与服务器之间保持状态的解决方案3, 也指这种解决方案的存储结构“把××保存在s ...

  7. javascript笔记——cookie解析

    JavaScript中的另一个机制:cookie,则可以达到真正全局变量的要求. cookie是浏览器 提供的一种机制,它将document 对象的cookie属性提供给JavaScript.可以由J ...

  8. 20151224jquery学习笔记---cookie插件

    hello,祝自己平安夜快乐. Cookie 是网站用来在客户端保存识别用户的一种小文件.一般来用库可以保存用户登录信息.购物数据信息等一系列微小信息.一. 使用 cookie 插件官方网站: htt ...

  9. javaee学习-Cookie使用范例

    Java中的javax.servlet.http.Cookie类用于创建一个Cookie Cookie类的主要方法 No. 方法 类型 描述 1 Cookie(String name, String  ...

随机推荐

  1. 深入理解BFC

    定义 在解释BFC之前,先说一下文档流.我们常说的文档流其实分为定位流.浮动流和普通流三种.而普通流其实就是指BFC中的FC.FC是formatting context的首字母缩写,直译过来是格式化上 ...

  2. SQL Server-聚焦在视图和UDF中使用SCHEMABINDING(二十六)

    前言 上一节我们讨论了视图中的一些限制以及建议等,这节我们讲讲关于在UDF和视图中使用SCHEMABINDING的问题,简短的内容,深入的理解,Always to review the basics. ...

  3. pt-pmp

    pt-pmp有两方面的作用:一是获取进程的堆栈信息,二是对这些堆栈信息进行汇总. 进程的堆栈信息是利用gdb获取的,所以在获取的过程中,会对mysql服务端的性能有一定的影响. 用官方的话说: Thi ...

  4. PHP中PDO事务的使用方法

    事务 (Transaction) 是操作数据库中很重要的一个功能, 它可以让你预定一条, 或者一系列 SQL 语句, 然后一起执行. 在执行的过程中, 如果其中的某条执行失败, 可以回滚所有已更改的操 ...

  5. 开发者的利器:Docker 理解与使用

    困扰写代码的机器难免会被我们安装上各种各样的开发工具.语言运行环境和引用库等一大堆的东西,长久以来不仅机器乱七八糟,而且有些相同的软件还有可能会安装不同的版本,这样又会导致一个项目正常运行了,却不小心 ...

  6. js闭包 和 prototype

    function test(){ var p=200; function q(){ return p++; } return q; } var s = test(); alert(s()); aler ...

  7. 开源 iOS 项目分类索引大全 - 待整理

    开源 iOS 项目分类索引大全 GitHub 上大概600个开源 iOS 项目的分类和介绍,对于你挑选和使用开源项目应该有帮助 系统基础库 Category/Util sstoolkit 一套Cate ...

  8. join Linq

    List<Publisher> Publishers = new List<Publisher>(); Publisher publish1 = new Publisher() ...

  9. 如何获取url中的参数并传递给iframe中的报表

    在使用报表软件时,用户系统左边一般有目录树,点击报表节点就会在右侧网页的iframe中显示出报表,同时点击的时候也会传递一些参数给网页,比如时间和用户信息等.如何使网页中的报表能够获取到传递过来的参数 ...

  10. 我的MYSQL学习心得(九) 索引

    我的MYSQL学习心得(九) 索引 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...