轉(zhuǎn)載:Servlet中HttpSession的使用

HttpSession概述

什么是HttpSesssion

javax.servlet.http.HttpSession接口表示一個(gè)會(huì)話,我們可以把一個(gè)會(huì)話內(nèi)需要共享的數(shù)據(jù)保存到HttSession對(duì)象中伟桅。

獲取HttpSession對(duì)象

HttpSession request.getSesssion():如果當(dāng)前會(huì)話已經(jīng)有了session對(duì)象那么直接返回伍俘,如果當(dāng)前會(huì)話還不存在會(huì)話,那么創(chuàng)建session并返回蚣抗;
HttpSession request.getSession(boolean):當(dāng)參數(shù)為true時(shí)侈百,與requeset.getSession()相同。如果參數(shù)為false翰铡,那么如果當(dāng)前會(huì)話中存在session則返回钝域,不存在返回null;

HttpSession是域?qū)ο?/h3>

我們已經(jīng)學(xué)習(xí)過(guò)HttpServletRequest锭魔、ServletContext例证,它們都是域?qū)ο螅F(xiàn)在我們又學(xué)習(xí)了一個(gè)HttpSession迷捧,它也是域?qū)ο笾帧K鼈內(nèi)齻€(gè)是Servlet中可以使用的域?qū)ο螅鳭SP中可以多使用一個(gè)域?qū)ο竽铮魈煳覀冊(cè)僦v解JSP的第四個(gè)域?qū)ο蟆?br> HttpServletRequest:一個(gè)請(qǐng)求創(chuàng)建一個(gè)request對(duì)象笙蒙,所以在同一個(gè)請(qǐng)求中可以共享request,例如一個(gè)請(qǐng)求從AServlet轉(zhuǎn)發(fā)到BServlet庆锦,那么AServlet和BServlet可以共享request域中的數(shù)據(jù)捅位;
ServletContext:一個(gè)應(yīng)用只創(chuàng)建一個(gè)ServletContext對(duì)象,所以在ServletContext中的數(shù)據(jù)可以在整個(gè)應(yīng)用中共享,只要不啟動(dòng)服務(wù)器艇搀,那么ServletContext中的數(shù)據(jù)就可以共享尿扯;
HttpSession:一個(gè)會(huì)話創(chuàng)建一個(gè)HttpSession對(duì)象,同一會(huì)話中的多個(gè)請(qǐng)求中可以共享session中的數(shù)據(jù)焰雕;

下面是session的域方法:

void setAttribute(String name, Object value):用來(lái)存儲(chǔ)一個(gè)對(duì)象姜胖,也可以稱之為存儲(chǔ)一個(gè)域?qū)傩裕纾簊ession.setAttribute(“xxx”, “XXX”)淀散,在session中保存了一個(gè)域?qū)傩杂依常驅(qū)傩悦Q為xxx,域?qū)傩缘闹禐閄XX档插。請(qǐng)注意慢蜓,如果多次調(diào)用該方法,并且使用相同的name郭膛,那么會(huì)覆蓋上一次的值晨抡,這一特性與Map相同;
Object getAttribute(String name):用來(lái)獲取session中的數(shù)據(jù)则剃,當(dāng)前在獲取之前需要先去存儲(chǔ)才行耘柱,例如:String value = (String) session.getAttribute(“xxx”);,獲取名為xxx的域?qū)傩裕?br> void removeAttribute(String name):用來(lái)移除HttpSession中的域?qū)傩怨飨郑绻麉?shù)name指定的域?qū)傩圆淮嬖诘骷澹敲幢痉椒ㄊ裁炊疾蛔觯?br> Enumeration getAttributeNames():獲取所有域?qū)傩缘拿Q;

登錄案例

需要的頁(yè)面:

login.jsp:登錄頁(yè)面己肮,提供登錄表單士袄;

index1.jsp:主頁(yè),顯示當(dāng)前用戶名稱谎僻,如果沒(méi)有登錄娄柳,顯示您還沒(méi)登錄;

index2.jsp:主頁(yè)艘绍,顯示當(dāng)前用戶名稱赤拒,如果沒(méi)有登錄,顯示您還沒(méi)登錄诱鞠;

Servlet:

LoginServlet:在login.jsp頁(yè)面提交表單時(shí)挎挖,請(qǐng)求本Servlet。在本Servlet中獲取用戶名般甲、密碼進(jìn)行校驗(yàn)肋乍,如果用戶名、密碼錯(cuò)誤敷存,顯示“用戶名或密碼錯(cuò)誤”,如果正確保存用戶名session中,然后重定向到index1.jsp锚烦;

當(dāng)用戶沒(méi)有登錄時(shí)訪問(wèn)index1.jsp或index2.jsp觅闽,顯示“您還沒(méi)有登錄”。如果用戶在login.jsp登錄成功后到達(dá)index1.jsp頁(yè)面會(huì)顯示當(dāng)前用戶名涮俄,而且不用再次登錄去訪問(wèn)index2.jsp也會(huì)顯示用戶名蛉拙。因?yàn)槎啻握?qǐng)求在一個(gè)會(huì)話范圍,index1.jsp和index2.jsp都會(huì)到session中獲取用戶名彻亲,session對(duì)象在一個(gè)會(huì)話中是相同的孕锄,所以都可以獲取到用戶名!
login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>login.jsp</title>
  </head>
 
  <body>
    <h1>login.jsp</h1>
    <hr/>
    <form action="/day06_4/LoginServlet" method="post">
    用戶名:<input type="text" name="username" /><br/>
        <input type="submit" value="Submit"/>
    </form>
  </body>
</html>

index1.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>index1.jsp</title>
  </head>
 
  <body>
<h1>index1.jsp</h1>
<%
    String username = (String)session.getAttribute("username");
    if(username == null) {
       out.print("您還沒(méi)有登錄苞尝!");
    } else {
       out.print("用戶名:" + username);
    }
%>
<hr/>
<a href="/day06_4/index2.jsp">index2</a>
  </body>
</html>

index2.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>index2.jsp</title>
  </head>
 
  <body>
<h1>index2.jsp</h1>
<%
    String username = (String)session.getAttribute("username");
    if(username == null) {
       out.print("您還沒(méi)有登錄畸肆!");
    } else {
       out.print("用戶名:" + username);
    }
%>
<hr/>
<a href="/day06_4/index1.jsp">index1</a>
  </body>
</html>

LoginServlet

public class LoginServlet extends HttpServlet {
    public void doPost(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {
       request.setCharacterEncoding("utf-8");
       response.setContentType("text/html;charset=utf-8");
      
       String username = request.getParameter("username");
      
       if(username.equalsIgnoreCase("cloud")) {
           response.getWriter().print("用戶名或密碼錯(cuò)誤!");
       } else {
           HttpSession session = request.getSession();
           session.setAttribute("username", username);
           response.sendRedirect("/day06_4/index1.jsp");
       }
    }
}

session的實(shí)現(xiàn)原理

session底層是依賴Cookie的宙址!我們來(lái)理解一下session的原理吧轴脐!
當(dāng)我首次去銀行時(shí),因?yàn)檫€沒(méi)有賬號(hào)抡砂,所以需要開一個(gè)賬號(hào)大咱,我獲得的是銀行卡,而銀行這邊的數(shù)據(jù)庫(kù)中留下了我的賬號(hào)注益,我的錢是保存在銀行的賬號(hào)中碴巾,而我?guī)ё叩氖俏业目ㄌ?hào)。
當(dāng)我再次去銀行時(shí)丑搔,只需要帶上我的卡餐抢,而無(wú)需再次開一個(gè)賬號(hào)了。只要帶上我的卡低匙,那么我在銀行操作的一定是我的賬號(hào)旷痕!

當(dāng)首次使用session時(shí),服務(wù)器端要?jiǎng)?chuàng)建session顽冶,session是保存在服務(wù)器端欺抗,而給客戶端的session的id(一個(gè)cookie中保存了sessionId)∏恐兀客戶端帶走的是sessionId绞呈,而數(shù)據(jù)是保存在session中。
當(dāng)客戶端再次訪問(wèn)服務(wù)器時(shí)间景,在請(qǐng)求中會(huì)帶上sessionId佃声,而服務(wù)器會(huì)通過(guò)sessionId找到對(duì)應(yīng)的session,而無(wú)需再創(chuàng)建新的session倘要。


session與瀏覽器

session保存在服務(wù)器圾亏,而sessionId通過(guò)Cookie發(fā)送給客戶端十拣,但這個(gè)Cookie的生命不-1,即只在瀏覽器內(nèi)存中存在志鹃,也就是說(shuō)如果用戶關(guān)閉了瀏覽器夭问,那么這個(gè)Cookie就丟失了。
當(dāng)用戶再次打開瀏覽器訪問(wèn)服務(wù)器時(shí)曹铃,就不會(huì)有sessionId發(fā)送給服務(wù)器缰趋,那么服務(wù)器會(huì)認(rèn)為你沒(méi)有session,所以服務(wù)器會(huì)創(chuàng)建一個(gè)session陕见,并在響應(yīng)中把sessionId中到Cookie中發(fā)送給客戶端秘血。     
你可能會(huì)說(shuō)评甜,那原來(lái)的session對(duì)象會(huì)怎樣灰粮?當(dāng)一個(gè)session長(zhǎng)時(shí)間沒(méi)人使用的話,服務(wù)器會(huì)把session刪除了蜕着!這個(gè)時(shí)長(zhǎng)在Tomcat中配置是30分鐘谋竖,可以在${CATALANA}/conf/web.xml找到這個(gè)配置,當(dāng)然你也可以在自己的web.xml中覆蓋這個(gè)配置承匣!
web.xml

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

session失效時(shí)間也說(shuō)明一個(gè)問(wèn)題蓖乘!如果你打開網(wǎng)站的一個(gè)頁(yè)面開始長(zhǎng)時(shí)間不動(dòng),超出了30分鐘后韧骗,再去點(diǎn)擊鏈接或提交表單時(shí)你會(huì)發(fā)現(xiàn)嘉抒,你的session已經(jīng)丟失了!

session其他常用API

String getId():獲取sessionId袍暴;
int getMaxInactiveInterval():獲取session可以的最大不活動(dòng)時(shí)間(秒)些侍,默認(rèn)為30分鐘。當(dāng)session在30分鐘內(nèi)沒(méi)有使用政模,那么Tomcat會(huì)在session池中移除這個(gè)session岗宣;
void setMaxInactiveInterval(int interval):設(shè)置session允許的最大不活動(dòng)時(shí)間(秒),如果設(shè)置為1秒淋样,那么只要session在1秒內(nèi)不被使用耗式,那么session就會(huì)被移除;
long getCreationTime():返回session的創(chuàng)建時(shí)間趁猴,返回值為當(dāng)前時(shí)間的毫秒值刊咳;
long getLastAccessedTime():返回session的最后活動(dòng)時(shí)間,返回值為當(dāng)前時(shí)間的毫秒值儡司;
void invalidate():讓session失效娱挨!調(diào)用這個(gè)方法會(huì)被session失效,當(dāng)session失效后捕犬,客戶端再次請(qǐng)求跷坝,服務(wù)器會(huì)給客戶端創(chuàng)建一個(gè)新的session酵镜,并在響應(yīng)中給客戶端新session的sessionId;
boolean isNew():查看session是否為新探孝。當(dāng)客戶端第一次請(qǐng)求時(shí)笋婿,服務(wù)器為客戶端創(chuàng)建session誉裆,但這時(shí)服務(wù)器還沒(méi)有響應(yīng)客戶端顿颅,也就是還沒(méi)有把sessionId響應(yīng)給客戶端時(shí),這時(shí)session的狀態(tài)為新足丢。

URL重寫

我們知道session依賴Cookie粱腻,那么session為什么依賴Cookie呢?因?yàn)榉?wù)器需要在每次請(qǐng)求中獲取sessionId斩跌,然后找到客戶端的session對(duì)象绍些。那么如果客戶端瀏覽器關(guān)閉了Cookie呢?那么session是不是就會(huì)不存在了呢耀鸦?
其實(shí)還有一種方法讓服務(wù)器收到的每個(gè)請(qǐng)求中都帶有sessioinId柬批,那就是URL重寫!在每個(gè)頁(yè)面中的每個(gè)鏈接和表單中都添加名為jSessionId的參數(shù)袖订,值為當(dāng)前sessionid氮帐。當(dāng)用戶點(diǎn)擊鏈接或提交表單時(shí)也服務(wù)器可以通過(guò)獲取jSessionId這個(gè)參數(shù)來(lái)得到客戶端的sessionId,找到sessoin對(duì)象洛姑。
index.jsp

<body>
<h1>URL重寫</h1>
<a href='/day06_5/index.jsp;jsessionid=<%=session.getId() %>' >主頁(yè)</a>
 
<form action='/day06_5/index.jsp;jsessionid=<%=session.getId() %>' method="post">
    <input type="submit" value="提交"/>
</form>
  </body>

也可以使用response.encodeURL()對(duì)每個(gè)請(qǐng)求的URL處理上沐,這個(gè)方法會(huì)自動(dòng)追加jsessionid參數(shù),與上面我們手動(dòng)添加是一樣的效果楞艾。

<a href='<%=response.encodeURL("/day06_5/index.jsp") %>' >主頁(yè)</a>
 
<form action='<%=response.encodeURL("/day06_5/index.jsp") %>' method="post">
    <input type="submit" value="提交"/>
</form>

使用response.encodeURL()更加“智能”参咙,它會(huì)判斷客戶端瀏覽器是否禁用了Cookie,如果禁用了硫眯,那么這個(gè)方法在URL后面追加jsessionid蕴侧,否則不會(huì)追加。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末两入,一起剝皮案震驚了整個(gè)濱河市净宵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谆刨,老刑警劉巖塘娶,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異痊夭,居然都是意外死亡刁岸,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門她我,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)虹曙,“玉大人迫横,你說(shuō)我怎么就攤上這事≡吞迹” “怎么了矾踱?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)疏哗。 經(jīng)常有香客問(wèn)我呛讲,道長(zhǎng),這世上最難降的妖魔是什么返奉? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任贝搁,我火速辦了婚禮,結(jié)果婚禮上芽偏,老公的妹妹穿的比我還像新娘雷逆。我一直安慰自己,他們只是感情好污尉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布膀哲。 她就那樣靜靜地躺著,像睡著了一般被碗。 火紅的嫁衣襯著肌膚如雪某宪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天蛮放,我揣著相機(jī)與錄音缩抡,去河邊找鬼。 笑死包颁,一個(gè)胖子當(dāng)著我的面吹牛瞻想,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播娩嚼,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蘑险,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了岳悟?” 一聲冷哼從身側(cè)響起佃迄,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贵少,沒(méi)想到半個(gè)月后呵俏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡滔灶,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年普碎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片录平。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡麻车,死狀恐怖缀皱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情动猬,我是刑警寧澤啤斗,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站赁咙,受9級(jí)特大地震影響钮莲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜序目,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一臂痕、第九天 我趴在偏房一處隱蔽的房頂上張望伯襟。 院中可真熱鬧猿涨,春花似錦、人聲如沸姆怪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)稽揭。三九已至俺附,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間溪掀,已是汗流浹背事镣。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留揪胃,地道東北人璃哟。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像喊递,于是被迫代替她去往敵國(guó)和親随闪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

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

  • 轉(zhuǎn)自 :http://blog.csdn.net/taoff/articles/1921009.aspx 一骚勘、術(shù)語(yǔ)...
    stone_yao閱讀 6,179評(píng)論 0 31
  • 本文目錄: JSP基礎(chǔ) Cookie HttpSession JSP基礎(chǔ) JSP(Java Server Page...
    極客圈閱讀 503評(píng)論 0 3
  • 從三月份找實(shí)習(xí)到現(xiàn)在铐伴,面了一些公司,掛了不少俏讹,但最終還是拿到小米当宴、百度、阿里泽疆、京東户矢、新浪、CVTE于微、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,243評(píng)論 11 349
  • Servlet:Sun公司制訂的一種用來(lái)擴(kuò)展Web服務(wù)器功能的組件規(guī)范逗嫡。當(dāng)瀏覽器將請(qǐng)求發(fā)送給Web服務(wù)器(比如:a...
    南山伐木閱讀 585評(píng)論 0 4
  • 這是知乎上的一個(gè)問(wèn)題青自。剛看到這個(gè)問(wèn)題時(shí),我心下一陣不屑驱证,現(xiàn)在這個(gè)快餐時(shí)代延窜,誰(shuí)還靜下心來(lái)讀書啊抹锄?讀書的都是裝清高的逆瑞,...
    槳一閱讀 591評(píng)論 0 1