會(huì)話管理入門(mén): Cookie技術(shù) & Session技術(shù)

會(huì)話管理入門(mén)

  • 軟件中的會(huì)話:

    1. 一次會(huì)話: 打開(kāi)瀏覽器 -> 訪問(wèn)一些服務(wù)器內(nèi)容 -> 關(guān)閉瀏覽器
    2. 登錄場(chǎng)景:打開(kāi)瀏覽器 -> 瀏覽到登陸頁(yè)面 -> 輸入用戶名和密碼 -> 訪問(wèn)到用戶主頁(yè)(顯示用戶名) -> 修改密碼(輸入原密碼)-> 修改收貨地址.......

    問(wèn)題:在此處登錄會(huì)話過(guò)程中產(chǎn)生的數(shù)據(jù)(用戶會(huì)話數(shù)據(jù))如何保存下來(lái)呢?

  • 購(gòu)物場(chǎng)景:

    • 打開(kāi)瀏覽器 -> 瀏覽商品列表 -> 加入購(gòu)物車(把商品信息保存下來(lái)) -> 關(guān)閉瀏覽器
    • 打開(kāi)瀏覽器-> 直接進(jìn)入購(gòu)物車 -> 查看到上次加入購(gòu)物車的商品 -> 下訂單 -> 支付

    問(wèn)題: 在購(gòu)物會(huì)話過(guò)程中,如何保存商品信息炊汹??

  • 會(huì)話管理: 管理瀏覽器客戶端和服務(wù)器端之間會(huì)話過(guò)程中產(chǎn)生的會(huì)話數(shù)據(jù)脚曾。

  • 域?qū)ο螅?實(shí)現(xiàn)資源之間的數(shù)據(jù)共享

    • request域?qū)ο?/li>
    • context域?qū)ο?/li>
  • 登錄場(chǎng)景:

    1. 小張 : 輸入“張三” (保存數(shù)據(jù): context.setAttribute("name","張三")) -> 用戶主頁(yè) (顯示“張三”)
    2. 小李 : 輸入“李四”(保存數(shù)據(jù):context.setAttribute("name","李四")) -> 用戶主頁(yè)(顯示“李四”)

    問(wèn)題: context是所有用戶公有的資源!!會(huì)覆蓋數(shù)據(jù)

    • 小張: 輸入“張三”(保存數(shù)據(jù): request.setAttribute("name","張三"))- > 用戶主頁(yè)(顯示“張三”)

    問(wèn)題: 一定要使用轉(zhuǎn)發(fā)技術(shù)來(lái)跳轉(zhuǎn)頁(yè)面!

  • 解決辦法: 可以使用session域?qū)ο髞?lái)保存會(huì)話數(shù)據(jù)袁铐!

會(huì)話技術(shù)

  • Cookie技術(shù):會(huì)話數(shù)據(jù)保存在瀏覽器客戶端
  • Session技術(shù):會(huì)話數(shù)據(jù)保存在服務(wù)器端

Cookie技術(shù)

  • 特點(diǎn) : Cookie技術(shù):會(huì)話數(shù)據(jù)保存在瀏覽器客戶端
  • 技術(shù)核心 : Cookie類:用于存儲(chǔ)會(huì)話數(shù)據(jù)
    1)構(gòu)造Cookie對(duì)象 : Cookie(java.lang.String name, java.lang.String value)
    2)設(shè)置cookie
    • void setPath(java.lang.String uri) : 設(shè)置cookie的有效訪問(wèn)路徑
    • void setMaxAge(int expiry): 設(shè)置cookie的有效時(shí)間
    • void setValue(java.lang.String newValue) : 設(shè)置cookie的值
      3)發(fā)送cookie到瀏覽器端保存
    • void response.addCookie(Cookie cookie) : 發(fā)送cookie
      4)服務(wù)器接收cookie : Cookie[] cookies= request.getCookies() : 接收cookie
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;
// 第一個(gè)cookie的程序
public class CookieDemo1 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

          //1.創(chuàng)建Cookie對(duì)象
          Cookie cookie1 = new Cookie("name","eric");
          //Cookie cookie2 = new Cookie("email","jacky@qq.com");
          //Cookie cookie1 = new Cookie("email","eric@qq.com");

          /**
           * 1)設(shè)置cookie的有效路徑揭蜒。默認(rèn)情況:有效路徑在當(dāng)前web應(yīng)用下。 /day11
           */
          //cookie1.setPath("/day11");
          //cookie2.setPath("/day12");
        
          /**
            * 2)設(shè)置cookie的有效時(shí)間
            * 正整數(shù):表示cookie數(shù)據(jù)保存瀏覽器的緩存目錄(硬盤(pán)中)剔桨,數(shù)值表示保存的時(shí)間屉更。
            * 負(fù)整數(shù):表示cookie數(shù)據(jù)保存瀏覽器的內(nèi)存中。瀏覽器關(guān)閉cookie就丟失了H髯骸瑰谜!
            * 零:表示刪除同名的cookie數(shù)據(jù)
            */  
          //cookie1.setMaxAge(20); //20秒,從最后不調(diào)用cookie開(kāi)始計(jì)算   
          cookie1.setMaxAge(-1); //cookie保存在瀏覽器內(nèi)存(會(huì)話cookie) 
          //cookie1.setMaxAge(0);
            
          //2.把cookie數(shù)據(jù)發(fā)送到瀏覽器(通過(guò)響應(yīng)頭發(fā)送: set-cookie名稱)        
          //response.setHeader("set-cookie", cookie.getName()+"="+cookie.getValue()+",email=eric@qq.com");
        
          //推薦使用這種方法树绩,避免手動(dòng)發(fā)送cookie信息
          response.addCookie(cookie1);
          //response.addCookie(cookie2);
          //response.addCookie(cookie1);

          //3.接收瀏覽器發(fā)送的cookie信息
          /*
          String name = request.getHeader("cookie");
          System.out.println(name);
          */
          Cookie[] cookies = request.getCookies();
          //注意:判斷null,否則空指針
          if(cookies!=null){
                  //遍歷
                  for(Cookie c:cookies){
                      String name = c.getName();
                      String value = c.getValue();
                      System.out.println(name+"="+value);
                  }
          }else{
                  System.out.println("沒(méi)有接收cookie數(shù)據(jù)");
              } 
          }
}
  • Cookie原理
    1. 服務(wù)器創(chuàng)建cookie對(duì)象萨脑,把會(huì)話數(shù)據(jù)存儲(chǔ)到cookie對(duì)象中 : new Cookie("name","value");
    2. 服務(wù)器發(fā)送cookie信息到瀏覽器 : response.addCookie(cookie);
    • 舉例 : set-cookie: name=eric : 隱藏發(fā)送了一個(gè)set-cookie名稱的響應(yīng)頭
    1. 瀏覽器得到服務(wù)器發(fā)送的cookie,然后保存在瀏覽器端饺饭。
    2. 瀏覽器在下次訪問(wèn)服務(wù)器時(shí)渤早,會(huì)帶著cookie信息
    • 舉例 : cookie: name=eric : 隱藏帶著一個(gè)叫cookie名稱的請(qǐng)求頭
    1. 服務(wù)器接收到瀏覽器帶來(lái)的cookie信息 : request.getCookies();
  • Cookie的細(xì)節(jié)
    1)void setPath(java.lang.String uri) : 設(shè)置cookie的有效訪問(wèn)路徑。有效路徑指的是cookie的有效路徑保存在哪里砰奕,那么瀏覽器在有效路徑下訪問(wèn)服務(wù)器時(shí)就會(huì)帶著cookie信息蛛芥,否則不帶cookie信息
    2)void setMaxAge(int expiry) : 設(shè)置cookie的有效時(shí)間。
    • 正整數(shù):表示cookie數(shù)據(jù)保存瀏覽器的緩存目錄(硬盤(pán)中)军援,數(shù)值表示保存的時(shí)間仅淑。
    • 負(fù)整數(shù):表示cookie數(shù)據(jù)保存瀏覽器的內(nèi)存中。瀏覽器關(guān)閉cookie就丟失了P馗纭涯竟!
    • 零:表示刪除同名的cookie數(shù)據(jù)
public class DeleteCookie extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
                  /**
                    * 需求: 刪除cookie
                    */
                  Cookie cookie = new Cookie("name","xxxx");
                  cookie.setMaxAge(0);//刪除同名的cookie
                  response.addCookie(cookie);
                  System.out.println("刪除成功");   
            }
}

3)Cookie數(shù)據(jù)類型只能保存非中文字符串類型的】昭幔可以保存多個(gè)cookie庐船,但是瀏覽器一般只允許存放300個(gè)Cookie,每個(gè)站點(diǎn)最多存放20個(gè)Cookie嘲更,每個(gè)Cookie的大小限制為4KB筐钟。

  • 案例 : 顯示用戶上次訪問(wèn)的時(shí)間
public class HistServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        
        //獲取當(dāng)前時(shí)間
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String curTime = format.format(new Date());

        //取得cookie
        Cookie[] cookies = request.getCookies();
        String lastTime = null;
        if(cookies!=null){
            for (Cookie cookie : cookies) {
                if(cookie.getName().equals("lastTime")){
                    //有l(wèi)astTime的cookie,已經(jīng)是第n次訪問(wèn)
                    lastTime = cookie.getValue();//上次訪問(wèn)的時(shí)間
                    //第n次訪問(wèn)
                    //1.把上次顯示時(shí)間顯示到瀏覽器
                    response.getWriter().write("歡迎回來(lái)赋朦,你上次訪問(wèn)的時(shí)間為:"+lastTime+",當(dāng)前時(shí)間為:"+curTime);
                    //2.更新cookie
                    cookie.setValue(curTime);
                    cookie.setMaxAge(1*30*24*60*60);
                    //3.把更新后的cookie發(fā)送到瀏覽器
                    response.addCookie(cookie);
                    break;
                }
            }
        }
        
        /**
         * 第一次訪問(wèn)(沒(méi)有cookie 或 有cookie篓冲,但沒(méi)有名為lastTime的cookie)
         */
        if(cookies==null || lastTime==null){
            //1.顯示當(dāng)前時(shí)間到瀏覽器
            response.getWriter().write("你是首次訪問(wèn)本網(wǎng)站,當(dāng)前時(shí)間為:"+curTime);
            //2.創(chuàng)建Cookie對(duì)象
            Cookie cookie = new Cookie("lastTime",curTime);
            cookie.setMaxAge(1*30*24*60*60);//保存一個(gè)月
            //3.把cookie發(fā)送到瀏覽器保存
            response.addCookie(cookie);
        }
    }
}
  • 案例 : 查看用戶瀏覽器過(guò)的商品

Session技術(shù)

  1. 引入 :
  • Cookie的局限:
    1)Cookie只能存字符串類型宠哄。不能保存對(duì)象
    2)只能存非中文壹将。
    3)1個(gè)Cookie的容量不超過(guò)4KB。
  • 如果要保存非字符串毛嫉,超過(guò)4kb內(nèi)容诽俯,只能使用session技術(shù)!3性痢暴区!
  • Session特點(diǎn):會(huì)話數(shù)據(jù)保存在服務(wù)器端 (內(nèi)存中)
  1. Session技術(shù)核心(HttpSession類:用于保存會(huì)話數(shù)據(jù))
    1)創(chuàng)建或得到session對(duì)象
    • HttpSession getSession()
    • HttpSession getSession(boolean create)
      2)設(shè)置session對(duì)象
    • void setMaxInactiveInterval(int interval) : 設(shè)置session的有效時(shí)間
    • void invalidate() : 銷毀session對(duì)象
    • java.lang.String getId() : 得到session編號(hào)
      3)保存會(huì)話數(shù)據(jù)到session對(duì)象
    • void setAttribute(java.lang.String name, java.lang.Object value) : 保存數(shù)據(jù)
    • java.lang.Object getAttribute(java.lang.String name) : 獲取數(shù)據(jù)
    • void removeAttribute(java.lang.String name) : 清除數(shù)據(jù)
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;
import javax.servlet.http.HttpSession;
/**
 * 保存會(huì)話數(shù)據(jù)到session域?qū)ο? */
public class SessionDemo1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1.創(chuàng)建session對(duì)象
        HttpSession session = request.getSession();
        
        /**
         * 得到session編號(hào)
         */
        System.out.println("id="+session.getId());
        
        /**
         * 修改session的有效時(shí)間
         */
        //session.setMaxInactiveInterval(20);
        
        /**
         * 手動(dòng)發(fā)送一個(gè)硬盤(pán)保存的cookie給瀏覽器
         */
        Cookie c = new Cookie("JSESSIONID",session.getId());
        c.setMaxAge(60*60);
        response.addCookie(c);
        
        //2.保存會(huì)話數(shù)據(jù)
        session.setAttribute("name", "rose");
    }
}
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
 * 從session域?qū)ο笾腥〕鰰?huì)話數(shù)據(jù)
 */
public class SessionDemo2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1.得到session對(duì)象
        HttpSession session = request.getSession(false);
        
        if(session==null){
            System.out.println("沒(méi)有找到對(duì)應(yīng)的sessino對(duì)象");
            return;
        }
        
        /**
         * 得到session編號(hào)
         */
        System.out.println("id="+session.getId());
        
        //2.取出數(shù)據(jù)
        String name = (String)session.getAttribute("name");
        System.out.println("name="+name);
    }
}
  1. Session原理
  • 服務(wù)器能夠識(shí)別不同的瀏覽者, 在哪個(gè)session域?qū)ο蟊4鏀?shù)據(jù)闯团,就必須從哪個(gè)域?qū)ο笕〕觯?
    1. 瀏覽器1:(給s1分配一個(gè)唯一的標(biāo)記:s001,把s001發(fā)送給瀏覽器)
    2. 瀏覽器1 的新窗口(帶著s001的標(biāo)記到服務(wù)器查詢,s001->s1,返回s1)
    3. 新的瀏覽器1:(沒(méi)有帶s001,不能返回s1)
    4. 瀏覽器2:(沒(méi)有帶s001,不能返回s1)
  • 代碼解讀:HttpSession session = request.getSession();
    1)第一次訪問(wèn): 創(chuàng)建session對(duì)象颜启,給session對(duì)象分配一個(gè)唯一的ID偷俭,叫JSESSIONID
    2)把JSESSIONID作為Cookie的值發(fā)送給瀏覽器保存
    3)第二次訪問(wèn)的時(shí)候,瀏覽器帶著JSESSIONID的cookie訪問(wèn)服務(wù)器
    4)服務(wù)器得到JSESSIONID缰盏,在服務(wù)器的內(nèi)存中搜索是否存放對(duì)應(yīng)編號(hào)的session對(duì)象
    5)如果找到對(duì)應(yīng)編號(hào)的session對(duì)象涌萤,直接返回該對(duì)象
    6)如果找不到對(duì)應(yīng)編號(hào)的session對(duì)象,創(chuàng)建新的session對(duì)象口猜,繼續(xù)走1的流程

結(jié)論:通過(guò)JSESSION的cookie值在服務(wù)器找session對(duì)象负溪!

  1. Sesson細(xì)節(jié)
    1)getId() : 得到session編號(hào)
    2)兩個(gè)getSession方法:
    • getSession(true) / getSession() : 創(chuàng)建或得到session對(duì)象。沒(méi)有匹配的session編號(hào)济炎,自動(dòng)創(chuàng)建新的session對(duì)象
    • getSession(false) : 得到session對(duì)象川抡。沒(méi)有匹配的session編號(hào),返回null
      3)void setMaxInactiveInterval(int interval) : 設(shè)置session的有效時(shí)間
    • session對(duì)象銷毀時(shí)間:
      1. 默認(rèn)情況30分服務(wù)器自動(dòng)回收
      2. 修改session回收時(shí)間
      3. 全局修改session有效時(shí)間: 在web.xml中修改<session config><session timeout>1</session timeout></session config> 默認(rèn)是以分鐘為單位
      4. 手動(dòng)銷毀session對(duì)象 : void invalidate() ->銷毀session對(duì)象
        4)如何避免瀏覽器的JSESSIONID的cookie隨著瀏覽器關(guān)閉而丟失的問(wèn)題

總結(jié):

1)會(huì)話管理 : 瀏覽器和服務(wù)器會(huì)話過(guò)程中的產(chǎn)生的會(huì)話數(shù)據(jù)的管理
2)Cookie技術(shù) :

  • 創(chuàng)建 : new Cookie("name","value")
  • 添加 : response.addCookie(coookie)
  • 獲取 : request.getCookies();
    3)Session技術(shù) :
  • 創(chuàng)建 : request.getSession();
  • 添加 : setAttrbute("name","會(huì)話數(shù)據(jù)");
  • 獲取 : getAttribute("會(huì)話數(shù)據(jù)");
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末须尚,一起剝皮案震驚了整個(gè)濱河市崖堤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌耐床,老刑警劉巖密幔,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異撩轰,居然都是意外死亡胯甩,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)堪嫂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)偎箫,“玉大人,你說(shuō)我怎么就攤上這事皆串⊙桶欤” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵恶复,是天一觀的道長(zhǎng)娇唯。 經(jīng)常有香客問(wèn)我,道長(zhǎng)寂玲,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任梗摇,我火速辦了婚禮拓哟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘伶授。我一直安慰自己断序,他們只是感情好流纹,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著违诗,像睡著了一般漱凝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诸迟,一...
    開(kāi)封第一講書(shū)人閱讀 52,328評(píng)論 1 310
  • 那天茸炒,我揣著相機(jī)與錄音,去河邊找鬼阵苇。 笑死壁公,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绅项。 我是一名探鬼主播紊册,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼快耿!你這毒婦竟也來(lái)了囊陡?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤掀亥,失蹤者是張志新(化名)和其女友劉穎撞反,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體铺浇,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痢畜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鳍侣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丁稀。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖倚聚,靈堂內(nèi)的尸體忽然破棺而出线衫,到底是詐尸還是另有隱情,我是刑警寧澤惑折,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布授账,位于F島的核電站,受9級(jí)特大地震影響惨驶,放射性物質(zhì)發(fā)生泄漏白热。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一粗卜、第九天 我趴在偏房一處隱蔽的房頂上張望屋确。 院中可真熱鬧,春花似錦、人聲如沸攻臀。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)刨啸。三九已至堡赔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間设联,已是汗流浹背善已。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留仑荐,地道東北人雕拼。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像粘招,于是被迫代替她去往敵國(guó)和親啥寇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容