ssion 簡(jiǎn)介
ssion 是我們 jsp 九大隱含對(duì)象的一個(gè)對(duì)象。
ssion 稱作域?qū)ο螅淖饔檬潜4嬉恍┬畔ⅲ?ssion 這個(gè)域?qū)ο笫且淮螘?huì)話期間使用同一個(gè)對(duì)象。所以這個(gè)對(duì)象可以用來保存共享數(shù)據(jù)。
使用 Cookie 有一個(gè)非常大的局限,就是如果 Cookie 很多,則無形的增加了客戶端與服務(wù)端的數(shù)據(jù)傳輸量。而且由于瀏覽器對(duì) Cookie 數(shù)量的限制,注定我們不能再 Cookie 中保存過多的信息,于是 Session 出現(xiàn)。Session 的作用就是在服務(wù)器端保存一些用戶的數(shù)據(jù),然后傳遞給用戶一個(gè)名字為JSESSIONID 的 Cookie,這個(gè) JESSIONID 對(duì)應(yīng)這個(gè)服務(wù)器中的一個(gè) Session 對(duì)象,通過它就可以獲取到保存用戶信息的 Session。ssion 是基于 cookie 的。
在用戶第一次使用 ssion 的時(shí)候(訪問 jsp 頁(yè)面會(huì)獲取 ssion,所以一般訪問 index.jsp 就算是第一次使用 ssion 了),服務(wù)器會(huì)為用戶創(chuàng)建一個(gè) ssion 域?qū)ο蟆J褂?jssionid 和這個(gè)對(duì)象關(guān)聯(lián),這個(gè)對(duì)象在整個(gè)用戶會(huì)話期間使用。響應(yīng)體增加 t-cookie:jssionid=xxx 的項(xiàng)。用戶下次以后的請(qǐng)求都會(huì)攜帶 jssionid 這個(gè)參數(shù),我們使用 request.getSession()的時(shí)候,就會(huì)使用 jssionid 取出 ssion 對(duì)象。
ssion 原理圖:
HttpSession 的生命周期
什么時(shí)候創(chuàng)建 HttpSession 對(duì)象
①. 對(duì)于 JSP: 是否瀏覽器訪問服務(wù)端的任何一個(gè) JSP, 服務(wù)器都會(huì)立即創(chuàng)建一個(gè) HttpSession 對(duì)象呢?
不一定。
若當(dāng)前的 JSP 是客戶端訪問的當(dāng)前 WEB 應(yīng)用的第一個(gè)資源,且 JSP 的 page 指定的 ssion 屬性值為 fal,則服務(wù)器就不會(huì)為 JSP 創(chuàng)建一個(gè) HttpSession 對(duì)象;若當(dāng)前 JSP 不是客戶端訪問的當(dāng)前 WEB 應(yīng)用的第一個(gè)資源,且其他頁(yè)面已經(jīng)創(chuàng)建一個(gè) HttpSession 對(duì)象,則服務(wù)器也不會(huì)為當(dāng)前 JSP 頁(yè)面創(chuàng)建一個(gè) HttpSession 對(duì)象,而會(huì)把和當(dāng)前會(huì)話關(guān)聯(lián)的那個(gè) HttpSession 對(duì)象返回給當(dāng)前的 JSP 頁(yè)面.②. 對(duì)于 Serlvet: 若 Serlvet 是客戶端訪問的第一個(gè) WEB 應(yīng)用的資源,則只有調(diào)用了 request.getSession() 或 request.getSession(true) 才會(huì)創(chuàng)建 HttpSession 對(duì)象
page 指令的 ssion=“fal“ 表示什么意思?
當(dāng)前 JSP 頁(yè)面禁用 ssion 隱含變量!但可以使用其他的顯式的 HttpSession 對(duì)象
在 Serlvet 中如何獲取 HttpSession 對(duì)象?
request.getSession(boolean create):
create 為 fal, 若沒有和當(dāng)前 JSP 頁(yè)面關(guān)聯(lián)的 HttpSession 對(duì)象, 則返回 null; 若有, 則返回 true
create 為 true, 一定返回一個(gè) HttpSession 對(duì)象. 若沒有和當(dāng)前 JSP 頁(yè)面關(guān)聯(lián)的 HttpSession 對(duì)象, 則服務(wù)器創(chuàng)建一個(gè)新的HttpSession 對(duì)象返回, 若有, 直接返回關(guān)聯(lián)的.
request.getSession(): 等同于 request.getSession(true)
什么時(shí)候銷毀 HttpSession 對(duì)象
①. 直接調(diào)用 HttpSession 的 invalidate() 方法: 該方法使 HttpSession 失效
②. 服務(wù)器卸載了當(dāng)前 WEB 應(yīng)用.
③. 超出 HttpSession 的過期時(shí)間.
④. 并不是關(guān)閉了瀏覽器就銷毀了 HttpSession.
ssion 使用
獲取 ssion 對(duì)象
HttpSession ssion = request.getSession();
ssion 是我們的四大域?qū)ο笾弧S脕肀4鏀?shù)據(jù)。常用的方法
ssion.tAttribute("ur", new Object()); ssion.getAttribute("ur");ssion.tMaxInactiveInterval(60*60*24);//秒為單位ssion.invalidate();//使 ssion 不可用
Session 時(shí) 效
①、基本原則
Session 對(duì)象在服務(wù)器端不能長(zhǎng)期保存,它是有時(shí)間限制的,超過一定時(shí)間沒有被訪問過的 Session 對(duì)象就應(yīng)該釋放掉,以節(jié)約內(nèi)存。所以 Session 的有效時(shí)間并不是從創(chuàng)建對(duì)象開始計(jì)時(shí),到指定時(shí)間后釋放——而是從最后一次被訪問開始計(jì)時(shí),統(tǒng)計(jì)其“空閑” 的時(shí)間。
②、默認(rèn)設(shè)置
在全局 web.xml 中能夠找到如下配置:
<ssion-config> <ssion-timeout>30</ssion-timeout></ssion-config>
③、手工設(shè)置
ssion.tMaxInactiveInterval(int conds) ssion.getMaxInactiveInterval()
④、強(qiáng)制失效
ssion.invalidate()
⑤、可以使 Session 對(duì)象釋放的情況
Session 對(duì)象空閑時(shí)間達(dá)到了目標(biāo)設(shè)置的最大值,自動(dòng)釋放
Session 對(duì)象被強(qiáng)制失效
Web 應(yīng)用卸載服務(wù)器進(jìn)程停止
URL 重寫
在整個(gè)會(huì)話控制技術(shù)體系中,保持 JSESSIONID 的值主要通過 Cookie 實(shí)現(xiàn)。但 Cookie 在瀏覽器端可能會(huì)被禁用,所以我們還需要一些備用的技術(shù)手段,例如:URL 重寫。
1)URL 重寫其實(shí)就是將 JSESSIONID 的值以固定格式附著在 URL 地址后面,以實(shí)現(xiàn)保持
JSESSIONID,進(jìn)而保持會(huì)話狀態(tài)。這個(gè)固定格式是:URL;jssionid=xxxxxxxxx
例如:
targetServlet;jssionid=F9C893D3E77E3E8329FF6BD9B7A09957
2) 實(shí) 現(xiàn) 方 式 :
respon.encodeURL(String)respon.encodeRedirectURL(String)
例如:
//1.獲取Session對(duì)象HttpSession ssion = request.getSession();//2.創(chuàng)建目標(biāo)URL地址字符串String url = "targetServlet";//3.在目標(biāo)URL地址字符串后面附加JSESSIONID的值url = respon.encodeURL(url);//4.重定向到目標(biāo)資源respon.ndRedirect(url);
Session 的活化和鈍化
Session 機(jī)制很好的解決了 Cookie 的不足,但是當(dāng)訪問應(yīng)用的用戶很多時(shí),服務(wù)器上就會(huì)創(chuàng)建非常多的 Session 對(duì)象,如果不對(duì)這些 Session 對(duì)象進(jìn)行處理,那么在 Session 失效之前,這些 Session 一直都會(huì)在服務(wù)器的內(nèi)存中存在。那么就,就出現(xiàn)了 Session 活化和鈍化的機(jī)制。
1)Session 鈍化:
Session 在一段時(shí)間內(nèi)沒有被使用時(shí),會(huì)將當(dāng)前存在的 Session 對(duì)象序列化到磁盤上,而不 再 占 用 內(nèi) 存 空 間 。
2)Session 活化:
Session 被鈍化后,服務(wù)器再次調(diào)用 Session 對(duì)象時(shí),將 Session 對(duì)象由磁盤中加載到內(nèi)存中使用。
如果希望 Session 域中的對(duì)象也能夠隨 Session 鈍化過程一起序列化到磁盤上,則對(duì)象的實(shí)現(xiàn)類也必須實(shí)現(xiàn)java.io.Serializable 接口。不僅如此,如果對(duì)象中還包含其他對(duì)象的引用,則被關(guān)聯(lián)的對(duì)象也必須支持序列化,否則會(huì)拋出異常:java.io.NotSerializableException
表單重復(fù)提交問題
什么是表單重復(fù)提交?
同一個(gè)表單中的數(shù)據(jù)內(nèi)容多次提交到服務(wù)器。 危害:
服務(wù)器重復(fù)處理信息,負(fù)擔(dān)加重。
如果是保存數(shù)據(jù)可能導(dǎo)致保存多份相同數(shù)據(jù)。
幾種重復(fù)提交
1)提交完表單后,直接刷新頁(yè)面,會(huì)再次提交。
- 根本原因:Servlet 處理完請(qǐng)求以后,直接轉(zhuǎn)發(fā)到目標(biāo)頁(yè)面。
- 這樣整一個(gè)業(yè)務(wù),只發(fā)送了一次請(qǐng)求,那么當(dāng)你在瀏覽器中點(diǎn)擊刷新按鈕或者狂按 f5,會(huì)一直都會(huì)刷新之前的請(qǐng)求
解決方案:使用重定向跳轉(zhuǎn)到目標(biāo)頁(yè)面
2)提交表單后,由于網(wǎng)速差等原因,服務(wù)器還未返回結(jié)果,連續(xù)點(diǎn)擊提交按鈕,會(huì)重 復(fù)提交。
- 根本原因:按鈕可以多次點(diǎn)擊
- 解決方案:通過 js,使得按鈕只能提交一次。
$(“#form1”).submit(function(){ $(“#sub_btn”).prop(“disabled”,true);})
3)表單提交后,點(diǎn)擊瀏覽器回退按鈕,不刷新頁(yè)面,點(diǎn)擊提交按鈕再次提交表單
- 根本原因:服務(wù)器并不能識(shí)別請(qǐng)求是否重復(fù)。
- 解決方案:使用 token 機(jī)制。
1、頁(yè)面生成時(shí),產(chǎn)生一個(gè)唯一的 token 值。將此值放入 ssion
2、表單提交時(shí),帶上這個(gè) token 值。
3、服務(wù)端驗(yàn)證 token 值存在,則提交表單,然后移除此值。驗(yàn)證 token 不存在,說明是之前驗(yàn)證過一次被移除了,所以是重復(fù)請(qǐng)求。不予處理
原理:
代碼:
jsp 頁(yè)面
<% String token = System.currentTimeMillis() + ""; request.getSession().tAttribute(token, "");%><div> <h1>測(cè)試表單重復(fù)提交</h1> <form action="login" method="get"> 用戶名:<input name="urname" type="text"/> 密碼:<input name="password" type="password"> <input name="token" value="<%=token%>"> <input type="submit"> </form> <hr></div>
Servlet
protected void doPost(HttpServletRequest request, HttpServletRespon respon) throws ServletException, IOException { HttpSession ssion = request.getSession(); String token = request.getParameter("token"); Object attribute = ssion.getAttribute(token); respon.tContentType("text/html;chart=UTF-8"); if(attribute!=null){ ssion.removeAttribute(token); respon.getWriter().write("請(qǐng)求成功!"); }el{ respon.getWriter().write("請(qǐng)不要重復(fù)請(qǐng)求!"); }}
其實(shí)防止重復(fù)提交的核心就是讓服務(wù)器有一個(gè)字段能來識(shí)別此次請(qǐng)求是否已經(jīng)執(zhí)行。 這個(gè)字段需要頁(yè)面?zhèn)鬟f過來,因?yàn)橹灰赝嘶厝サ捻?yè)面,字段都是一致的。不會(huì)變化, 通過這個(gè)特性我們想到了 token 機(jī)制來防止重復(fù)提交
本文發(fā)布于:2023-02-28 20:03:00,感謝您對(duì)本站的認(rèn)可!
本文鏈接:http://www.newhan.cn/zhishi/a/167765229477608.html
版權(quán)聲明:本站內(nèi)容均來自互聯(lián)網(wǎng),僅供演示用,請(qǐng)勿用于商業(yè)和其他非法用途。如果侵犯了您的權(quán)益請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)刪除。
本文word下載地址:session(session和cookie的區(qū)別).doc
本文 PDF 下載地址:session(session和cookie的區(qū)別).pdf
| 留言與評(píng)論(共有 0 條評(píng)論) |