Cookie盼忌,Session积糯,Servlet跳轉(zhuǎn),作用域

會(huì)話跟蹤

從打開瀏覽器訪問某個(gè)站點(diǎn)開始谦纱,到關(guān)閉這個(gè)瀏覽器的整個(gè)過程看成,稱為一次會(huì)話。

會(huì)話跟蹤技術(shù)(Cookie跨嘉,Session)的作用

由于HTTP是無狀態(tài)協(xié)議川慌,每次的請求都是獨(dú)立的,不會(huì)影響之前之后的請求應(yīng)答祠乃,從而導(dǎo)致每個(gè)請求間的數(shù)據(jù)無法共享梦重。
會(huì)話跟蹤技術(shù)就是記錄這次會(huì)話中客戶端的狀態(tài)與數(shù)據(jù),實(shí)現(xiàn)請求間的數(shù)據(jù)共享亮瓷。

Cookie Session
存儲(chǔ)位置 客戶端(瀏覽器) 服務(wù)器端
安全性 本地可清理琴拧,安全性不好 安全性相對好
服務(wù)器壓力 減少 增加

1.Cookie

Cookie為客戶端技術(shù),會(huì)將共享數(shù)據(jù)放到客戶端(瀏覽器)中嘱支。
Cookie不支持中文蚓胸,需要編碼和解碼。
瀏覽器中Cookie有數(shù)量限制斗塘,只能保存300個(gè)Cookie信息赢织。

1.服務(wù)端向客戶端發(fā)送一個(gè)Cookie
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        //通過Cookie將共享數(shù)據(jù)保存到瀏覽器
        //該Cookie會(huì)以響應(yīng)頭的形式發(fā)送給客戶端
        Cookie cookie = new Cookie("name", URLEncoder.encode("value", "UTF-8"));
        resp.addCookie(cookie);
}


2.服務(wù)端獲取客戶端的Cookie
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
            if ("name".equals(cookie.getName())) {
                String value = cookie.getValue();
         }
    }
}
Cookie持久化
1.如果不設(shè)置持久化時(shí)間,cookie會(huì)存儲(chǔ)在瀏覽器的內(nèi)存中
2.瀏覽器關(guān)閉馍盟,會(huì)話級別的cookie信息會(huì)銷毀
3.如果設(shè)置持久化時(shí)間于置,cookie信息會(huì)被持久化到瀏覽器的磁盤文件里

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        Cookie cookie = new Cookie("name", "value");
        cookie.setMaxAge(60 * 1000); //設(shè)置Cookie在客戶端的持久化時(shí)間,參數(shù):時(shí)間秒
        cookie.setMaxAge(0); //時(shí)間設(shè)置成0贞岭,代表刪除該Cookie
        resp.addCookie(cookie);
}
Cookie設(shè)置范圍路徑
如果不設(shè)置攜帶路徑八毯,當(dāng)請求訪問產(chǎn)生該cookie的web資源所在的路徑時(shí),都會(huì)攜帶cookie信息瞄桨。

 @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        Cookie cookie = new Cookie("name", "value");

        //訪問WEB16應(yīng)用中的任何資源都攜帶cookie
        cookie.setPath("/WEB16");
        
        //訪問WEB16中的cookieServlet時(shí)才攜帶cookie信息
        cookie.setPath("/WEB16/cookieServlet");
    }

2.Session

當(dāng)用戶訪問Web服務(wù)目錄中的一個(gè)頁面時(shí)话速,Tomcat服務(wù)器會(huì)產(chǎn)生一個(gè)Session對象,這個(gè)Session對象被分配了一個(gè)String類型的id號芯侥,Tomcat將這個(gè)id號發(fā)送到客戶端泊交,存放在用戶的Cookie中乳讥,這樣Session對象和用戶間就建立了一一對應(yīng)關(guān)系,即每個(gè)用戶對應(yīng)一個(gè)Session對象廓俭。

不同的Session云石,具有不同的id,當(dāng)用戶再連接該Web服務(wù)目錄其他頁面時(shí)研乒,依舊使用最初創(chuàng)建的Session汹忠,直到Session對象到達(dá)最大生存時(shí)間或服務(wù)器關(guān)閉,才重新創(chuàng)建一個(gè)新的Session雹熬。

Session對象的生命周期

Session的作用范圍默認(rèn)在一次會(huì)話中宽菜,即在一次會(huì)話中任何資源,都共用一個(gè)session對象竿报。

創(chuàng)建
第一次執(zhí)行 request.getSession() 時(shí)創(chuàng)建.

銷毀
服務(wù)器(非正常)關(guān)閉铅乡,或session過期/失效(默認(rèn)30分鐘)。
Session過期時(shí)長烈菌,在web.xml中進(jìn)行配置隆判。
<session-config>
     <session-timeout>30</session-timeout>
</session-config>
1.創(chuàng)建Session
HttpSession session = req.getSession();
此方法會(huì)獲得專屬于當(dāng)前會(huì)話的Session對象。
如果服務(wù)器端沒有該會(huì)話的Session對象僧界,將會(huì)創(chuàng)建一個(gè)新的Session返回。
如果已存在屬于該會(huì)話的Session臭挽,將直接返回已有的Session捂襟。
實(shí)質(zhì)就是根據(jù)JSESSIONID判斷該客戶端是否在服務(wù)器上已經(jīng)存在session了)

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        HttpSession session = req.getSession();
        session.setAttribute("name", "value");
        session.getAttribute("name");
        session.removeAttribute("name"); //移除Session
        session.invalidate(); //銷毀Session
}

Servlet跳轉(zhuǎn)

1.請求轉(zhuǎn)發(fā)(forward)
  • 請求轉(zhuǎn)發(fā)跳轉(zhuǎn)時(shí),地址欄中的地址不會(huì)改變欢峰,還是第一個(gè)請求資源的路徑葬荷。總共只有一次請求纽帖,因此可以在請求轉(zhuǎn)發(fā)的過程中 共享數(shù)據(jù)宠漩。

  • 最終的響應(yīng)的數(shù)據(jù),由最后的Servlet決定懊直,可以訪問 WEB-INF 中的資源扒吁,不能夠跨域訪問。

下面用一個(gè)簡單的 A 界面輸入用戶名室囊,提交跳轉(zhuǎn)到 B Servlet顯示的例子看一下跳轉(zhuǎn)的流程雕崩。

請求轉(zhuǎn)發(fā)API
req.getRequestDispatcher("跳轉(zhuǎn)目標(biāo)的servlet").forward(req, resp);

@WebServlet(value = "/a")
public class AServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        //避免提交數(shù)據(jù)時(shí)中文亂碼
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        String name = req.getParameter("name");
        PrintWriter out = resp.getWriter();

        //注意:最終的響應(yīng)是由最終跳轉(zhuǎn)到的Servlet響應(yīng)的
        //界面輸出的是B的響應(yīng)
        //這里A before,alert都不輸出
        out.println("A before 不輸出:" + name);

        //請求轉(zhuǎn)發(fā)
        req.getRequestDispatcher("/b").forward(req, resp);

        out.println("A alert 不輸出" + name);
    }
}

@WebServlet(value = "/b")
public class BServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();

        //因?yàn)槭峭粋€(gè)請求所以數(shù)據(jù)共享
        String name = req.getParameter("name");
        out.println("B Servlet:" + name);
    }
}
A Servlet

跳轉(zhuǎn)后B Servlet
2.URL重定向(redirect)
  • 重定向跳轉(zhuǎn)時(shí)融撞,地址欄中的地址會(huì)改變盼铁,總共有兩次請求,所以在URL重定向的過程中尝偎,不能共享數(shù)據(jù)饶火,需要用Session或Cookie解決無協(xié)議問題鹏控。

  • 最終的響應(yīng)的數(shù)據(jù),由最后的Servlet決定肤寝,不能訪問 WEB-INF 中的資源当辐,可以請求轉(zhuǎn)發(fā)跨域訪問。

URL重定向API
resp.sendRedirect("跳轉(zhuǎn)目標(biāo)的servlet");

注意
請求轉(zhuǎn)發(fā)為request調(diào)用醒陆,重定向?yàn)閞esponse調(diào)用


@WebServlet(value = "/a")
public class AServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        //避免提交數(shù)據(jù)時(shí)中文亂碼
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");


        //重定向是兩個(gè)請求所以不能共享數(shù)據(jù)
        //需要用Session解決無協(xié)議問題
        String name = req.getParameter("name");
        req.getSession().setAttribute("name", name);

        PrintWriter writer = resp.getWriter();
        writer.println("A before:"+name);

        //重定向
        resp.sendRedirect("/b");

        //注意:最終的響應(yīng)是由最終跳轉(zhuǎn)到的Servlet響應(yīng)的
        //界面輸出的是B的響應(yīng)
        //這里A before瀑构,alert都不輸出
        writer.println("A alert");
    }
}

@WebServlet(value = "/b")
public class BServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();
        out.println("B Servlet:" + req.getSession().getAttribute("name"));
    }
}
A Servlet
跳轉(zhuǎn)后B Servlet
2.請求包含(include)
  • 使用請求包含跳轉(zhuǎn)時(shí),A包含B的響應(yīng)刨摩,數(shù)據(jù)可以共享寺晌。
請求包含API
req.getRequestDispatcher("跳轉(zhuǎn)目標(biāo)的servlet").include(req, resp);

@WebServlet(value = "/a")
public class AServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        //避免提交數(shù)據(jù)時(shí)中文亂碼
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        String name = req.getParameter("name");
        //req.getSession().setAttribute("name", name);

        PrintWriter writer = resp.getWriter();
        writer.println("A before:" + name);

        req.getRequestDispatcher("/b").include(req, resp);
        writer.println("A alert:" + name);
    }
}


@WebServlet(value = "/b")
public class BServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();
        out.println("B Servlet:" + req.getParameter("name"));
    }
}
A Servlet
跳轉(zhuǎn)后B Servlet

Servlet四大作用域

作用域的作用,是在不同的范圍內(nèi)澡刹,實(shí)現(xiàn)數(shù)據(jù)共享呻征,往哪個(gè)作用域中存放數(shù)據(jù),就只能從哪個(gè)作用域中獲取罢浇。

類型 作用范圍 使用
PageContext 當(dāng)前頁面 Jsp中使用較多
ServletRequest 一次請求 同次請求中的數(shù)據(jù)共享
Session 一次會(huì)話 同次會(huì)話中的數(shù)據(jù)共享
ServletContext 一次應(yīng)用 服務(wù)器啟動(dòng)時(shí)創(chuàng)建陆赋,關(guān)閉時(shí)銷毀
域?qū)ο螅捍鎯?chǔ)數(shù)據(jù)的區(qū)域就是域?qū)ο蟆?/h6>
域?qū)ο蟮耐ㄓ梅椒?
作用域?qū)ο?setAtrribute(String name,Object obj)
作用域?qū)ο?getAtrribute(String name)
作用域?qū)ο?removeAttribute(String name)
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        ServletContext servletContext = getServletContext();
        servletContext.setAttribute("key", "value");

        req.setAttribute("key", "value");

        req.getSession().setAttribute("key", "value");
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市嚷闭,隨后出現(xiàn)的幾起案子攒岛,更是在濱河造成了極大的恐慌,老刑警劉巖胞锰,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灾锯,死亡現(xiàn)場離奇詭異,居然都是意外死亡嗅榕,警方通過查閱死者的電腦和手機(jī)顺饮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凌那,“玉大人兼雄,你說我怎么就攤上這事∶钡” “怎么了赦肋?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嘲碱。 經(jīng)常有香客問我金砍,道長,這世上最難降的妖魔是什么麦锯? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任恕稠,我火速辦了婚禮,結(jié)果婚禮上扶欣,老公的妹妹穿的比我還像新娘鹅巍。我一直安慰自己千扶,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布骆捧。 她就那樣靜靜地躺著澎羞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪敛苇。 梳的紋絲不亂的頭發(fā)上妆绞,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天,我揣著相機(jī)與錄音枫攀,去河邊找鬼括饶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛来涨,可吹牛的內(nèi)容都是我干的图焰。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼蹦掐,長吁一口氣:“原來是場噩夢啊……” “哼技羔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起卧抗,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤藤滥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后社裆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體超陆,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年浦马,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片张漂。...
    茶點(diǎn)故事閱讀 40,872評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晶默,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出航攒,到底是詐尸還是另有隱情磺陡,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布漠畜,位于F島的核電站币他,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏憔狞。R本人自食惡果不足惜蝴悉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瘾敢。 院中可真熱鬧拍冠,春花似錦尿这、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至晃财,卻和暖如春叨橱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背断盛。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工罗洗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人郑临。 一個(gè)月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓栖博,卻偏偏與公主長得像,于是被迫代替她去往敵國和親厢洞。 傳聞我的和親對象是個(gè)殘疾皇子仇让,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評論 2 361

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

  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司躺翻,掛了不少丧叽,但最終還是拿到小米、百度公你、阿里踊淳、京東、新浪陕靠、CVTE迂尝、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,280評論 11 349
  • 寫在前面 cookie和session的區(qū)別: 1、cookie數(shù)據(jù)存放在客戶的瀏覽器上剪芥,session數(shù)據(jù)放在服...
    Pitfalls閱讀 1,526評論 0 17
  • 此文知識(shí)來自于:《深入分析Java_Web技術(shù)》第十章現(xiàn)代session與cookie的應(yīng)用 本章概要:當(dāng)我們的一...
    李文文丶閱讀 1,345評論 0 4
  • 還記得生活中讓我們快樂的事情嗎垄开?從腦科學(xué)的角度來說,讓我們快樂的根本原因税肪,就是大腦給我們分泌多巴胺而導(dǎo)致的溉躲。比...
    戴老師成長記錄儀閱讀 1,307評論 6 10
  • 2月7日 多云(也許會(huì)有陽光) 7點(diǎn)52分進(jìn)站,取票益兄,檢票锻梳,飛奔到高鐵站的時(shí)候,一列和諧號從左手指...
    仨木閱讀 214評論 0 0