Servlet - Cookie 處理



Cookie 是儲存在客戶端計算機上的文字檔案,它們用於各種資訊跟蹤目的。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 = 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 Cookie 方法

以下是您在 Servlet 中操作 Cookie 時可以使用的一些有用方法列表。

序號 方法及描述
1

public void setDomain(String pattern)

此方法設定 Cookie 應用到的域,例如 tutorialspoint.com。

2

public String getDomain()

此方法獲取 Cookie 應用到的域,例如 tutorialspoint.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 應用到的路徑。如果您未指定路徑,則 Cookie 將返回到與當前頁面相同的目錄中的所有 URL 以及所有子目錄。

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 應有效多長時間(以秒為單位)。以下將設定 Cookie 持續 24 小時。

cookie.setMaxAge(60 * 60 * 24); 

(3) 將 Cookie 傳送到 HTTP 響應標頭 - 使用 response.addCookie 將 Cookie 新增到 HTTP 響應標頭,如下所示:

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 目錄中。當您訪問https://:8080/Hello.htm時,以下是上述表單的實際輸出。

名字
姓氏

嘗試輸入名字和姓氏,然後單擊提交按鈕。這將在螢幕上顯示名字和姓氏,同時它將設定兩個 Cookie firstName 和 lastName,下次您按下提交按鈕時,它們將傳遞迴伺服器。

下一節將解釋如何在 Web 應用程式中訪問這些 Cookie。

使用 Servlet 讀取 Cookie

要讀取 Cookie,您需要透過呼叫HttpServletRequestgetCookies()方法建立一個javax.servlet.http.Cookie物件的陣列。然後迴圈遍歷陣列,並使用 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”,則執行https://:8080/ReadCookies將顯示以下結果:

Found Cookies Name and Value

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

使用 Servlet 刪除 Cookie

刪除 Cookie 非常簡單。如果您想刪除 Cookie,只需執行以下三個步驟:

  • 讀取已存在的 Cookie 並將其儲存在 Cookie 物件中。

  • 使用setMaxAge()方法將 Cookie 的生存期設定為零以刪除現有 Cookie

  • 將此 Cookie 添加回響應標頭。

示例

以下示例將刪除名為“first_name”的現有 Cookie,下次執行 ReadCookies Servlet 時,它將返回 first_name 的 null 值。

// 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 檔案中建立相應的條目。現在執行https://:8080/DeleteCookies將顯示以下結果:

Cookies Name and Value

Deleted cookie : first_name

Name : first_name, Value: John

Name : last_name, Value: Player

現在嘗試執行https://:8080/ReadCookies,它將僅顯示一個 Cookie,如下所示:

Found Cookies Name and Value

Name : last_name, Value: Player

您可以在 Internet Explorer 中手動刪除 Cookie。從“工具”選單開始,然後選擇“Internet 選項”。要刪除所有 Cookie,請按“刪除 Cookie”。

廣告