這次主要說明下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());
}
}
}
其中各個參數的作用我們來一一查看:- comment屬性爲Cookie的註釋。
- domain爲Cookie設置的域名。
- path爲Cookie使用的路徑。
- secure爲Cookie是否使用過安全協議傳輸。
- version爲Cookie所遵從的協議版本。
4. 我們在生成Cookie的時候不僅可以設置setMaxAge(),還可以設置其他屬性。至於Cookie的缺點,網絡上也討論的很多。任何技術都有兩面性,只要我們合理的利用就能發揮他的最大功能。
完!