一、會話的概念
會話可簡單理解為:用戶開一個瀏覽器,點擊多個超鏈接,訪問服務(wù)器多個web資源,然后關(guān)閉瀏覽器,整個過程稱之為一個會話。
有狀態(tài)會話:一個同學(xué)來過教室,下次再來教室,我們會知道這個同學(xué)曾經(jīng)來過,這稱之為有狀態(tài)會話。
二、會話過程中要解決的一些問題?
每個用戶在使用瀏覽器與服務(wù)器進行會話的過程中,不可避免各自會產(chǎn)生一些數(shù)據(jù),程序要想辦法為每個用戶保存這些數(shù)據(jù)。
三、保存會話數(shù)據(jù)的兩種技術(shù)
3.1、Cookie
Cookie是客戶端技術(shù),程序把每個用戶的數(shù)據(jù)以cookie的形式寫給用戶各自的瀏覽器。當(dāng)用戶使用瀏覽器再去訪問服務(wù)器中的web資源時,就會帶著各自的數(shù)據(jù)去。這樣,web資源處理的就是用戶各自的數(shù)據(jù)了。
3.2、Session
Session是服務(wù)器端技術(shù),利用這個技術(shù),服務(wù)器在運行時可以為每一個用戶的瀏覽器創(chuàng)建一個其獨享的session對象,由于session為用戶瀏覽器獨享,所以用戶在訪問服務(wù)器的web資源時,可以把各自的數(shù)據(jù)放在各自的session中,當(dāng)用戶再去訪問服務(wù)器中的其它web資源時,其它web資源再從用戶各自的session中取出數(shù)據(jù)為用戶服務(wù)。
四、Java提供的操作Cookie的API
String getComment()返回cookie中注釋,如果沒有注釋的話將返回空值.
String getDomain() 返回cookie中Cookie適用的域名. 使用getDomain() 方法可以指示瀏覽器把Cookie返回給同 一域內(nèi)的其他服務(wù)器,而通常Cookie只返回給與發(fā)送它的服務(wù)器名字完全相同的服務(wù)器。注意域名必須以點開始(例如.yesky.com)
int getMaxAge() 返回Cookie過期之前的最大時間,以秒計算。
String getName()返回Cookie的名字。名字和值是我們始終關(guān)心的兩個部分,筆者會在后面詳細(xì)介紹 getName/setName。
String getPath()返回Cookie適用的路徑。如果不指定路徑,Cookie將返回給當(dāng)前頁面所在目錄及其子目錄下 的所有頁面。
boolean getSecure() 如果瀏覽器通過安全協(xié)議發(fā)送cookies將返回true值,如果瀏覽器使用標(biāo)準(zhǔn)協(xié)議則返回false值。
String getValue() 返回Cookie的值。筆者也將在后面詳細(xì)介紹getValue/setValue。
int getVersion() 返回Cookie所遵從的協(xié)議版本。
void setComment(String purpose) 設(shè)置cookie中注釋。
void setDomain(String pattern) 設(shè)置cookie中Cookie適用的域名
void setMaxAge(int expiry) 以秒計算,設(shè)置Cookie過期時間。
void setPath(String uri) 指定Cookie適用的路徑。
void setSecure(boolean flag) 指出瀏覽器使用的安全協(xié)議,例如HTTPS或SSL。
void setValue(String newValue) cookie創(chuàng)建后設(shè)置一個新的值。
void setVersion(int v) 設(shè)置Cookie所遵從的協(xié)議版本。
五、Cookie使用范例
5.1、使用cookie記錄用戶上一次訪問的時間
package rain.cookie.study;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
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 CookieDemo1
* cookie實例:獲取用戶上一次訪問的時間
*/
@WebServlet("/CookieDemo1")
public class CookieDemo1 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//設(shè)置服務(wù)端以UTF-8編碼進行輸出
response.setCharacterEncoding("utf-8");
//設(shè)置客戶端以UTF-8進行接收,解決中文亂碼問題
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//獲取瀏覽器訪問服務(wù)器時傳遞過來的cookie數(shù)組
Cookie[] cookies = request.getCookies();
if(cookies != null) {
out.write("您上次訪問的時間是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
if(cookie.getName().equals("lastAccessTime")) {
long lastTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastTime);
out.write(date.toLocaleString());
}
}
}else {
out.write("這是您第一次訪問本站!");
}
//用戶訪問過之后 要重新將時間存儲到cookie中,然后發(fā)送給客戶端
Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+"");
//將cookie添加到Response對象中 發(fā)送給客戶端
response.addCookie(cookie);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
運行結(jié)果:


在上面的例子中,在程序代碼中并沒有使用setMaxAge方法設(shè)置cookie的有效期,所以當(dāng)關(guān)閉瀏覽器之后,cookie就失效了,要想在關(guān)閉了瀏覽器之后,cookie依然有效,那么在創(chuàng)建cookie時,就要為cookie設(shè)置一個有效期。如下所示:
//用戶訪問過之后 要重新將時間存儲到cookie中,然后發(fā)送給客戶端
Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+"");
//設(shè)置Cookie的有效期為1天
cookie.setMaxAge(24*60*60);
//將cookie添加到Response對象中 發(fā)送給客戶端
response.addCookie(cookie);
六、Cookie存儲中文
如果要在cookie里面存儲中文,必須先進行編碼,需要用到的一個類是URLEncoder里面的URLDecoder.decode(String s, String enc),否則就會掛掉。程序?qū)伋?code>java.lang.IllegalArgumentException 異常。正確的做法是:
Cookie cookie = new Cookie("username",URLEncoder.encode("我是張三", "utf-8"));
response.addCookie(cookie);
在獲取cookie里面的中文數(shù)據(jù)時,再使用URLDecoder里面的URLDecoder.decode(String s, String enc)進行解碼。如下
URLDecoder.decode(value, "utf-8")