標籤:servlet cookie session
HTTP無狀態協議
首先我們要知道:
HTTP協議是無狀態協議。
我們知道HTTP協議就是伺服器通過Request從瀏覽器接收和Response向瀏覽器輸出的這麼一個過程(瀏覽器和伺服器的互動過程)。
所謂無狀態也就是完成一個過程後(用戶端和伺服器就斷開了),下一個過程如果需要前面的資訊,它還需要重新進行一次,伺服器不能記住上次的請求。
這樣可能就是在頻繁進行相同的請求傳送時,資料量增大,效率降低。所以,如果在伺服器不需要先前資訊時它的應答就較快。
那麼,如何讓伺服器知道不同的請求是否來自同一個用戶端,就狀態管理問題出現了Cookie和Session。
Cookie
Cookie儲存在用戶端,有兩種實現方式。
方式一
將Cookie儲存到瀏覽器記憶體中
1儲存Cookie。寫到用戶端(addCookie())
public class SetCookie extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {Cookie c1 = new Cookie("password","123");response.addCookie(c1);}} Cookie以鍵值對的形式進行儲存。
2讀取Cookie(通過Http協議傳過去的)
public class ShowCookie extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {Cookie[] Cookies = request.getCookies();for(int i=0; i<Cookies[i];i++){Cookie c = Cookies[i];reponse.getWriter().Println(c.getName() + "," + c.getValue());}}}
此方式,Cookie只能在當前瀏覽器視窗和子視窗中有效,重開瀏覽器無效。所以有一定的限制。
方式二
將Cookie儲存到文字檔
檔案如何產生的,通過限制Cookie的生命期,然後在寫到用戶端,就可以產生文字檔了。
如下例,拿到用戶端IP的例子:
1儲存Cookie。寫到用戶端文字檔
public class SetCookie extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { <span style="font-family:SimSun;"> //<span lang="zh-CN" style="font-family:SimSun;">擷取</span><span lang="en-US" style="font-family:Calibri;">IP</span><span lang="zh-CN" style="font-family:SimSun;">地址</span></span>Cookie c2 = new Cookie("client_ip",request.getRemoteAddr());//設定Cookie的生命週期為1小時,單位秒 c2.setMaxAge(60*60); response.addCookie(c2);response.getWriter().println("SetCookie OK");}}
2 讀取Cookie,同方式一,略。
Cookie說明:
上面兩種方式都是通過Servlet建立一個 Cookie對象,儲存鍵-值對。
1、通過 response的 addCookie方法將該 Cookie資訊添加到相應資訊中。
2、再通過request.getCookies()方法擷取到Cookie資訊。
3、總的來說cookie機制採用的是在用戶端保持狀態的方案。它是在用戶端的工作階段狀態的儲存機制,他需要使用者開啟用戶端的cookie支援。
4、不足:由於Cookie是儲存在用戶端的,相對存在較大的安全隱患,且一般瀏覽器對 Cookie的數目及資料大小有嚴格的限制。所以對一些小數量,安全性的資訊,一般情況下通過Session儲存。
Session
Session儲存在服務端。
由於Session的是將會話儲存在服務端,關閉瀏覽器(或新開)就沒了。但是這麼多的使用者Session,如何區分?這就需要一個SessionID,每一個SessionID都指向了唯一的一個使用者會話。但是用戶端如何知道SessionID呢,方式有兩種。
方式一
在Cookie中儲存SessionID
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲得 HttpSession對象 HttpSession session = request.getSession(); //設定 Session對象的最長不活動間隔 session.setMaxInactiveInterval(30); //擷取 Session中的資料 List list = (List)session.getAttribute("list"); if (list == null) { list = new ArrayList(); list.add("hey"); //向 Session中添加資料 session.setAttribute("list", list); } }
方式二
如果禁用了Cookie?通過URL重寫,SessionId可以儲存在URL後面
URL重寫:
public class UrlRewriterSession extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {HttpSession session = request.getSession(true);response.getWriter().println("<a href= '" + response.encodeURL(request.getRequestURL().toString()) + "'>UrlRewrite</a>");}}不論用戶端是否禁用Cookie。如果想安全使用Session,只能使用URL重寫,但相應的會增加編程負擔,所以有時網站要求用戶端開啟Cookie。
總結
相比Cookie,Session其實在之前ASP.net中已經用的很多了,當時真是覺得真好用,把值放到Session中,什麼時候用直接取,不用再查資料庫了,太方便了,以至於快到了濫用的趨勢,然而過度使用session將會導致代碼不可讀而且不好維護,並且Session的預設失效期是30分鐘,如果在Session中放入了大的對象,伺服器的壓力可想而知。所以Session的使用也需要有度。