Java Cookie和Session

來源:互聯網
上載者:User

Java Cookie和Session
1.會話技術簡介

http協議是無狀態的,因此對於服務端來說,當它接收到用戶端的http請求時,無法識別這個請求來源於哪個用戶端。無狀態的協議有優點也有缺點,但對於需要識別用戶端甚至是需要記住用戶端的業務來說,應當要讓http協議"有狀態"。

需要記住用戶端的業務種類非常多。例如登陸系統,在一個頁面登入後,新開啟一個該網站頁面,應當也保持登入狀態。再例如購物車系統,某使用者添加商品1後應當保證他還能繼續添加商品2,在結算時能夠讀取購物車中的所有商品。

如何讓服務端記住用戶端?目前使用最多的是cookie和session兩種會話技術。

  • 1.Cookie:資料存放區在用戶端本地,減少伺服器端的儲存的壓力,安全性不好,用戶端可以清除cookie。
  • 2.Session:將資料存放區到伺服器端,安全性相對好,會增加伺服器的壓力。
2.Cookie技術

Cookie技術是將使用者的資料存放區到用戶端的技術,它的作用是為了讓服務端根據每個用戶端持有的cookie來區分不同用戶端。

cookie由cookie name、具有唯一性的cookie value以及一些屬性(path、expires、domain等)構成,其中value是區分用戶端的唯一依據。

Cookie的原理為:服務端在接收到用戶端首次發送的請求後,服務端在響應首部中加入"set-cookie"欄位發送給用戶端;用戶端接收響應後,將cookie資訊儲存到記憶體中(如果設定了MaxAge屬性,則儲存到磁碟中);因為cookie資料在瀏覽器的記憶體中,因此無論是哪個頁面,用戶端再次向服務端發送請求時都能擷取該cookie資訊,並在請求首部中加入"cookie"欄位發送給服務端;服務端藉此就可以識別用戶端,並從cookie中找到該用戶端的資訊。

使用Cookie需要解決的兩個問題:

  • (1).服務端怎樣將一個Cookie發送到用戶端。
  • (2).服務端怎樣接受用戶端攜帶的Cookie。
2.1 伺服器端向用戶端發送Cookie

設定Cookie涉及的幾個常用方法為:

  • Cookie(String cookie_name,String cookie_value):構造一個Cookie對象。
  • setPath(uri):當訪問屬於該uri下的路徑(包括子路徑)時,該cookie都生效,例如setPath("/Cookie"),當本機使用http://localhost/Cookie/servlet1http://localhost/Cookie/servlet2訪問時,都擁有該Cookie。
  • setMaxAge(int second):設定該屬性時,cookie將持久化儲存到用戶端的磁碟中,儲存時間為second秒。如果cookie不具有該屬性,則cookie只會存放在記憶體中。
  • setDomain(String domain):設定Cookie生效的域範圍,例如cookie.setDomain(".foo.com");,這將對foo.com域下的所有主機都生效(如www.foo.com),但不包括子域(www.abc.foo.com)。

設定好Cookie後,需要使用response的方法addCookie(Cookie cookie)將cookie加入到響應首部中發送給用戶端。

例如,以下是名為CooikeDemo工程的一個servlet,該servlet的uri路徑為"/cookieservlet"。

import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class CookieServlet extends HttpServlet {    private static final long serialVersionUID = 1L;    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        Cookie cookie = new Cookie("username","zhangsan");  //構造cookie對象        cookie.setPath("/CookieDemo");       //設定cookie生效的uri範圍        cookie.setMaxAge(10*60);             //設定cookie持久到磁碟的時間為10分鐘        response.addCookie(cookie);          //在響應首部中加入set-cookie欄位並發送給用戶端    }protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    doGet(request, response);}

該cookie將會在響應首部加入set-cookie欄位發送給用戶端:

當用戶端再次請求時,將在請求首部中加入cookie欄位。

需要注意的幾點:

  • (1).Cookie中不能儲存中文。
  • (2).如果不設定持久化時間,cookie會儲存在瀏覽器的記憶體中,瀏覽器關閉時cookie資訊銷毀,這是會話級的cookie。如果設定持久化時間,cookie資訊會被持久化到磁碟中,這是持久層級的cookie。持久化後的cookie不會隨瀏覽器關閉而失效,而是在有效時間內都有效。
  • (3).setPath()設定的生效路徑為目錄時,則cookie對該目錄和子目錄下的資源都生效,如果生效路徑為檔案時,則只對該檔案有效。例如:
    cookie.setPath("/webapp");  //代表訪問webapp應用中的任何資源都攜帶cookiecookie.setPath("/webapp/cookieservlet");  //代表訪問webapp中的cookieservlet時才攜帶cookie資訊
  • (4).如果想要刪除當前還有效cookie資訊,可以使用同名同路徑的持久化時間為0的cookie進行覆蓋。這樣一來,每次用戶端接收到響應後cookie就立即失效,也就無法攜帶cookie請求服務端。例如刪除上面樣本的cookie資訊
    Cookie cookie = new Cookie("username","zhangsan");cookie.setPath("/CookieDemo");cookie.setMaxAge(0);response.addCookie(cookie);
2.2 伺服器端接受用戶端攜帶的Cookie

如前面的圖中所示,用戶端的cookie資訊是以要求標頭的方式發送到伺服器端的。因此服務端要擷取cookie資訊,需要使用request對象中的方法getCookies()。這時唯一的擷取cookie的方法,它返回的是Cookie數組集合,因此需要遍曆該數組才能擷取指定名稱的cookie。

例如,擷取cookie name為"username"的cookie。

Cookie[] cookies = request.getCookies();if(cookies != null) {    for (Cookie coo : cookies) {        String cookie_name = coo.getName();        if (cookie_name.equals("username")) {            String cookie_value = coo.getValue();            System.out.println(cookie_name+":"+cookie_value);        }    }}
3.Session技術

從開啟一個瀏覽器訪問某個網站,到關閉這個瀏覽器的整個過程(釋放瀏覽器記憶體),成為一次會話。除了Cookie技術可以讓服務端在一次會話過程中記住用戶端,Session技術也可以達到這樣的目的。

Session技術將資料存放區在伺服器端,它會為每個用戶端都建立一塊記憶體空間儲存用戶端資料,並為用戶端分配一個儲存在cookie中的JSESSIONID,用戶端需要每次都攜帶一個這個ID,伺服器通過這個ID可以找到屬於該用戶端的記憶體空間。由於這個標識ID是藉助Cookie儲存的唯一性標識JSESSIONID,因此Session是基於Cookie來實現的。

Session的原理:服務端接收到某用戶端首次發送的請求後,為此用戶端產生一個session,並分配一段屬於該session的緩衝區,同時將該session配對的標識號JSESSIONID作為cookie的name添加到響應首部中返回給用戶端;用戶端下次訪問時,請求首部中將攜帶該JSESSIONID,服務端將根據該JSESSIONID尋找與之配對的session,如果能找到對應的session,則直接操作該session資源,否則將重新為此JSESSIONID分配一個session和對應的緩衝區。

使用Session技術需要解決如下三個問題:

  • (1).怎樣獲得屬於某用戶端的session對象(記憶體地區)?
  • (2).怎樣向session中存取資料?
  • (3).session對象的生命週期?
3.1 獲得Session對象

服務端通過用戶端發送cookie中的JSESSIONID區分用戶端,可以通過請求包中的這個資訊來擷取該用戶端相關的session資訊。

HttpSession session = request.getSession();

此方法有兩個作用:

  • (1).從cookie中擷取JSESSIONID,並尋找是否存在該ID對應的session對象。如果存在,則擷取該session對象。
  • (2).如果該用戶端沒有發送JSESSIONID或JSESSIONID和服務端記錄的ID值不匹配,則為該JSESSIONID重新分配一個session對象。

實際上就是根據JSESSIONID判斷該用戶端是否在伺服器上已經存在session了,有則用之,無則分配之。

3.2 向session中存取資料(session也是一個域對象)

session也是一個域對象,session域的作用範圍是整個session,可以對用戶端的多次請求生效。該範圍小於context域(即application域),大於request域(只在一次請求內有效)。

作為域對象,session對象也同樣具有如下三個方法:

session.setAttribute(String name,Object obj);session.getAttribute(String name);session.removeAttribute(String name);

此外,可以通過session對象的getId()方法擷取到該session的JSESSIONID值。

3.3 Session對象的生命週期
  • 建立:第一次執行request.getSession()時建立。
  • 銷毀:
    • 1.伺服器(非正常)關閉時。
    • 2.session到期/失效(預設30分鐘,這個預設時間可以在web.xml中修改)。
      <session-config>  <session-timeout>30</session-timeout></session-config>
      需要注意的是失效時間的起算點,即從何時開始計算30分鐘?從不動作伺服器端的資源開始計時(即從最近一次讀取session資料開始)。
    • 3.手動銷毀session:session.invalidate();

也就是說,用戶端在一次會話中任何資源都共用一個session對象。

問題:瀏覽器關閉,session就銷毀了嗎?
不對,session儲存在服務端,和用戶端沒多大關係,只要用戶端沒有操作session,等一段時間後,session自動銷毀。
但是,關閉瀏覽器後,cookie中的JSESSIONID就丟失了,也就無法再找到對應的session資料。可以在發送session給用戶端前將jsessionid當成cookie的屬性並配置cookie的持久化時間持久化到用戶端磁碟,這樣再次開啟瀏覽器時jsessionid就不會丟失。代碼大致如下:

HttpSession session = request.getSession();session.setAttribute("username","Tom");String id = session.getId();                  //擷取JSESSIONID值Cookie cookie = new Cookie("JSESSIONID",id);  //"JSESSIONID"為固定值cookie.setPath("/CookieDemo");cookie.setMaxAge(12*60*60);   //JSESSIONID持久化儲存12小時response.addCookie(cookie);response.getWriter().write("JSESSIONID:"+id);System.out.println(session.getAttribute("username"));

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.