在學習完了Servlet中的Cookie技術後,我們再來學習另一個能儲存會話資料的技術——Session。
Session是伺服器端技術,利用這個技術,伺服器在運作時可以為每一個使用者的浏覽器建立一個其獨享的session對象,注意是預設情況下,一個浏覽器獨占一個session,由于session為使用者浏覽器獨享,是以使用者在通路伺服器的web資源時,可以把各自資料存放在各自的session中,當使用者再去通路伺服器的其他web資源時,其他web資源再從使用者各自的session中取出資料為使用者服務。
Session和Cookie的主要差別:
Cookie技術是用戶端技術,是由伺服器将使用者的資料寫回給使用者浏覽器的。
Session技術是伺服器端技術,是把使用者的資料寫到伺服器為使用者所建立的獨享的Session對象中,但Session是基于Cookie的(請看下一篇《Servlet的學習之Session(2)》)。
Session對象由伺服器建立,這跟Cookie不一樣。程式設計人員可以通過request請求對象的getSession()方法擷取Session對象。
注意,Session一旦建立,是會存活無操作情況(或者浏覽器關閉)下30分鐘,這是由伺服器(如Tomcat)來指定的。當我們關閉浏覽器後,因為Session是基于cookie的,是以Session是存在的,隻是我們可能無法再使用到(要看cookie是否還能取到)。
那麼我們以一個簡單的Session例子來說明,建立兩個Servlet:分别命名為ServletDemo1和ServletDemo2。
在ServletDemo1中的代碼如下:
1 HttpSession session = request.getSession();
2 String data = "message form SessionDemo1";
3 session.setAttribute("data", data);
在ServletDemo2中的代碼如下:
1 response.setContentType("text/html;charset=utf-8");
2 PrintWriter writer = response.getWriter();
3
4 HttpSession session = request.getSession();
5 String data = (String) session.getAttribute("data");
6 writer.write(data);
當我們打開一個浏覽器先通路ServletDemo1,此時浏覽器會幫我們建立Session對象,并儲存資料,這時再通路ServletDemo2可以看到該儲存的資料:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyADNzYjN2ETNtEjN2QDMyETOxMjMwETNxAjMtYzN4cDO38CXwETNxAjMvwlN3gzN4czLcd2bsJ2Lc12bj5ycn9Gbi52YuUTMwIzcldWYtl2Lc9CX6MHc0RHaiojIsJye.png)
說明Session确實能儲存通路不同Servlet時的資料。
這裡說清楚一點,雖然代碼都是相同的,但是針對不同浏覽器通路的話看到的是不同的Session對象儲存的不同的資料,雖然這時候資料都是一樣的。比如說A在自己主機上通路這個Servlet和B在自己電腦上通路這個相同的Servlet,A和B得到各自的Session。
而如果我們打開一個浏覽器通路ServletDemo1後,再打開另一個浏覽器通路ServletDemo2,那麼則會顯示該資料找不到:
注意:這時候是兩個浏覽器,即已經是兩個會話了!!!
我們來做一個類似于點選商品然後能加入到購物車的案例,使用Session技術。
前提準備,我們需要為商品建立JavaBean,代碼如下:
1 public class Product {
2 private String id;
3 private String name;
4 private String author;
5
6 public Product() {
7 super();
8 }
9
10 public Product(String id, String name, String author) {
11 super();
12 this.id = id;
13 this.name = name;
14 this.author = author;
15 }
16
17 public String getId() {
18 return id;
19 }
20
21 public void setId(String id) {
22 this.id = id;
23 }
24
25 public String getName() {
26 return name;
27 }
28
29 public void setName(String name) {
30 this.name = name;
31 }
32
33 public String getAuthor() {
34 return author;
35 }
36
37 public void setAuthor(String author) {
38 this.author = author;
39 }
然後再建立一個資料庫,以類的方式來建立(誰讓資料庫還沒學呢T_T!),然後使用Map集合來存儲資料,便于通過鍵值對檢索:
1 public class ProductDatabase {
2
3 private static Map<String,Product> map = new HashMap<String,Product>();
4
5 static{
6 map.put("1", new Product("1","《Java程式設計思想》","JB"));
7 map.put("2", new Product("2","《Java核心技術》","fdaf"));
8 map.put("3", new Product("3","《Java并發程式設計》","什麼鬼"));
9 map.put("4", new Product("4","《Head first 設計模式》","老王"));
10 map.put("5", new Product("5","《HTML5權威手冊》","hhaa"));
11 }
12
13 public static Map<String,Product> getMap() {
14
15 return map;
16 }
17 }
好了,我們在商品顯示的首頁顯示商品,同時為每個商品建立一個超連結,以便于當使用者點選超連結時能将商品的id作為存儲資料的依據由其他Servlet類擷取使用者購買的商品種類:
1 response.setCharacterEncoding("UTF-8");
2 response.setContentType("text/html;charset=utf-8");
3 PrintWriter writer = response.getWriter();
4
5 //擷取資料庫中的商品資料
6 Map<String, Product> map = ProductDatabase.getMap();
7 for(Map.Entry<String, Product> entry : map.entrySet()) {
8 Product book = entry.getValue();
9 writer.print(book.getName()+" <a href='/myservlet/servlet/BuySession?id="+book.getId()+"' >購買</a> <br/>");
10 }
此時可以看一看效果:
接着我們來做 點選購買超連結後的Servlet,該Servlet需要将擷取使用者所購買的商品(通過id号),同時需要擷取(建立)Session對象,并利用一個集合将所購買的商品存入,這個Session對象存儲使用者希望購買的商品,當我們跳轉到購物車頁面上時能從Session中取出商品并顯示:
1 //擷取使用者所購買商品的id号
2 String productId = request.getParameter("id");
3 Product book = ProductDatabase.getMap().get(productId);
4
5 //将使用者所購買的商品加入到Session對象中儲存,以便最後一起結賬,類似于購物車功能
6 HttpSession session = request.getSession();
7 List<Product> list = (List<Product>) session.getAttribute("productList");
8 if(list == null){
9 //首次購買
10 list = new ArrayList<Product>();
11 session.setAttribute("productList", list);
12 }
13
14 list.add(book);
15
16 //跳轉到購物車清單上
17 response.sendRedirect("/myservlet/servlet/CartListServlet");
18
注意:這裡使用的是sendRedirect重定向,如果使用的是forward轉發,則在購物車頁面進行重新整理的話會将每次購買的商品再次購買。
在購物車頁面的Servlet中功能就可以比較簡單了,從使用者的Session中取出儲存的購買商品對象,并顯示在頁面上即可:
1 response.setCharacterEncoding("UTF-8");
2 response.setContentType("text/html;charset=utf-8");
3 PrintWriter writer = response.getWriter();
4
5 writer.print("您購買的商品如下: <br/>");
6
7 HttpSession session = request.getSession();
8 List<Product> list = (List<Product>) session.getAttribute("productList");
9 for(Product p : list) {
10 writer.write(p.getName()+"<br/>");
11 }
點選多個商品,會看到在購物車的Servlet頁面上會顯示出我們購買的商品:
而另外開啟的多個浏覽器點選這些商品會看到購買的不同購物車頁面,是以可以使用Session來解決不同使用者來通路相同頁面而同時儲存他們各自不同資料的需求。
當然這隻是一個簡單的強調session對象能在一個會話過程中儲存一個浏覽器通路多個Servlet中會産生的資料,上面這樣的簡單示例肯定是不能用于購物的,比如當我們将浏覽器關閉時(會話結束),這個session對象就結束了,那麼下次再打開浏覽器我們的購物車将一無所有,如果要滿足使用者的不同需求,那麼就要了解一些session對象的底層結構,将在下一篇中介紹和學習。