Servlet Cookies 處理


Cookies 是儲存在客戶端電腦上的文字文件,並保留了各種追蹤資訊。 Java Servlet 顯然支援 HTTP Cookies。

識別回傳使用者包含三個步驟:

  • 伺服器腳本向瀏覽器發送一組 Cookies。例如:姓名、年齡或識別號碼等。

  • 瀏覽器將這些資訊儲存在本機電腦上,以備將來使用。

  • 當下一次瀏覽器向 Web 伺服器發送任何請求時,瀏覽器會將這些 Cookies 資訊傳送到伺服器,伺服器將使用這些資訊來識別使用者。

本章將向您解釋如何設定或重置 Cookies,如何存取它們,以及如何將它們刪除。

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

Servlet 就能夠透過請求方法request.getCookies() 存取Cookie,該方法將傳回一個Cookie 對象的數組。

Servlet Cookies 方法

以下是在 Servlet 中操作 Cookies 時可使用的有用的方法清單。

序號方法& 描述
#1public void setDomain(String pattern )
此方法設定cookie 適用的網域,例如w3cschool.cc。
2public String getDomain()
此方法取得 cookie 適用的網域,例如 w3cschool.cc。
3public void setMaxAge(int expiry)
此方法設定 cookie 過期的時間(以秒為單位)。如果不這樣設置,cookie 只會在目前 session 會話中持續有效。
4public int getMaxAge()
此方法傳回cookie 的最大生存週期(以秒為單位),預設情況下,-1 表示cookie 將持續下去,直到瀏覽器關閉。
5public String getName()
此方法傳回 cookie 的名稱。名稱在創建後不能改變。
6public void setValue(String newValue)
此方法設定與 cookie 關聯的值。
7public String getValue()
此方法取得與 cookie 關聯的值。
8public void setPath(String uri)
此方法設定 cookie 適用的路徑。如果您不指定路徑,與目前頁面相同目錄下的(包括子目錄下的)所有 URL 都會傳回 cookie。
9public String getPath()
此方法取得 cookie 適用的路徑。
10public void setSecure(boolean flag)
該方法設定布林值,表示cookie 是否應該只在加密的(即SSL)連線上發送。
11public void setComment(String purpose)
該方法規定了描述 cookie 目的的註解。該註釋在瀏覽器向使用者呈現 cookie 時非常有用。
12public String getComment()
該方法傳回了描述cookie 目的的註釋,如果cookie 沒有註解則傳回null 。

透過Servlet 設定Cookies

透過Servlet 設定Cookies 包含三個步驟:

(1) 建立一個Cookie 物件:您可以呼叫帶有cookie 名稱和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 回應頭中的Cookies,如下所示:

response.addCookie(cookie);

實例

讓我們修改我們的表單資料實例,為名字和姓氏設定Cookies。

// 导入必需的 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
  {
      // 为名字和姓氏创建 Cookies      
      Cookie firstName = new Cookie("first_name",
                      request.getParameter("first_name"));
      Cookie lastName = new Cookie("last_name",
                      request.getParameter("last_name"));

      // 为两个 Cookies 设置过期日期为 24 小时后
      firstName.setMaxAge(60*60*24); 
      lastName.setMaxAge(60*60*24); 

      // 在响应头中添加两个 Cookies
      response.addCookie( firstName );
      response.addCookie( lastName );

      // 设置响应内容类型
      response.setContentType("text/html;charset=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("first_name") + "\n</li>" +
                "  <li><b>姓氏</b>:"
                + request.getParameter("last_name") + "\n</li>" +
                "</ul>\n" +
                "</body></html>");
  }
}

編譯上面的 Servlet HelloForm,並在 web.xml 檔案中建立適當的條目,最後嘗試下面的 HTML 頁面來呼叫 Servlet。

 <html>
<head>
<meta charset="utf-8">
<title>php中文网(php.cn)</title>
</head>
<body>
<form action="HelloForm" method="GET">
名字:<input type="text" name="first_name">
<br />
姓氏:<input type="text" name="last_name" />
<input type="submit" value="提交" />
</form>
</body>
</html>

將上面的 HTML 內容保存到檔案 hello.htm 中,並把它放在 <Tomcat-installation-directory>/webapps/ROOT 目錄中。當您造訪http://localhost:8080/Hello.htm 時,上面表單的實際輸出如下所示:

##嘗試輸入名字和姓氏,然後點擊"提交"按鈕,名字和姓氏會顯示在螢幕上,同時會設定firstName 和lastName 這兩個Cookies,下次您按下提交按鈕時,會將這兩個Cookies 傳回伺服器。

下一節會說明如何在 Web 應用程式中存取這些 Cookies。

透過Servlet 讀取Cookies

要讀取Cookies,您需要透過呼叫

HttpServletRequestgetCookies( ) 方法建立一個javax .servlet.http.Cookie 物件的陣列。然後循環遍歷數組,並使用 getName() 和 getValue() 方法來存取每個 cookie 和關聯的值。

實例

讓我們讀取上面的實例中設定的Cookies

// 导入必需的 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;
      // 获取与该域相关的 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>");
   }
}

編譯上面的Servlet

ReadCookies,並在web.xml 檔案中創建適當的條目。如果您已經設定了first_name cookie 為"John",last_name cookie 為"Player" ,嘗試執行http://localhost:8080/ReadCookies,將顯示下列結果:


透過 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;charset=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("first_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>");
   }
}

編譯上面的 Servlet DeleteCookies,並在 web.xml 檔案中建立適當的條目。現在執行http://localhost:8080/DeleteCookies,將顯示以下結果:

#找出Cookies 名稱和值

名稱:first_name,值:John

名稱:last_name,值:Player
##現在嘗試執行
##Cookies 名稱和值

已刪除的cookie:first_name

名稱:first_name,值:John
名稱:last_name,值:Player
#http://localhost :8080/ReadCookies

,它將只顯示一個cookie,如下所示:

查找Cookies 名稱和值您可以手動在Internet Explorer 中刪除Cookies。在"工具"選單,選擇"Internet 選項"。如果要刪除所有的 Cookies,請按"刪除 Cookies"。
名稱:last_name,值:Player