# Cookie入門
### 基本概述
????Cookie,有時也用其復數形式Cookies,指某些網站為了辨別用戶身份、進行session跟蹤而儲存在用戶本地終端上的數據(通常經過加密)。Cookie也可以叫做瀏覽器緩存。
????因為HTTP是無狀態的協議,它不能保存用戶狀態,這時候往往會用到Cookie技術來對用戶進行標識并進行一些特定的處理。服務器可以利用Cookies包含信息的任意性來篩選并經常性維護這些信息,以判斷在HTTP傳輸中的狀態。
參考文檔:[http://tomcat.apache.org/tomcat-5.5-doc/servletapi/index.html](http://tomcat.apache.org/tomcat-5.5-doc/servletapi/index.html)
?
### Cookie原理圖

案例:
~~~
package com.pc;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author Switch
* 功能:設置Cookie
*/
public class Servlet8 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 字符編碼
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
// 創建Cookie (api)
Cookie cookie = new Cookie("Switch", "123456");
// 設置cookie的生命周期
cookie.setMaxAge(3600);
// 把cookie信息會寫給瀏覽器
response.addCookie(cookie);
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
~~~
~~~
package com.pc;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Switch
* 功能:獲取Cookie
*
*/
public class Servlet9 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 字符編碼
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
// 獲取客戶端發過來的所有cookie
Cookie[] cookies = request.getCookies();
if (cookies != null) {
// 測試
// System.out.println(cookies.length);
for(Cookie c : cookies){
out.println(c.getName() + " " + c.getValue());
}
}
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
~~~
~~~
package com.pc;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author Switch
* 功能:測試Cookie同名會發生什么情況
*/
public class Servlet10 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 字符編碼
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
// 創建Cookie (api)
Cookie cookie1 = new Cookie("Switch2", "123456");
// 設置cookie的生命周期
cookie1.setMaxAge(3600);
// 把cookie信息會寫給瀏覽器
response.addCookie(cookie1);
// 同名會后面的會覆蓋前面的Cookie
Cookie cookie2 = new Cookie("Switch2", "654321");
// 設置cookie的生命周期
cookie2.setMaxAge(3600);
// 把cookie信息會寫給瀏覽器
response.addCookie(cookie2);
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
~~~
小結:
1、cookie是在服務器創建的
2、cookie是保存在瀏覽器緩存文件中的
3、cookie的生命周期是可設置的
cookie.setMaxAge(time); //?time是以秒為單位的
如果不設置setMaxAge則當瀏覽器關閉時,該cookie就消亡。
4、cookie可以被多個瀏覽器共享
5、cookie是(名---值)對應關系
name和value都是String型的
如果設置Cookie,name相同,則后設置會覆蓋前設置
6、一個web應用中可以保存多個cookie,并且會保存在瀏覽器緩存文件夾的同一個文件中
7、cookie存放方式是以明文的方式,所以為了安全,要進行加密。
### MD5加密算法
~~~
package com.pc;
import java.security.*;
import java.security.spec.*;
/**
* @author Switch
* 功能:MD5加密
*/
class MD5_test {
public final static String MD5(String s) {
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' };
try {
byte[] strTemp = s.getBytes();
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
mdTemp.update(strTemp);
byte[] md = mdTemp.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
return null;
}
}
public static void main(String[] args) {
System.out.print(MD5_test.MD5("Switch"));
}
}
~~~
?
PS:MD5是一種單向加密方式,其加密是不可逆轉的,但是也可能存在破解方法,不過要一定的時間,所以建議采用MD5?64位加密或者是128位加密,該提供的方法只是32位加密方式。
????使用Cookie保存用戶重要信息時,比如密碼、銀行賬號時,必須要進行加密傳輸存儲。
?
案例:保存上次登錄的時間
~~~
package com.pc;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Servlet11 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 字符編碼
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
// 用Cookie記錄上次登錄時間
boolean b = false;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
// 獲取name
String name = cookie.getName();
if ("lasttime".equals(name)) {
// 顯示時間
out.println("上次登錄時間是:" + cookie.getValue());
updateDate(response);
b = true;
break;
}
}
}
if (!b) {
out.println("這是您第一次登錄");
updateDate(response);
}
out.flush();
out.close();
}
private void updateDate(HttpServletResponse response) {
// 更新時間
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
String nowDate = simpleDateFormat.format(new Date());
Cookie c = new Cookie("lasttime", nowDate);
// 7天有效期
c.setMaxAge(3600 * 24 * 7);
response.addCookie(c);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
~~~
### cookie生命周期
? ? cookie默認的生命周期是會話級別的,也就是說瀏覽器一關閉cookie立即失效。可以通過setMaxAge(time)的方法設置生命周期。
<table><tbody><tr><td valign="top"><p>time ? ? ? ?</p></td><td valign="top"><p>解釋</p></td></tr><tr><td valign="top"><p>正數 ? ? ??</p></td><td valign="top"><p>設置多少秒后失效</p></td></tr><tr><td valign="top"><p>0 ? ? ? ? ? ??</p></td><td valign="top"><p>刪除該<span style="font-family:Calibri">cookie</span></p></td></tr><tr><td valign="top"><p>負數 ? ? ? ?</p></td><td valign="top"><p>設置該<span style="font-family:Calibri">cookie</span><span style="font-family:宋體">為會話級別</span></p></td></tr></tbody></table>
案例:
~~~
//先得到該cookie
Cookie cookies[]=request.getCookies();
for(Cookie cookie: cookies){
if(cookie.getName().equals("id")){
System.out.println("id");
//刪除
cookie.setMaxAge(0);
//一定帶上這句話,否則不能刪除
response.addCookie(cookie);
}
}
~~~
PS:如果該web應用只有一個cookie?,則刪除該cookie后,在瀏覽器的臨時文件夾下沒有該cookie文件,如果該web應用有多個cookie,則刪除一個cookie后,文件還在,只是該cookie沒有。
### cookie細節
1、一個瀏覽器最多能夠存放300個cookie,每個web站點,最多只能占用20個cookie,而且一個cookie大小最大不能超過4k。
2、cookie存放中文,有可能會出現亂碼的情況,這時可以采用如下方法解決
存放:
String?val=java.net.URLEncoder.encode("張三","utf-8");
Cookie?cookie=new?Cookie("name",val);
取出:
String?val=java.net.URLDecoder.decode(cookie.getValue(),?"utf-8");
out.println("name?="+val);
?
?
?
----------參考《韓順平.細說Servlet》