Servlet學習之cookie

    這次主要說明下cookie的用法,主要包括:

  • 什麼是Cookie,有什麼用途
  • 怎麼使用Cookie
  • 關於Cookie的一些理解
     1.Cookie,英文意思爲小餅乾。在Servlet中其實是一個很小的緩存文件,儲存在客戶端的本地硬盤上。主要有以下用途:
  • 記錄用戶名和密碼。方便用戶在需要驗證的網站無需多次填寫用戶名和密碼
  • 在電子商務網站中標識用戶。例如在淘寶我們往購物車裏添加商品,通過本地cookie可以讓機器理解所添加的商品屬於同一個用戶,因爲客戶每次打開一個網頁就是一次http請求,打開新的商品信息就會重新與服務器建立新的連接,需要重新驗證用戶信息,好在cookie幫助了我們,避免了每次打開新的網頁都需要驗證用戶的麻煩。
  • 定製網站。在一些網站上,我們登錄後會出現我們自己的主界面,上面的信息都是通過通過cookie來記住我們的喜好而實現的。
  • 定向廣告。通過cookie可以讓服務器知道你瀏覽了那些網站信息,當你打開網頁的時候,網頁上的廣告會顯示我們最近瀏覽的網站信息。例如我們在淘寶瀏覽了籃球信息,我們在瀏覽其他商品的時候就會跳出籃球的廣告。
     2.Cookie是由服務器端設置,發送到客戶端本地。我先寫個基本的Cookie生成例子:

Cookie cookie = new Cookie("useID","1234")
cookie.setMaxAge(60*60*24*7)
response.addCookie(cookie)
第一步使用Cookie類生成一個cookie對象,設置name和value爲useID,1234。第二步通過setMaxAge設置該cookie在客戶端有效的時間,上面設置爲一年。如果不設置時間,則默認在關閉瀏覽器即可失效。如果設置爲0,表示刪除該cookie。第三步使用addCookie方法將cookie發送到客戶端。這一步不可漏掉,否則無效。
現在我們已經設置了Cookie,我們怎麼讀取呢,通過request.getCookies( )方法返回一個cookie對象數組,然後遍歷數組,通過getName()得到所需的cookie名稱,getValue()得到該cookie的值。沒有的話返回爲null。基本的Cookie流程就是這樣,服務器通過給客戶端設置Cookie來標識用戶,通過讀取客戶端的Cookie來識別用戶,從而實現上面所說的功能。
      3.關於對Cookie的一些理解已經說得很清楚了,Cookie實現的原理簡單但是爲了一探究竟,我們通過下載tomcat src源碼來加深對Cookie的理解。我們找到javax包中的http包,打開Cookie類,除去註釋如下
package javax.servlet.http;

import java.text.MessageFormat;
import java.util.ResourceBundle;

public class Cookie implements Cloneable {

    private static final String LSTRING_FILE =
	"javax.servlet.http.LocalStrings";
    private static ResourceBundle lStrings =
	ResourceBundle.getBundle(LSTRING_FILE);
       
    private String name;	// NAME= ... "$Name" style is reserved
    private String value;	// value of NAME   
    private String comment;	// ;Comment=VALUE ... describes cookie's use
				// ;Discard ... implied by maxAge < 0
    private String domain;	// ;Domain=VALUE ... domain that sees cookie
    private int maxAge = -1;	// ;Max-Age=VALUE ... cookies auto-expire
    private String path;	// ;Path=VALUE ... URLs that see the cookie
    private boolean secure;	// ;Secure ... e.g. use SSL
    private int version = 0;	// ;Version=1 ... means RFC 2109++ style
  
    public Cookie(String name, String value) {
	if (!isToken(name)
		|| name.equalsIgnoreCase("Comment")	// rfc2019
		|| name.equalsIgnoreCase("Discard")	// 2019++
		|| name.equalsIgnoreCase("Domain")
		|| name.equalsIgnoreCase("Expires")	// (old cookies)
		|| name.equalsIgnoreCase("Max-Age")	// rfc2019
		|| name.equalsIgnoreCase("Path")
		|| name.equalsIgnoreCase("Secure")
		|| name.equalsIgnoreCase("Version")
		|| name.startsWith("$")
	    ) {
	    String errMsg = lStrings.getString("err.cookie_name_is_token");
	    Object[] errArgs = new Object[1];
	    errArgs[0] = name;
	    errMsg = MessageFormat.format(errMsg, errArgs);
	    throw new IllegalArgumentException(errMsg);
	}

	this.name = name;
	this.value = value;
    }
    public void setComment(String purpose) {
	comment = purpose;
    }
    public String getComment() {
	return comment;
    }
    public void setDomain(String pattern) {
	domain = pattern.toLowerCase();	// IE allegedly needs this
    }
    public String getDomain() {
	return domain;
    }
    public void setMaxAge(int expiry) {
	maxAge = expiry;
    }
    public int getMaxAge() {
	return maxAge;
    }
    
    public void setPath(String uri) {
	path = uri;
    }

    public String getPath() {
	return path;
    }

    public void setSecure(boolean flag) {
	secure = flag;
    }

    public boolean getSecure() {
	return secure;
    }

    public String getName() {
	return name;
    }

    public void setValue(String newValue) {
	value = newValue;
    }


    public String getValue() {
	return value;
    }


    public int getVersion() {
	return version;
    }


    public void setVersion(int v) {
	version = v;
    }

   
    private static final String tspecials = ",; ";
    
    
  
    private boolean isToken(String value) {
	int len = value.length();

	for (int i = 0; i < len; i++) {
	    char c = value.charAt(i);

	    if (c < 0x20 || c >= 0x7f || tspecials.indexOf(c) != -1)
		return false;
	}
	return true;
    }


    public Object clone() {
	try {
	    return super.clone();
	} catch (CloneNotSupportedException e) {
	    throw new RuntimeException(e.getMessage());
	}
    }
}
其中各個參數的作用我們來一一查看:
  1. comment屬性爲Cookie的註釋。
  2. domain爲Cookie設置的域名。
  3. path爲Cookie使用的路徑。
  4. secure爲Cookie是否使用過安全協議傳輸。
  5. version爲Cookie所遵從的協議版本。
    4.  我們在生成Cookie的時候不僅可以設置setMaxAge(),還可以設置其他屬性。至於Cookie的缺點,網絡上也討論的很多。任何技術都有兩面性,只要我們合理的利用就能發揮他的最大功能。
      完!



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章