【菜鳥學Java】11:Session技術

連江偉發表於2016-02-16

        【什麼是Session?】

        Session:在計算機中,尤其是在網路應用中,稱為“會話控制”。Session 物件儲存特定使用者會話所需的資訊。這樣,當使用者在應用程式的 Web 頁之間跳轉時,儲存在 Session 物件中的變數將不會丟失,而是在整個使用者會話中一直存在下去。當使用者請求來自應用程式的 Web 頁時,如果該使用者還沒有會話,則 Web 伺服器將自動建立一個 Session 物件。當會話過期或被放棄後,伺服器將終止該會話。

        【為何用Session?】

        Session技術是為何出現的?這是因為目前網路中所使用的http協議是一種無狀態的協議,簡單來說就是當你向伺服器傳送一次請求,然後再一次傳送請求到服務端,對於伺服器來講,它是不知道你的第一次請求和第二次請求是來源於同一個人或者說是同一個客戶端。這樣的話就使我們的客戶端和服務端的互動非常的麻煩,就好比是我們每一個人都沒有了記憶,你剛對一個人介紹完自己,當你再次和那個人交談,他依然會問:Who are you?

        而Session技術就很好的解決了這個問題,如果沒有Session,舉個簡單的例子:當你在一個頁面提交請求資料,頁面跳轉之後,下一個頁面就不能獲得你上個頁面的請求資料。

        關於Session的原理,我從網上找了一張圖,相信可以更好的幫助大家理解到底Session是如何工作的,來保證在一個會話中共享資料。如下圖所示:

        【怎麼用Session?】

        Session在網路程式設計中應用廣泛,比如我們在登陸各種網站的時候需要填寫的驗證碼,在各大電商網站中購物時的那個購物車等等,都是Session技術的應用場景。下面我就舉一個大家都很熟悉的購物車的示例,一起來看看Session如何用在我們的專案開發中,當然這些都是比較簡單的demo,僅作參考,不是大型網站購物車的實現方法,切記。

        既然我們要做購物車的demo,那麼需要建立兩個頁面,一個商品列表頁和一個購物車的頁面,然後建立一個Servlet用來處理前臺頁面的請求,就這麼簡單。來看具體的程式碼:

        處理請求的Servlet類CServlet:

public class CServlet extends HttpServlet {


	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
			//1 獲得 使用者想要新增的商品資訊
				String  name = request.getParameter("name");//0
				//將提交的商品編號翻譯成商品的中文名稱
				String[] products  = new String[]{"肥皂","蠟燭","床單","攝影機","內衣","襪子"};
				String productName = products[Integer.parseInt(name)]; //終端使用者要新增的商品名稱
			//2 獲得session
				HttpSession session  = request.getSession();
			//3 從session取得儲存購物車資訊的map
				Map<String,Integer> cart = (Map<String, Integer>) session.getAttribute("cart");
				if(cart !=null){
					//取到 ==> 不是第一次新增 ==>繼續新增
					Integer count = cart.get(productName);
					if(count!=null){
						cart.put(productName,count+1);
					}else{
						cart.put(productName,1);
					}
				}else{
					//沒取到 ==>  第一次新增 ==> 建立出map新增
					cart = new LinkedHashMap<String, Integer>();
					cart.put(productName,1);
				}
			//4將map重新放回session域
				session.setAttribute("cart", cart);
			//5頁面重定向到列表頁面繼續購物
				response.sendRedirect(request.getContextPath()+"/shopping/list.jsp");

	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);
	}
}

        商品列表頁list.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>商品列表</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>

<body>
<a href="/day11-session/shopping/cart.jsp" >檢視購物車</a>
	<table border="1" align="center" >
		<tr>
			<td>
				<h3>肥皂</h3>
				<img src="/day11-session/img/haha (1).jpg" width="100" height="100" /><br/>
				<a href="/day11-session/CServlet?name=0">加入購物車</a>
			</td>
			<td>
				<h3>蠟燭</h3>
				<img src="/day11-session/img/haha (2).jpg" width="100" height="100" /><br/>
				<a href="/day11-session/CServlet?name=1">加入購物車</a>
			</td>
		</tr>
		<tr>
			<td>
				<h3>床單</h3>
				<img src="/day11-session/img/haha (3).jpg" width="100" height="100" /><br/>
				<a href="/day11-session/CServlet?name=2">加入購物車</a>
			</td>
			<td>
				<h3>攝像機</h3>
				<img src="/day11-session/img/haha (4).jpg" width="100" height="100" /><br/>
				<a href="/day11-session/CServlet?name=3">加入購物車</a>
			</td>
		</tr>
		<tr>
			<td>
				<h3>內衣</h3>
				<img src="/day11-session/img/haha (5).jpg" width="100" height="100" /><br/>
				<a href="/day11-session/CServlet?name=4">加入購物車</a>
			</td>
			<td>
				<h3>襪子</h3>
				<img src="/day11-session/img/haha (6).jpg" width="100" height="100" /><br/>
				<a href="/day11-session/CServlet?name=5">加入購物車</a>
			</td>
		</tr>
		
	</table>
		<a href="/day11-session/shopping/cart.jsp">檢視購物車</a>
</body>
</html>

        購物車頁面cart.jsp

<%@page import="java.util.Map.Entry"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>購物車</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
  	<%
  		//1 獲得session
  			//HttpSession session = request.getSession();
  		//2 從session中取得 儲存購物車資訊的map
  		Map<String,Integer> cart = 	(Map<String,Integer>)session.getAttribute("cart");
  		//3 遍歷map 在頁面上顯示
  		%>
   		<table border="1" align="center">
   			<tr><th>商品名稱</th><th>商品數量</th></tr>
   			<% 
  		for(Entry<String,Integer> en : cart.entrySet()){
  			%>
   			<tr><td><%=en.getKey()%></td><td><%=en.getValue() %></td></tr>
  			<% 
  		}
  			%>
   		</table>
   		<a href="/day11-session/shopping/list.jsp">繼續購物</a>
  </body>
</html>

        執行程式我們隨便選幾樣商品來看看是否能夠滿足我們的需求,如下圖所示:


        小結一下:

        談到Session,就不得不說cookie,因為Session的一些必要資訊是存放在cookie中的,比如最為重要的session_id,可能在某些情況下,Session是必須依賴於cookie才可以發揮其作用的。當然如果禁用了瀏覽器的cookie時,我們還是可以通過URL來將SessionID傳給伺服器的。那麼Session和Cookie具體有哪些區別呢?

        1首先需要大家明白的是,cookie資訊是存放在客戶的瀏覽器上的,而Session資料是存放在伺服器上的。

        2相比較Session來講,cookie是很不安全的,高手可以通過分析存放在本地的cookie資訊並且利用cookie欺騙跳過瀏覽器,直接對通訊資料進行改寫,而Session的安全性相對高些,對於一些敏感資訊,最好使用Session。

        3Session會在一定時間內儲存在伺服器上,當訪問量劇增的時候,伺服器的效能將會大打折扣,此時使用cookie則可以減輕伺服器的壓力。

        4單個cookie儲存的資料不能超過4k,而且很多瀏覽器都會限制一個站點儲存的cookie數量,因此大量的資料使用Session比較好。

相關文章