session是服務(wù)器端技術(shù),利用這個技術(shù),服務(wù)器在運行時可以為每一個用戶的瀏覽器創(chuàng)建一個其獨享的session對象,注意是默認(rèn)情況下,一個瀏覽器獨占一個session,由于session為用戶瀏覽器獨享,所以用戶在訪問服務(wù)器的web資源時,可以把各自數(shù)據(jù)存放在各自的session中,當(dāng)用戶再去訪問服務(wù)器的其他web資源時,其他web資源再從用戶各自的session中取出數(shù)據(jù)為用戶服務(wù)。
session和cookie的主要區(qū)別:
cookie技術(shù)是客戶端技術(shù),是由服務(wù)器將用戶的數(shù)據(jù)寫回給用戶瀏覽器的。
session技術(shù)是服務(wù)器端技術(shù),是把用戶的數(shù)據(jù)寫到服務(wù)器為用戶所創(chuàng)建的獨享的session對象中,但session是基于cookie的。
session對象由服務(wù)器創(chuàng)建,這跟cookie不一樣。編程人員可以通過request請求對象的getsession()方法獲取session對象。
注意,session一旦創(chuàng)建,是會存活無操作情況(或者瀏覽器關(guān)閉)下30分鐘,這是由服務(wù)器(如tomcat)來指定的。當(dāng)我們關(guān)閉瀏覽器后,因為session是基于cookie的,因此session是存在的,只是我們可能無法再使用到(要看cookie是否還能取到)。
那么我們以一個簡單的session例子來說明,創(chuàng)建兩個servlet:分別命名為servletdemo1和servletdemo2。
在servletdemo1中的代碼如下:
1
2
3
|
httpsession session = request.getsession(); string data = "message form sessiondemo" ; session.setattribute( "data" , data); |
在servletdemo2中的代碼如下:
1
2
3
4
5
6
|
response.setcontenttype( "text/html;charset=utf-8" ); printwriter writer = response.getwriter(); httpsession session = request.getsession(); string data = (string) session.getattribute( "data" ); writer.write(data); |
當(dāng)我們打開一個瀏覽器先訪問servletdemo1,此時瀏覽器會幫我們創(chuàng)建session對象,并保存數(shù)據(jù),這時再訪問servletdemo2可以看到該保存的數(shù)據(jù):
說明session確實能保存訪問不同servlet時的數(shù)據(jù)。
這里說清楚一點,雖然代碼都是相同的,但是針對不同瀏覽器訪問的話看到的是不同的session對象保存的不同的數(shù)據(jù),雖然這時候數(shù)據(jù)都是一樣的。比如說a在自己主機上訪問這個servlet和b在自己電腦上訪問這個相同的servlet,a和b得到各自的session。
而如果我們打開一個瀏覽器訪問servletdemo1后,再打開另一個瀏覽器訪問servletdemo2,那么則會顯示該數(shù)據(jù)找不到:
注意:這時候是兩個瀏覽器,即已經(jīng)是兩個會話了!!!
我們來做一個類似于點擊商品然后能加入到購物車的案例,使用session技術(shù)。
前提準(zhǔn)備,我們需要為商品創(chuàng)建javabean,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
public class product { private string id; private string name; private string author; public product() { super (); } public product(string id, string name, string author) { super (); this .id = id; this .name = name; this .author = author; } public string getid() { return id; } public void setid(string id) { this .id = id; } public string getname() { return name; } public void setname(string name) { this .name = name; } public string getauthor() { return author; } public void setauthor(string author) { this .author = author; } |
然后再建立一個數(shù)據(jù)庫,以類的方式來創(chuàng)建(誰讓數(shù)據(jù)庫還沒學(xué)呢t_t!),然后使用map集合來存儲數(shù)據(jù),便于通過鍵值對檢索:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class productdatabase { private static map<string,product> map = new hashmap<string,product>(); static { map.put( "1" , new product( "1" , "《java編程思想》" , "jb" )); map.put( "2" , new product( "2" , "《java核心技術(shù)》" , "fdaf" )); map.put( "3" , new product( "3" , "《java并發(fā)編程》" , "什么鬼" )); map.put( "4" , new product( "4" , "《head first 設(shè)計模式》" , "老王" )); map.put( "5" , new product( "5" , "《html5權(quán)威手冊》" , "hhaa" )); } public static map<string,product> getmap() { return map; } } |
好了,我們在商品顯示的首頁顯示商品,同時為每個商品建立一個超鏈接,以便于當(dāng)用戶點擊超鏈接時能將商品的id作為存儲數(shù)據(jù)的依據(jù)由其他servlet類獲取用戶購買的商品種類:
1
2
3
4
5
6
7
8
9
10
|
response.setcharacterencoding( "utf-8" ); response.setcontenttype( "text/html;charset=utf-8" ); printwriter writer = response.getwriter(); //獲取數(shù)據(jù)庫中的商品數(shù)據(jù) map<string, product> map = productdatabase.getmap(); for (map.entry<string, product> entry : map.entryset()) { product book = entry.getvalue(); writer.print(book.getname()+ " <a href='/myservlet/servlet/buysession?id=" +book.getid()+ "' >購買</a> <br/>" ); } |
此時可以看一看效果:
接著我們來做 點擊購買超鏈接后的servlet,該servlet需要將獲取用戶所購買的商品(通過id號),同時需要獲取(創(chuàng)建)session對象,并利用一個集合將所購買的商品存入,這個session對象存儲用戶希望購買的商品,當(dāng)我們跳轉(zhuǎn)到購物車頁面上時能從session中取出商品并顯示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//獲取用戶所購買商品的id號 string productid = request.getparameter( "id" ); product book = productdatabase.getmap().get(productid); //將用戶所購買的商品加入到session對象中保存,以便最后一起結(jié)賬,類似于購物車功能 httpsession session = request.getsession(); list<product> list = (list<product>) session.getattribute( "productlist" ); if (list == null ){ //首次購買 list = new arraylist<product>(); session.setattribute( "productlist" , list); } list.add(book); //跳轉(zhuǎn)到購物車列表上 response.sendredirect( "/myservlet/servlet/cartlistservlet" ); |
注意:這里使用的是sendredirect重定向,如果使用的是forward轉(zhuǎn)發(fā),則在購物車頁面進(jìn)行刷新的話會將每次購買的商品再次購買。
在購物車頁面的servlet中功能就可以比較簡單了,從用戶的session中取出保存的購買商品對象,并顯示在頁面上即可:
1
2
3
4
5
6
7
8
9
10
11
|
response.setcharacterencoding( "utf-8" ); response.setcontenttype( "text/html;charset=utf-8" ); printwriter writer = response.getwriter(); writer.print( "您購買的商品如下: <br/>" ); httpsession session = request.getsession(); list<product> list = (list<product>) session.getattribute( "productlist" ); for (product p : list) { writer.write(p.getname()+ "<br/>" ); } |
點擊多個商品,會看到在購物車的servlet頁面上會顯示出我們購買的商品:
而另外開啟的多個瀏覽器點擊這些商品會看到購買的不同購物車頁面,所以可以使用session來解決不同用戶來訪問相同頁面而同時保存他們各自不同數(shù)據(jù)的需求。
當(dāng)然這只是一個簡單的強調(diào)session對象能在一個會話過程中保存一個瀏覽器訪問多個servlet中會產(chǎn)生的數(shù)據(jù),上面這樣的簡單示例肯定是不能用于購物的,比如當(dāng)我們將瀏覽器關(guān)閉時(會話結(jié)束),這個session對象就結(jié)束了,那么下次再打開瀏覽器我們的購物車將一無所有,如果要滿足用戶的不同需求,那么就要了解一些session對象的底層結(jié)構(gòu)