Servlets - Cookies 处理

Cookies 是存储在客户端计算机上的文本文件,用于各种信息跟踪目的。Java Servlets 透明地支持 HTTP cookies。

识别回访用户涉及三个步骤 −

  • 服务器脚本向浏览器发送一组 cookies。例如姓名、年龄或身份证号码等。

  • 浏览器将此信息存储在本地机器上以备将来使用。

  • 当浏览器下次向 Web 服务器发送任何请求时,它会将这些 cookie 信息发送到服务器,服务器使用该信息来识别用户。

本章将教您如何设置或重置 cookie、如何访问它们以及如何删除它们。

Cookie 的剖析

Cookie 通常在 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 = tutorialspoint.com
Connection: close
Content-Type: text/html

如您所见,Set-Cookie 标头包含一个名称值对、一个 GMT 日期、一个路径和一个域。名称和值将进行 URL 编码。expires 字段指示浏览器在给定的时间和日期之后"忘记"cookie。

如果浏览器配置为存储 cookie,它将保留此信息直到到期日期。如果用户将浏览器指向与 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

然后,servlet 将通过请求方法 request.getCookies() 访问 cookie,该方法返回一个 Cookie 对象数组。

Servlet Cookies 方法

以下是在 servlet 中操作 cookie 时可以使用的有用方法列表。

Sr.No. 方法 &描述
1

public void setDomain(String pattern)

此方法设置 cookie 适用的域,例如 tutorialspoint.com。

2

public String getDomain()

此方法获取 cookie 适用的域,例如 tutorialspoint.com。

3

public void setMaxAge(int expiry)

此方法设置 cookie 的持续时间(单位:分钟)秒)后,cookie 才会过期。如果不设置,cookie 只会在当前会话中有效。

4

public int getMaxAge()

此方法返回 cookie 的最大使用期限,以秒为单位,默认情况下为 -1,表示 cookie 将一直存在,直到浏览器关闭。

5

public String getName()

此方法返回 cookie 的名称。创建后无法更改名称。

6

public void setValue(String newValue)

此方法设置与 cookie 关联的值

7

public String getValue()

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

8

public void setPath(String uri)

此方法设置此 cookie 适用的路径。如果不指定路径,则将返回当前页面同一目录下所有 URL 及其子目录的 cookie。

9

public String getPath()

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

10

public void setSecure(boolean flag)

此方法设置布尔值,指示 cookie 是否应仅通过加密(即 SSL)连接发送。

11

public void setComment(String purpose)

此方法指定描述 cookie 用途的注释。如果浏览器向用户显示 cookie,则注释很有用。

12

public String getComment()

此方法返回描述此 cookie 用途的注释,如果 cookie 没有注释,则返回 null。

使用 Servlet 设置 Cookie

使用 servlet 设置 cookie 涉及三个步骤 −

(1) 创建 Cookie 对象 − 使用 cookie 名称和 cookie 值调用 Cookie 构造函数,两者都是字符串。

Cookie cookie = new Cookie("key","value");

请记住,名称和值都不应包含空格或以下任何字符 −

[ ] ( ) = , " / ? @ : ;

(2) 设置最大年龄 − 您可以使用 setMaxAge 指定 cookie 的有效时间(以秒为单位)。以下将设置一个 24 小时的 cookie。

cookie.setMaxAge(60 * 60 * 24);

(3) 将 Cookie 发送到 HTTP 响应标头 − 您可以使用 response.addCookie 在 HTTP 响应标头中添加 cookie,如下所示 −

response.addCookie(cookie);

示例

让我们修改我们的表单示例,以设置名字和姓氏的 cookie。

// 导入所需的 Java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
// 扩展 HttpServlet 类
public class HelloForm extends HttpServlet {

   public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
      
      // 为名字和姓氏创建 cookie。
      Cookie firstName = new Cookie("first_name", request.getParameter("first_name"));
      Cookie lastName = new Cookie("last_name", request.getParameter("last_name"));

      // 将两种 cookie 的有效期都设置为 24 小时后。
      firstName.setMaxAge(60*60*24);
      lastName.setMaxAge(60*60*24);

      // 在响应标头中添加这两个 cookie。
      response.addCookie( firstName );
      response.addCookie( lastName );

      // 设置响应内容类型
      response.setContentType("text/html");
 
      PrintWriter out = response.getWriter();
      String title = "Setting Cookies Example";
      String docType =
         "<!doctype html public \"-//w3c//dtd html 4.0 " + "transitional//en\">";
      
      out.println(docType +
         "<html>" ++
            "<head>
               <title>" + title + "</title>
            </head>" ++
            
            "<body bgcolor = \"#f0f0f0\">" ++
               "<h1 align = \"center\">" + title + "</h1>" ++
               "<ul>" ++
                  "  <li><b>First Name</b>: "
                  + request.getParameter("first_name") + "" ++
                  "  <li><b>Last Name</b>: "
                  + request.getParameter("last_name") + "" ++
               "</ul>" ++
            "</body>
         </html>"
      );
   }
}

编译上述 servlet HelloForm 并在 web.xml 文件中创建适当的条目,最后尝试以下 HTML 页面调用 servlet。

 
<html>
   <body>
      <form action = "HelloForm" method = "GET">
         First Name: <input type = "text" name = "first_name">
         <br />
         Last Name: <input type = "text" name = "last_name" />
         <input type = "submit" value = "Submit" />
      </form>
   </body>
</html>

将上述 HTML 内容保存在文件 Hello.htm 中,并将其放在 <Tomcat-installationdirectory>/webapps/ROOT 目录中。当您访问 http://localhost:8080/Hello.htm 时,以下是上述表单的实际输出。

First Name:
Last Name:

尝试输入名字和姓氏,然后单击提交按钮。这将在您的屏幕上显示名字和姓氏,同时它将设置两个 cookie firstName 和 lastName,当您下次按下提交按钮时,它们将传递回服务器。

下一节将向您解释如何在 Web 应用程序中访问这些 cookie。

使用 Servlet 读取 Cookie

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

示例

让我们读取我们在上一个示例中设置的 cookie −

// 导入所需的 Java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
// 扩展 HttpServlet 类
public class ReadCookies extends HttpServlet {
 
   public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
      
      Cookie cookie = null;
      Cookie[] cookies = null;

      // Get an array of Cookies associated with this domain
      cookies = request.getCookies();

      // 设置响应内容类型
      response.setContentType("text/html");

      PrintWriter out = response.getWriter();
      String title = "Reading Cookies Example";
      String docType =
         "<!doctype html public \"-//w3c//dtd html 4.0 " +
         "transitional//en\">";
         
      out.println(docType +
         "<html>" ++
         "<head><title>" + title + "</title></head>" ++
         "<body bgcolor = \"#f0f0f0\">" +);

      if( cookies != null ) {
         out.println("<h2> Found Cookies Name and Value</h2>");

         for (int i = 0; i < cookies.length; i++) {
            cookie = cookies[i];
            out.print("Name : " + cookie.getName( ) + ",  ");
            out.print("Value: " + cookie.getValue( ) + " <br/>");
         }
      } else {
         out.println("<h2>No cookies founds</h2>");
      }
      out.println("</body>");
      out.println("</html>");
   }
}

编译上述 servlet ReadCookies 并在 web.xml 文件中创建相应条目。如果您将 first_name cookie 设置为"John",将 last_name cookie 设置为"Player",则运行 http://localhost:8080/ReadCookies 将显示以下结果 −

Found Cookies Name and Value

Name : first_name, Value: John
Name : last_name, Value: Player

使用 Servlet 删除 Cookies

删除 cookies 非常简单。如果您想删除 cookie,则只需执行以下三个步骤即可 −

  • 读取已经存在的 cookie 并将其存储在 Cookie 对象中。

  • 使用 setMaxAge() 方法将 cookie 年龄设置为零以删除现有 cookie

  • 将此 cookie 重新添加到响应标头中。

示例

以下示例将删除名为"first_name"的现有 cookie,当您下次运行 ReadCookies servlet 时,它将返回 first_name 的空值。

// 导入所需的 Java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
// 扩展 HttpServlet 类
public class DeleteCookies 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");
 
      PrintWriter out = response.getWriter();
      String title = "Delete Cookies Example";
      String docType =
         "<!doctype html public \"-//w3c//dtd html 4.0 " + "transitional//en\">";
         
      out.println(docType +
         "<html>" ++
         "<head><title>" + title + "</title></head>" ++
         "<body bgcolor = \"#f0f0f0\">" +);
         
      if( cookies != null ) {
         out.println("<h2> Cookies Name and Value</h2>");

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

            if((cookie.getName( )).compareTo("first_name") == 0 ) {
               cookie.setMaxAge(0);
               response.addCookie(cookie);
               out.print("Deleted cookie : " + cookie.getName( ) + "<br/>");
            }
            out.print("Name : " + cookie.getName( ) + ",  ");
            out.print("Value: " + cookie.getValue( )+" <br/>");
         }
      } else {
         out.println("<h2>No cookies founds</h2>");
      }
      out.println("</body>");
      out.println("</html>");
   }
}

编译上述 servlet DeleteCookies 并在 web.xml 文件中创建相应条目。现在运行 http://localhost:8080/DeleteCookies 将显示以下结果 −

Cookies 名称和值

Deleted cookie : first_name

Name : first_name, Value: John

Name : last_name, Value: Player

现在尝试运行 http://localhost:8080/ReadCookies 并且它将仅显示一个 cookie,如下所示 −

找到 Cookies 名称和值

Name : last_name, Value: Player

您可以在 Internet Explorer 中手动删除 cookie。从"工具"菜单开始,然后选择"Internet 选项"。要删除所有 Cookie,请按"删除 Cookie"。