JavaWeb(二)會話管理之細說cookie與session

來源:互聯網
上載者:User

標籤:www.   辦理   etc   中介   tco   記事本   通知   redirect   class   

前言

  前面花了幾篇部落格介紹了Servlet,講的非常的詳細。這一篇給大家介紹一下cookie和session。

一、會話概述1.1、什麼是會話?

  會話可簡單理解為:使用者開一個瀏覽器,點擊多個超連結,訪問伺服器多個web資源,然後關閉瀏覽器,整個過程稱之為一個會話。

  一次會話指的是:就好比打電話,A給B打電話,接通之後,會話開始,直到掛斷電話,該次會話就結束了,而瀏覽器訪問伺服器,就跟打電話一樣,瀏覽器A給伺服器發送請求,訪問web程式,該次會話就已經接通,

          其中不管瀏覽器發送多少請求(就相當於接通電話後說話一樣),都視為一次會話,直到瀏覽器關閉,本次會話結束。其中注意,一個瀏覽器就相當於一部電話,如果使用Firefox瀏覽器,訪問伺服器,就是一次會話了,

          然後開啟google瀏覽器,訪問伺服器,這是另一個會話,雖然是在同一台電腦,同一個使用者在訪問,但是,這是兩次不同的會話。

1.2、會話機制

  Web程式中常用的技術,用來跟蹤使用者的整個會話。常用的會話跟蹤技術是Cookie與Session。Cookie通過在用戶端記錄資訊確定使用者身份,Session通過在伺服器端記錄資訊確定使用者身份。

  知道了什麼是會話後,思考一個問題,一個瀏覽器訪問一個伺服器就能建立一個會話,如果別的電腦,都同時訪問該伺服器,就會建立很多會話,就拿一些購物網站來說,我們訪問一個購物網站的伺服器,會話就被建立了,

  然後就點擊瀏覽商品,對感興趣的商品就先加入購物車,等待一起付賬,這看起來是很普通的操作,但是想一下,如果有很多別的電腦上的瀏覽器同時也在訪問該購物網站的伺服器,跟我們做類似的操作呢?伺服器又是怎麼記住使用者,

  怎麼知道使用者A購買的任何商品都應該放在A的購物車內,不論是使用者A什麼時間購買的,不能放入使用者B或使用者C的購物車內的呢?所以就有了cookie和session這兩個技術,cookie和session用來跟蹤使用者的整個會話。

  會話要解決的問題:    

    每個使用者在使用瀏覽器與伺服器進行會話的過程中,不可避免各自會產生一些資料,程式要想辦法為每個使用者儲存這些資料。
    例如:使用者點擊超連結通過一個servlet購買了一個商品,程式應該想辦法儲存使用者購買的商品,以便於使用者點結帳servlet時,結帳servlet可以得到使用者購買的商品為使用者結帳。

二、cookie和session概述2.1、cookie

  Cookie是用戶端技術,程式把每個使用者的資料以cookie的形式寫給使用者各自的瀏覽器。當使用者使用瀏覽器再去訪問伺服器中的web資源時,就會帶著各自的資料去。這樣,web資源處理的就是使用者各自的資料了。

  由於cookie是由用戶端瀏覽器儲存和攜帶的,所以稱之為用戶端技術:API中介紹

    

2.2、session  

  Session是伺服器端技術,利用這個技術,伺服器在運行時可以為每一個使用者的瀏覽器建立一個其獨享的HttpSession對象,由於session為使用者瀏覽器獨享,所以使用者在訪問伺服器的web資源時,

  可以把各自的資料放在各自的session中,當使用者再去訪問伺服器中的其它web資源時,其它web資源再從使用者各自的session中取出資料為使用者服務。

2.3、Cookie和Session之間的區別和聯絡

  假如一個咖啡店有喝5杯咖啡免費贈一杯咖啡的優惠,然而一次性消費5杯咖啡的機會微乎其微,這時就需要某種方式來紀錄某位顧客的消費數量。想象一下其實也無外乎下面的幾種方案: 

    1)該店的店員很厲害,能記住每位顧客的消費數量,只要顧客一走進咖啡店,店員就知道該怎麼對待了。這種做法就是協議本身支援狀態。但是http協議本身是無狀態的。

    2)發給顧客一張卡片,上面記錄著消費的數量,一般還有個有效期間限。每次消費時,如果顧客出示這張卡片,則此次消費就會與以前或以後的消費相聯絡起來。

      這種做法就是在用戶端保持狀態。也就是cookie。 顧客就相當於瀏覽器,cookie如何工作,下面會詳細講解

    3)發給顧客一張會員卡,除了卡號之外什麼資訊也不紀錄,每次消費時,如果顧客出示該卡片,則店員在店裡的紀錄本上找到這個卡號對應的紀錄添加一些消費資訊。這種做法就是在伺服器端保持狀態。

  由於HTTP協議是無狀態的,而出於種種考慮也不希望使之成為有狀態的,因此,後面兩種方案就成為現實的選擇。具體來說cookie機制採用的是在用戶端保持狀態的方案,而session機制採用的是在伺服器端保持狀態的方案。

  同時我們也看到,由於採用伺服器端保持狀態的方案在用戶端也需要儲存一個標識,所以session機制可能需要藉助於cookie機制來達到儲存標識的目的,但實際上它還有其他選擇。

三、Cookie

  上面已經介紹了為什麼要使用Cookie,以及Cookie的一些特點,比如儲存在用戶端,用來記錄使用者身份資訊的,現在來看看如何使用Cookie。

  藉著上面會員卡的例子來說,採用的是第二種方案,其中還需要解決的問題就是:如何分發會員卡,會員卡的內容,客戶如何使用會員卡,會員卡的有效日期,會員卡的使用範圍

  1)如何分發會員卡、會員卡的內容:也就是cookie是如何建立的?建立後如何發送給用戶端?

    由伺服器進行建立,也就相當於咖啡店來建立會員卡,在建立會員卡的同時,就會將會員卡中的內容也給設定了   

    Cookie cookie = new Cookie(key,value);  //以索引值對的方式存放內容,    response.addCookie(cookie);  //發送回瀏覽器端   

    注意:一旦cookie建立好了,就不能在往其中增加別的索引值對,但是可以修改其中的內容,        

     cookie.setValue();  //將key對應的value值修改

  2)客戶如何使用會員卡,cookie在用戶端是如何工作的,工作原理是什嗎? 

    圖一:

      

    圖二:

      

    這個過程就相當於,咖啡店建立好了會員卡,並且已經設定了其中的內容,交到了客戶手中,下次客戶過來時,就帶著會員卡過來,就知道你是會員了,然後咖啡店就拿到你的會員卡對其進行操作。

  3)會員卡的有效日期?也就是cookie也是擁有有效日期的。   

    這個可以自由設定,預設是關閉瀏覽器,cookie就沒用了。    

  cookie.setMaxAge(expiry);  //設定cookie被瀏覽器儲存的時間。      expiry:單位秒,預設為-1,      expiry=-1:代表瀏覽器關閉後,也就是會話結束後,cookie就失效了,也就沒有了。       expiry>0:代表瀏覽器關閉後,cookie不會失效,仍然存在。並且會將cookie儲存到硬碟中,直到設定時間到期才會被瀏覽器自動刪除,      expiry=0:刪除cookie。不管是之前的expiry=-1還是expiry>0,當設定expiry=0時,cookie都會被瀏覽器給刪除。 

   4)會員卡的使用範圍?

    比如:星巴克在北京有一個分店,在上海也有一個分店,我們只是在北京的星巴克辦理了會員卡,那麼當我們到上海時,就不能使用該會員卡進行打折優惠了。

        而cookie也是如此,可以設定伺服器端擷取cookie的訪問路徑,而並非在伺服器端的web項目中所有的servlet都能訪問該cookie。

    cookie預設路徑:當前訪問的servlet父路徑。

      例如:http://localhost:8080/test01/a/b/c/SendCookieServlet

      預設路徑:/test01/a/b/c  也就是說,在該預設路徑下的所有Servlet都能夠擷取到cookie,/test01/a/b/c/MyServlet 這個MyServlet就能擷取到cookie。

    修改cookie的訪問路徑

      setPath("/");  //在該伺服器下,任何項目,任何位置都能擷取到cookie。

      用途:保證在tomcat下所有的web項目可以共用相同的cookie 

      例如:tieba , wenku , beike 多重專案共用資料。例如使用者名稱。

      setPath("/test01/");  //在test01項目下任何位置都能擷取到cookie。

四、詳解Cookie4.1、Cookie的工作流程

  1)servlet建立cookie,儲存少量資料,發送瀏覽器。
  2)瀏覽器獲得伺服器發送的cookie資料,將自動的儲存到瀏覽器端。
  3)下次訪問時,瀏覽器將自動攜帶cookie資料發送給伺服器。

4.2、Cookie操作

  1)建立cookie:new Cookie(name,value)
  2)發送cookie到瀏覽器:HttpServletResponse.addCookie(Cookie)
  3)servlet接收cookie:HttpServletRequest.getCookies() 瀏覽器發送的所有cookie

4.3、Cookie特點

  1)每一個cookie檔案大小:4kb , 如果超過4kb瀏覽器不識別
  2)一個web網站(web項目):發送20個
  3)一個瀏覽器儲存總大小:300個
  4)cookie 不安全,可能泄露使用者資訊。瀏覽器支援禁用cookie操作。
  5) 預設情況生命週期:與瀏覽器會話一樣,當瀏覽器關閉時cookie銷毀的。---臨時cookie

4.4、Cookie API
  getName() 獲得名稱,cookie中的key  getValue() 獲得值,cookie中的value  setValue(java.lang.String newValue)  設定內容,用於修改key對應的value值。  setMaxAge(int expiry) 設定有效時間【】  setPath(java.lang.String uri)  設定路徑【】    setDomain(java.lang.String pattern) 設定網域名稱 , 一般無效,有瀏覽器自動化佈建,setDomain(".zyh.com")    www.zyh.com / bbs.zyh.com 都可以訪問    a.b.zyh.com無法訪問    作用:設定cookie的作用範圍,網域名稱+路徑在一起就構成了cookie的作用範圍,上面單獨設定的setPath有用,是因為有瀏覽器自動化佈建該網域名稱屬性,但是我們必須知道有這麼個屬性進行網域名稱設定的  isHttpOnly()  是否只是http協議使用。只能servlet的通過getCookies()獲得,javascript不能獲得。  setComment(java.lang.String purpose) (瞭解)  //對該cookie進行描述的資訊(說明作用),瀏覽器顯示cookie資訊時能看到  setSecure(boolean flag) (瞭解)  是否使用安全傳輸協議。為true時,只有當是https請求串連時cookie才會發送給伺服器端,而http時不會,但是服務端還是可以發送給瀏覽端的。  setVersion(int v) (瞭解)  參數為0(傳統Netscape cookie規範編譯)或1(RFC 2109規範編譯)。這個沒用到,不是很懂

  注意:cookie不能發送中文,如果要發送中文,就需要進行特別處理。

  JDK提供工具,進行編碼:

    URLEncoder:編碼

    URLDecoder:解碼

      //發送cookie      Cookie cookie = new Cookie(URLEncoder.encode("哈哈"),URLEncoder.encode("呵呵"));      response.addCookie(cookie);      //獲得cookie中文內容      URLDecoder.decoder(request.getCookie().getName);  //擷取key      URLDecoder.decoder(request.getCookie().getValue);  //擷取value
4.5、Cookie應用

  1)記住使用者名稱

    登入時,在伺服器端擷取到使用者名稱,然後建立一個cookie,將使用者名稱存入cookie中,發送回瀏覽器端,然後瀏覽器下次在訪問登入頁面時,先拿到cookie,將cookie中的資訊拿出來,

    看是否儲存了該使用者名稱,如果儲存了,那麼直接用他,如果沒有,則自己手寫使用者名稱。

  2)記錄

    比如購物網站,都會有我們的瀏覽記錄的,實現原理其實也是用cookie技術,每瀏覽一個商品,就將其存入cookie中,到需要顯示瀏覽記錄時,只需要將cookie拿出來遍曆即可。

五、Session

  在上面的介紹中我們知道:

    在WEB開發中,伺服器可以為每個使用者瀏覽器建立一個會話對象(session對象),注意:一個瀏覽器獨佔一個session對象(預設情況下)。

    因此,在需要儲存使用者資料時,伺服器程式可以把使用者資料寫到使用者瀏覽器獨佔的session中,當使用者使用瀏覽器訪問其它程式時,其它程式可以從使用者的session中取出該使用者的資料,為使用者服務。    

  同樣,會員卡的例子的第三種方法,發給顧客一張會員卡,除了卡號之外什麼資訊也不紀錄,每次消費時,如果顧客出示該卡片,則店員在店裡的記事本上找到這個卡號對應的紀錄添加一些消費資訊。

  這種做法就是在伺服器端保持狀態。 這就是session的用法,在伺服器端來保持狀態,儲存一些使用者資訊。  

    功能作用:伺服器用於共用資料技術 

      

5.1、session原理分析

    我們通過兩幅圖來描述一下:雖然代碼相同,但不同瀏覽器得到的各自的資料

        

    原理分析圖:伺服器是如何?一個session為一個使用者瀏覽器服務的

      

    首先瀏覽器請求伺服器訪問web網站時,程式需要為用戶端的請求建立一個session的時候,伺服器首先會檢查這個用戶端請求是否已經包含了一個session標識、稱為SESSIONID,

    如果已經包含了一個sessionid則說明以前已經為此用戶端建立過session,伺服器就按照sessionid把這個session檢索出來使用,如果用戶端請求不包含session id,則伺服器為此用戶端建立一個session並且

    產生一個與此session相關聯的session id,sessionid 的值應該是一個既不會重複,又不容易被找到規律以仿造的字串,這個sessionid將在本次響應中返回到用戶端儲存,儲存這個sessionid的方式就可以是cookie,

    這樣在互動的過程中,瀏覽器可以自動的按照規則把這個標識發回給伺服器,伺服器根據這個sessionid就可以找得到對應的session,又回到了這段文字的開始。

5.2、擷取session   
    request.getSession();  //如果沒有將建立一個新的,等效getSession(true);

    有些人不理解,為什麼是通過request來擷取session,可以這樣理解,在擷取session時,需要檢測請求中是否有session標識,所以需要用request來擷取

    request.getSession(boolean);  //true:沒有將建立,false:沒有將返回null
5.3、session屬性操作
  xxxAttribute(...)    用來存放一些資訊,然後才能共用資訊   setAttrubute(key,value);  getAttribute(key);
 5.4、session生命週期

  常常聽到這樣一種誤解“只要關閉瀏覽器,session就消失了”。其實可以想象一下會員卡的例子,除非顧客主動對店家提出銷卡,否則店家絕對不會輕易刪除顧客的資料。對session來說也是一樣的,除非程式通知伺服器刪除一個session,

  否則伺服器會一直保留,程式一般都是在使用者做log off的時候發個指令去刪除session。然而瀏覽器從來不會主動在關閉之前通知伺服器它將要關閉,因此伺服器根本不會有機會知道瀏覽器已經關閉,之所以會有這種錯覺,

  是大部分session機制都使用會話cookie來儲存session id,而關閉瀏覽器後這個session id就消失了,再次串連伺服器時也就無法找到原來的session。如果伺服器設定的cookie被儲存到硬碟上,或者使用某種手段改寫瀏覽器發出的HTTP要求標頭,

  把原來的session id發送給伺服器,則再次開啟瀏覽器仍然能夠找到原來的session。

  恰恰是由於關閉瀏覽器不會導致session被刪除,迫使伺服器為seesion設定了一個失效時間,一般是30分鐘,當距離用戶端上一次使用session的時間超過這個失效時間時,伺服器就可以認為用戶端已經停止了活動,才會把session刪除以節省儲存空間。  

  我們也可以自己來控制session的有效時間:

    session.invalidate()將session對象銷毀    setMaxInactiveInterval(int interval) 設定有效時間,單位秒

  在web.xml中配置session的有效時間: 

     <session-config>          <session-timeout>30</session-timeout>   單位:分鐘    <session-config>

  所以,討論了這麼久,session的生命週期就是:

    建立:第一次調用getSession()

    銷毀:

      1)逾時,預設30分鐘

      2)執行api:session.invalidate()將session對象銷毀、setMaxInactiveInterval(int interval) 設定有效時間,單位:秒 

      3)伺服器非正常關閉     

        自殺,直接將JVM馬上關閉

        如果正常關閉,session就會被持久化(寫入到檔案中,因為session預設的逾時時間為30分鐘,正常關閉後,就會將session持久化,等30分鐘後,就會被刪除)

        位置: D:\java\tomcat\apache-tomcat-7.0.53\work\Catalina\localhost\test01\SESSIONS.ser

5.5、session id的URL重寫

  當瀏覽器將cookie禁用,基於cookie的session將不能正常工作,每次使用request.getSession() 都將建立一個新的session。達不到session共用資料的目的,但是我們知道原理,只需要將session id 傳遞給伺服器session就可以正常工作的。

  解決:通過URL將session id 傳遞給伺服器:URL重寫

  1)手動方式: url;jsessionid=....

  2)api方式:

      encodeURL(java.lang.String url) 進行所有URL重寫

      encodeRedirectURL(java.lang.String url) 進行重新導向 URL重寫 

       這兩個用法基本一致,只不過考慮特殊情況,要訪問的連結可能會被Redirect到其他servlet去進行處理,這樣你用上述方法帶來的session的id資訊不能被同時傳送到其他servlet。這時候用encodeRedirectURL()方法就可以了。  

  如果瀏覽器禁用cooke,api將自動追加session id ,如果沒有禁用,api將不進行任何修改。

  注意:如果瀏覽器禁用cookie,web項目的所有url都需進行重寫。否則session將不能正常工作。

  當cookie禁用時:

    

六、總結cookie和session

  上面都詳細的說明了cookie和session的核心內容:

  1)知道什麼是cookie和session

    cookie是一種在用戶端記錄使用者資訊的技術,因為http協議是無狀態的,為瞭解決這個問題而產生了cookie。記錄使用者名稱等一些應用

    session是一種在服務端記錄使用者資訊的技術,一般session用來在伺服器端共用資料。

  2)cookie的工作原理和session的工作原理

    cookie工作原理,可以看上面講解cookie的那張圖,cookie是由伺服器端建立發送回瀏覽器端的,並且每次請求伺服器都會將cookie帶過去,以便伺服器知道該使用者是哪一個。

    其cookie中是使用索引值對來儲存資訊的,並且一個cookie只能儲存一個索引值對。所以在擷取cookie時,是會擷取到所有的cookie,然後從其中遍曆。

      

    session的工作原理就是依靠cookie來做支撐,第一次使用request.getSession()時session被建立,並且會為該session建立一個獨一無二的sessionid存放到cookie中,然後發送會瀏覽器端,

    瀏覽器端每次請求時,都會帶著這個sessionid,伺服器就會認識該sessionid,知道了sessionid就找得到哪個session。以此來達到共用資料的目的。 這裡需要注意的是,session不會隨著瀏覽器的關閉而死亡,而是等待逾時時間。

 

喜歡就點個“推薦”哦!

JavaWeb(二)會話管理之細說cookie與session

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.