Servlet - Cookies 处理

  • 简述

    Cookies 是存储在客户端计算机上的文本文件,用于各种信息跟踪目的。Java Servlet 透明地支持 HTTP cookie。
    识别回访用户涉及三个步骤 -
    • 服务器脚本向浏览器发送一组 cookie。例如姓名、年龄或身份证号码等。
    • 浏览器将此信息存储在本地机器上以备将来使用。
    • 下次浏览器向 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 = cainiaoya.com
    Connection: close
    Content-Type: text/html
    
    如您所见,Set-Cookie 标头包含名称值对、GMT 日期、路径和域。名称和值将进行 URL 编码。expires 字段是浏览器在给定时间和日期之后“忘记”cookie 的指令。
    如果浏览器配置为存储 cookie,它将保留此信息直到到期日期。如果用户将浏览器指向任何与 cookie 的路径和域匹配的页面,它就会将 cookie 重新发送到服务器。浏览器的标题可能看起来像这样 -
    
    GET / HTTP/1.0
    Connection: Keep-Moove
    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 Cookie 方法

    以下是您在 servlet 中操作 cookie 时可以使用的有用方法列表。
    序号 方法和说明
    1
    public void setDomain(String pattern)
    此方法设置 cookie 应用到的域,例如 cainiaoya.com。
    2
    public String getDomain()
    此方法获取 cookie 适用的域,例如 cainiaoya.com。
    3
    public void setMaxAge(int expiry)
    此方法设置 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)
    此方法设置布尔值,指示是否应仅通过加密(即 SSL)连接发送 cookie。
    11
    public void setComment(String purpose)
    此方法指定描述 cookie 用途的注释。如果浏览器将 cookie 呈现给用户,则该注释很有用。
    12
    public String getComment()
    此方法返回描述此 cookie 用途的注释,如果 cookie 没有注释,则返回 null。
  • 使用 Servlet 设置 Cookie

    使用 servlet 设置 cookie 涉及三个步骤 -
    (1) Creating a Cookie object − 使用 cookie 名称和 cookie 值调用 Cookie 构造函数,这两个值都是字符串。
    
    Cookie cookie = new Cookie("key","value");
    
    请记住,名称和值都不应包含空格或以下任何字符 -
    
    [ ] ( ) = , " / ? @ : ;
    
    (2) Setting the maximum age- 您使用 setMaxAge 来指定 cookie 的有效时间(以秒为单位)。以下将设置 24 小时的 cookie。
    
    cookie.setMaxAge(60 * 60 * 24); 
    
    (3) Sending the Cookie into the HTTP response headers - 您可以使用 response.addCookie 在 HTTP 响应头中添加 cookie,如下所示 -
    
    response.addCookie(cookie);
    

    例子

    让我们修改我们的表单示例来设置名字和姓氏的 cookie。
    
    // Import required java libraries
    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
     
    // Extend HttpServlet class
    public class HelloForm extends HttpServlet {
       public void doGet(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
          
          // Create cookies for first and last names.      
          Cookie firstName = new Cookie("first_name", request.getParameter("first_name"));
          Cookie lastName = new Cookie("last_name", request.getParameter("last_name"));
          // Set expiry date after 24 Hrs for both the cookies.
          firstName.setMaxAge(60*60*24);
          lastName.setMaxAge(60*60*24);
          // Add both the cookies in the response header.
          response.addCookie( firstName );
          response.addCookie( lastName );
          // Set response content type
          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\">\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>First Name</b>: "
                      + request.getParameter("first_name") + "\n" +
                      "  <li><b>Last Name</b>: "
                      + request.getParameter("last_name") + "\n" +
                   "</ul>\n" +
                "</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 时,这里是上述表单的实际输出。
    名:
    尝试输入名字和姓氏,然后单击提交按钮。这将在您的屏幕上显示名字和姓氏,同时它会设置两个 cookie firstName 和 lastName,它们将在您下次按下提交按钮时传回服务器。
    下一节将向您解释如何在 Web 应用程序中访问这些 cookie。
  • 使用 Servlet 读取 Cookie

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

    例子

    让我们阅读我们在前面的例子中设置的 cookie -
    
    // Import required java libraries
    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
     
    // Extend HttpServlet class
    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();
          // Set response content type
          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\">\n";
             
          out.println(docType +
             "<html>\n" +
             "<head><title>" + title + "</title></head>\n" +
             "<body bgcolor = \"#f0f0f0\">\n" );
          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 删除 Cookie

    删除cookies非常简单。如果你想删除一个 cookie,那么你只需要遵循以下三个步骤 -
    • 读取一个已经存在的 cookie 并将其存储在 Cookie 对象中。
    • 使用 setMaxAge() 删除现有cookie的方法
    • 将此 cookie 添加回响应标头。

    例子

    以下示例将删除名为“first_name”的现有 cookie,当您下次运行 ReadCookies servlet 时,它会为 first_name 返回空值。
    
    // Import required java libraries
    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
     
    // Extend HttpServlet class
    public class DeleteCookies 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();
          // Set response content type
          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\">\n";
             
          out.println(docType +
             "<html>\n" +
             "<head><title>" + title + "</title></head>\n" +
             "<body bgcolor = \"#f0f0f0\">\n" );
             
          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 Name and Value

    Deleted cookie : first_name
    Name : first_name, Value: John
    Name : last_name, Value: Player
    现在尝试运行http://localhost:8080/ReadCookies它将只显示一个 cookie,如下所示 -

    Found Cookies Name and Value

    Name : last_name, Value: Player
    您可以手动删除 Internet Explorer 中的 cookie。从工具菜单开始,然后选择 Internet 选项。要删除所有 cookie,请按删除 cookie。