Latest web development tutorials

Servlet Cookie 處理

Cookie 是存儲在客戶端計算機上的文本文件,並保留了各種跟踪信息。 Java Servlet 顯然支持HTTP Cookie。

識別返回用戶包括三個步驟:

  • 服務器腳本向瀏覽器發送一組Cookie。 例如:姓名、年齡或識別號碼等。
  • 瀏覽器將這些信息存儲在本地計算機上,以備將來使用。
  • 當下一次瀏覽器向Web 服務器發送任何請求時,瀏覽器會把這些Cookie 信息發送到服務器,服務器將使用這些信息來識別用戶。

本章將向您講解如何設置或重置Cookie,如何訪問它們,以及如何將它們刪除。

Servlet Cookie 處理需要對中文進行編碼與解碼,方法如下:

String   str   =   java.net.URLEncoder.encode("中文");            //编码
String   str   =   java.net.URLDecoder.decode("编码后的字符串");   // 解码

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=w3cschool.cc
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 時可使用的有用的方法列表。

序号方法 & 描述
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 設置Cookie

通過Servlet 設置Cookie 包括三個步驟:

(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響應頭中的Cookie,如下所示:

response.addCookie(cookie);

實例

讓我們修改我們的表單數據實例 ,為名字和姓氏設置Cookie。

package com.w3big.test;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;

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;

/**
 * Servlet implementation class HelloServlet
 */
@WebServlet("/HelloForm")
public class HelloForm extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public HelloForm() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		// 为名字和姓氏创建 Cookie      
		Cookie name = new Cookie("name",
				URLEncoder.encode(request.getParameter("name"), "UTF-8")); // 中文转码
		Cookie url = new Cookie("url",
		              request.getParameter("url"));
		
		// 为两个 Cookie 设置过期日期为 24 小时后
		name.setMaxAge(60*60*24); 
		url.setMaxAge(60*60*24); 
		
		// 在响应头中添加两个 Cookie
		response.addCookie( name );
		response.addCookie( url );
		
		// 设置响应内容类型
		response.setContentType("text/html;charset=UTF-8");
		
		PrintWriter out = response.getWriter();
		String title = "设置 Cookie 实例";
		String docType = "<!DOCTYPE html>\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>" +
		        "  <li><b>站点 URL:</b>:"
		        + request.getParameter("url") + "\n</li>" +
		        "</ul>\n" +
		        "</body></html>");
		}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

編譯上面的ServletHelloForm ,並在web.xml文件中創建適當的條目:

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
  <servlet> 
    <!-- 类名 -->  
    <servlet-name>HelloForm</servlet-name>
    <!-- 所在的包 -->
    <servlet-class>com.w3big.test.HelloForm</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>HelloForm</servlet-name>
    <!-- 访问的网址 -->
    <url-pattern>/TomcatTest/HelloForm</url-pattern>
  </servlet-mapping>
</web-app>
最後嘗試下面的HTML 頁面來調用Servlet。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>本教程(w3big.com)</title>
</head>
<body>
<form action=/TomcatTest/HelloForm method="GET">
站点名 :<input type="text" name="name">
<br />
站点 URL:<input type="text" name="url" /><br>
<input type="submit" value="提交" />
</form>
</body>
</html>

保存上面的HTML 內容到文件/TomcatTest/test.html 中。

接下來我們訪問http://localhost:8080/TomcatTest/test.html,Gif 演示如下:

注意:以上的一些路徑需要更加你項目實際路徑修改。

通過Servlet 讀取Cookie

要讀取Cookie,您需要通過調用HttpServletRequestgetCookies( )方法創建一個javax.servlet.http.Cookie對象的數組。 然後循環遍歷數組,並使用getName() 和getValue() 方法來訪問每個cookie 和關聯的值。

實例

讓我們讀取上面的實例中設置的Cookie

package com.w3big.test;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;

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;

/**
 * Servlet implementation class ReadCookies
 */
@WebServlet("/ReadCookies")
public class ReadCookies extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ReadCookies() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
    	Cookie cookie = null;
    	Cookie[] cookies = null;
    	// 获取与该域相关的 Cookie 的数组
    	cookies = request.getCookies();
         
         // 设置响应内容类型
         response.setContentType("text/html;charset=UTF-8");
    
         PrintWriter out = response.getWriter();
         String title = "Delete Cookie Example";
         String docType = "<!DOCTYPE html>\n";
         out.println(docType +
                   "<html>\n" +
                   "<head><title>" + title + "</title></head>\n" +
                   "<body bgcolor=\"#f0f0f0\">\n" );
          if( cookies != null ){
            out.println("<h2>Cookie 名称和值</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("值:" +  URLDecoder.decode(cookie.getValue(), "utf-8") +" <br/>");
            }
         }else{
             out.println(
               "<h2 class=\"tutheader\">No Cookie founds</h2>");
         }
         out.println("</body>");
         out.println("</html>");
		}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

編譯上面的ServletReadCookies ,並在web.xml文件中創建適當的條目。嘗試運行http://localhost:8080/TomcatTest/HelloForm ,將顯示如下結果:


通過Servlet 刪除Cookie

刪除Cookie 是非常簡單的。 如果您想刪除一個cookie,那麼您只需要按照以下三個步驟進行:

  • 讀取一個現有的cookie,並把它存儲在Cookie 對像中。
  • 使用setMaxAge()方法設置cookie的年齡為零,來刪除現有的cookie。
  • 把這個cookie 添加到響應頭。

實例

下面的例子將刪除現有的名為"url" 的cookie,當您下次運行ReadCookies 的Servlet 時,它會返回url 為null。

package com.w3big.test;

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;

/**
 * Servlet implementation class DeleteCookies
 */
@WebServlet("/DeleteCookies")
public class DeleteCookies extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public DeleteCookies() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
    	Cookie cookie = null;
  	  Cookie[] cookies = null;
        // 获取与该域相关的 Cookie 的数组
        cookies = request.getCookies();
        
  	  	// 设置响应内容类型
        response.setContentType("text/html;charset=UTF-8");
   
        PrintWriter out = response.getWriter();
        String title = "删除 Cookie 实例";
        String docType = "<!DOCTYPE html>\n";
        out.println(docType +
                  "<html>\n" +
                  "<head><title>" + title + "</title></head>\n" +
                  "<body bgcolor=\"#f0f0f0\">\n" );
         if( cookies != null ){
           out.println("<h2>Cookie 名称和值</h2>");
           for (int i = 0; i < cookies.length; i++){
              cookie = cookies[i];
              if((cookie.getName( )).compareTo("url") == 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 Cookie founds</h2>");
        }
        out.println("</body>");
        out.println("</html>");
		}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

編譯上面的ServletDeleteCookies ,並在web.xml文件中創建適當的條目。現在運行http://localhost:8080/TomcatTest/DeleteCookies ,將顯示如下結果: