国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

java cookie和session

2019-11-06 06:31:44
字體:
來源:轉載
供稿:網友

常用的會話跟蹤技術是Cookie與session。Cookie通過在客戶端記錄信息確定用戶身份,Session通過在服務器端記錄信息確定用戶身份。 Session 與 Cookie 的作用都是為了保持訪問用戶與后端服務器的交互狀態。它們有各自的優點,也有各自的缺陷,然而具有諷刺意味的是它們的優點和它們的使用場景又是矛盾的。例如,使用 Cookie 來傳遞信息時,隨著 Cookie 個數的增多和訪問量的增加,它占用的網絡帶寬也很大,試想假如 Cookie 占用 200 個字節,如果一天的 PV 有幾億,它要占用多少帶寬?所以有大訪問量的時候希望用 Session,但是 Session 的致命弱點是不容易在多臺服務器之間共享,所以這也限制了 Session 的使用。

一、cookie

1:cookie的概念

Cookie是瀏覽器(User Agent)訪問一些網站后,這些網站存放在客戶端的一組數據,用于使網站等跟蹤用戶,實現用戶自定義功能。通俗地說就是當一個用戶通過 HTTP 協議訪問一個服務器的時候,這個服務器會將一些 Key/Value 鍵值對返回給客戶端瀏覽器,并給這些數據加上一些限制條件,在條件符合時這個用戶下次訪問這個服務器的時候,數據又被完整地帶回給服務器。

Cookie實際上是一小段的文本信息。客戶端請求服務器,如果服務器需要記錄該用戶狀態,就使用response向客戶端瀏覽器頒發一個Cookie。客戶端瀏覽器會把Cookie保存起來。當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該Cookie一同提交給服務器。服務器檢查該Cookie,以此來辨認用戶狀態。服務器還可以根據需要修改Cookie的內容。

在瀏覽器控制臺輸入javaScript:alert (document. cookie)就可以了(需要有網才能查看)。Javascript腳本會彈出一個對話框顯示本網站頒發的所有Cookie的內容。 這里寫圖片描述 注意:Cookie功能需要瀏覽器的支持。 如果瀏覽器不支持Cookie(如大部分手機中的瀏覽器)或者把Cookie禁用了,Cookie功能就會失效。 不同的瀏覽器采用不同的方式保存Cookie。

2:Cookie的功能

2.1:java中的Cookie

(1)Java中把Cookie封裝成了javax.servlet.http.Cookie類。每個Cookie都是該Cookie類的對象。 (2)服務器通過操作Cookie類對象對客戶端Cookie進行操作。通過request.getCookie()獲取客戶端提交的所有Cookie(以Cookie[]數組形式返回),通過response.addCookie(Cookiecookie)向客戶端設置Cookie。 Cookie對象使用key-value屬性對的形式保存用戶狀態,一個Cookie對象保存一個屬性對,一個request或者response同時使用多個Cookie。因為Cookie類位于包javax.servlet.http.*下面,所以jsp中不需要import該類。

2.2:Cookie的不可跨域名性

Cookie具有不可跨域名性。根據Cookie規范,瀏覽器訪問Google只會攜帶Google的Cookie,而不會攜帶Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。 Cookie在客戶端是由瀏覽器來管理的。瀏覽器能夠保證Google只會操作Google的Cookie而不會操作Baidu的Cookie,從而保證用戶的隱私安全。瀏覽器判斷一個網站是否能操作另一個網站Cookie的依據是域名。Google與Baidu的域名不一樣,因此Google不能操作Baidu的Cookie。 需要注意的是,雖然網站images.google.com與網站www.google.com同屬于Google,但是域名不一樣,二者同樣不能互相操作彼此的Cookie。

注意:用戶登錄網站www.google.com之后會發現訪問images.google.com時登錄信息仍然有效,而普通的Cookie是做不到的。這是因為Google做了特殊處理。

2.3:保存中文(Unicode編碼)

中文與英文字符不同,中文屬于Unicode字符,在內存中占4個字符,而英文屬于ASCII字符,內存中只占2個字節。Cookie中使用Unicode字符時需要對Unicode字符進行編碼,否則會亂碼。

提示:Cookie中保存中文只能編碼。一般使用UTF-8編碼即可。不推薦使用GBK等中文編碼,因為瀏覽器不一定支持,而且JavaScript也不支持GBK編碼。

2.4:BASE64編碼(保存二進制圖片)

Cookie不僅可以使用ASCII字符與Unicode字符,還可以使用二進制數據。例如在Cookie中使用數字證書,提供安全度。使用二進制數據時也需要進行編碼。 注意:本程序僅用于展示Cookie中可以存儲二進制內容,并不實用。由于瀏覽器每次請求服務器都會攜帶Cookie,因此Cookie內容不宜過多,否則影響速度。Cookie的內容應該少而精。

2.5:Cookie的屬性

除了name與value之外,Cookie還具有其他幾個常用的屬性。每個屬性對應一個getter方法與一個setter方法。

屬性名 描述
String name 該Cookie的名稱。Cookie一旦創建,名稱便不可更改
Object value 該Cookie的值。如果值為Unicode字符,需要為字符編碼。如果值為二進制數據,則需要使用BASE64編碼
int maxAge 該Cookie失效的時間,單位秒。如果為正數,則該Cookie在maxAge秒之后失效。如果為負數,該Cookie為臨時Cookie,關閉瀏覽器即失效,瀏覽器也不會以任何形式保存該Cookie。如果為0,表示刪除該Cookie。默認為–1
boolean secure 該Cookie是否僅被使用安全協議傳輸。安全協議。安全協議有HTTPS,SSL等,在網絡上傳輸數據之前先將數據加密。默認為false
String path 該Cookie的使用路徑。如果設置為“/sessionWeb/”,則只有contextPath為“/sessionWeb”的程序可以訪問該Cookie。如果設置為“/”,則本域名下contextPath都可以訪問該Cookie。注意最后一個字符必須為“/”
String domain 可以訪問該Cookie的域名。如果設置為“.google.com”,則所有以“google.com”結尾的域名都可以訪問該Cookie。注意第一個字符必須為“.”
String comment 該Cookie的用處說明。瀏覽器顯示Cookie信息的時候顯示該說明
int version 該Cookie使用的版本號。0表示遵循Netscape的Cookie規范,1表示遵循W3C的RFC 2109規范

2.6:Cookie的有效期

Cookie的maxAge決定著Cookie的有效期,單位為秒(Second)。Cookie中通過getMaxAge()方法與setMaxAge(int maxAge)方法來讀寫maxAge屬性。

如果maxAge屬性為正數,則表示該Cookie會在maxAge秒之后自動失效。瀏覽器會將maxAge為正數的Cookie持久化,即寫到對應的Cookie文件中。無論客戶關閉了瀏覽器還是電腦,只要還在maxAge秒之前,登錄網站時該Cookie仍然有效。

Cookie cookie = new Cookie("username","hello world"); // 新建Cookiecookie.setMaxAge(Integer.MAX_VALUE); // 設置生命周期為MAX_VALUEresponse.addCookie(cookie); // 輸出到客戶端

如果maxAge為負數,則表示該Cookie僅在本瀏覽器窗口以及本窗口打開的子窗口內有效,關閉窗口后該Cookie即失效。maxAge為負數的Cookie,為臨時性Cookie,不會被持久化,不會被寫到Cookie文件中。Cookie信息保存在瀏覽器內存中,因此關閉瀏覽器該Cookie就消失了。Cookie默認的maxAge值為–1。

如果maxAge為0,則表示刪除該Cookie。Cookie機制沒有提供刪除Cookie的方法,因此通過設置該Cookie即時失效實現刪除Cookie的效果。失效的Cookie會被瀏覽器從Cookie文件或者內存中刪除。

Cookie cookie = new Cookie("username","hello world"); // 新建Cookiecookie.setMaxAge(0); // 設置生命周期為0,不能為負數response.addCookie(cookie); // 必須執行這一句

response對象提供的Cookie操作方法只有一個添加操作add(Cookie cookie)。 要想修改Cookie只能使用一個同名的Cookie來覆蓋原來的Cookie,達到修改的目的。刪除時只需要把maxAge修改為0即可。

注意:從客戶端讀取Cookie時,包括maxAge在內的其他屬性都是不可讀的,也不會被提交。瀏覽器提交Cookie時只會提交name與value屬性。maxAge屬性只被瀏覽器用來判斷Cookie是否過期。

2.7:Cookie的修改和刪除

Cookie并不提供修改、刪除操作。如果要修改某個Cookie,只需要新建一個同名的Cookie,添加到response中覆蓋原來的Cookie。 如果要刪除某個Cookie,只需要新建一個同名的Cookie,并將maxAge設置為0,并添加到response中覆蓋原來的Cookie。注意是0而不是負數。負數代表其他的意義。

注意:修改、刪除Cookie時,新建的Cookie除value、maxAge之外的所有屬性,例如name、path、domain等,都要與原Cookie完全一樣。否則,瀏覽器將視為兩個不同的Cookie不予覆蓋,導致修改、刪除失敗。

2.8:Cookie的路徑

domain屬性決定運行訪問Cookie的域名,而path屬性決定允許訪問Cookie的路徑(ContextPath)。例如,如果只允許/session/下的程序使用Cookie,可以這么寫:

Cookie cookie = new Cookie("time","20170302"); // 新建Cookiecookie.setPath("/session/"); // 設置路徑response.addCookie(cookie); // 輸出到客戶端

注意:頁面只能獲取它屬于的Path的Cookie。例如/session/test/a.jsp不能獲取到路徑為/session/abc/的Cookie。使用時一定要注意。

2.9:Cookie的安全屬性

HTTP協議不僅是無狀態的,而且是不安全的。使用HTTP協議的數據不經過任何加密就直接在網絡上傳播,有被截獲的可能。使用HTTP協議傳輸很機密的內容是一種隱患。如果不希望Cookie在HTTP等非安全協議中傳輸,可以設置Cookie的secure屬性為true。瀏覽器只會在HTTPS和SSL等安全協議中傳輸此類Cookie。下面的代碼設置secure屬性為true:

Cookie cookie = new Cookie("time", "20170302"); // 新建Cookiecookie.setSecure(true); // 設置安全屬性response.addCookie(cookie); // 輸出到客戶端

提示:secure屬性并不能對Cookie內容加密,因而不能保證絕對的安全性。如果需要高安全性,需要在程序中對Cookie內容加密、解密,以防泄密。

2.10:JavaScript操作Cookie

Cookie是保存在瀏覽器端的,因此瀏覽器具有操作Cookie的先決條件。瀏覽器可以使用腳本程序如JavaScript或者VBScript等操作Cookie。這里以JavaScript為例介紹常用的Cookie操作。例如下面的代碼會輸出本頁面所有的Cookie。

<script>document.write(document.cookie);</script>

由于JavaScript能夠任意地讀寫Cookie,有些好事者便想使用JavaScript程序去窺探用戶在其他網站的Cookie。不過這是徒勞的,W3C組織早就意識到JavaScript對Cookie的讀寫所帶來的安全隱患并加以防備了,W3C標準的瀏覽器會阻止JavaScript讀寫任何不屬于自己網站的Cookie。換句話說,A網站的JavaScript程序讀寫B網站的Cookie不會有任何結果。

二、session

1:session的概念

Session是另一種記錄客戶狀態的機制,不同的是Cookie保存在客戶端瀏覽器中,而Session保存在服務器上。客戶端瀏覽器訪問服務器的時候,服務器把客戶端信息以某種形式記錄在服務器上。這就是Session。

Session 是存放在服務器端的類似于HashTable結構(每一種web開發技術的實現可能不一樣,下文直接稱之為HashTable)來存放用戶數據,當瀏覽器 第一次發送請求時,服務器自動生成了一個HashTable和一個Session ID用來唯一標識這個HashTable,并將其通過響應發送到瀏覽器。當瀏覽器第二次發送請求,會將前一次服務器響應中的Session ID放在請求中一并發送到服務器上,服務器從請求中提取出Session ID,并和保存的所有Session ID進行對比,找到這個用戶對應的HashTable。

一般情況下,服務器會在一定時間內(默認20分鐘)保存這個 HashTable,過了時間限制,就會銷毀這個HashTable。在銷毀之前,程序員可以將用戶的一些數據以Key和Value的形式暫時存放在這個 HashTable中。當然,也有使用數據庫將這個HashTable序列化后保存起來的,這樣的好處是沒了時間的限制,壞處是隨著時間的增加,這個數據 庫會急速膨脹,特別是訪問量增加的時候。一般還是采取前一種方式,以減輕服務器壓力。

2:session的功能

2.1:java中的session

Session對應的類為javax.servlet.http.HttpSession類。每個來訪者對應一個Session對象,所有該客戶的狀態信息都保存在這個Session對象里。Session對象是在客戶端第一次請求服務器的時候創建的。Session也是一種key-value的屬性對,通過getAttribute(Stringkey)和setAttribute(String key,Objectvalue)方法讀寫客戶狀態信息。Servlet里通過request.getSession()方法獲取該客戶的Session。

HttpSession session = request.getSession(); // 獲取Session對象session.setAttribute("loginTime", new Date()); // 設置Session中的屬性

提示:Session的使用比Cookie方便,但是過多的Session存儲在服務器內存中,會對服務器造成壓力。

2.2:Session的生命周期

Session在用戶第一次訪問服務器的時候自動創建。需要注意只有訪問JSP、Servlet等程序時才會創建Session,只訪問HTML、IMAGE等靜態資源并不會創建Session。如果尚未生成Session,也可以使用request.getSession(true)強制生成Session。 Session生成后,只要用戶繼續訪問,服務器就會更新Session的最后訪問時間,并維護該Session。用戶每訪問服務器一次,無論是否讀寫Session,服務器都認為該用戶的Session“活躍(active)”了一次。

2.3:Session的有效期

由于會有越來越多的用戶訪問服務器,因此Session也會越來越多。為防止內存溢出,服務器會把長時間內沒有活躍的Session從內存刪除。這個時間就是Session的超時時間。如果超過了超時時間沒訪問過服務器,Session就自動失效了。 Session的超時時間為maxInactiveInterval屬性,可以通過對應的getMaxInactiveInterval()獲取,通過setMaxInactiveInterval(longinterval)修改。 Session的超時時間也可以在web.xml中修改。另外,通過調用Session的invalidate()方法可以使Session失效。

2.4:Session的常用方法

方法名 描述
void setAttribute(String attribute, Object value) 設置Session屬性。value參數可以為任何Java Object。通常為Java Bean。value信息不宜過大
String getAttribute(String attribute) 返回Session屬性
Enumeration getAttributeNames() 返回Session中存在的屬性名
void removeAttribute(String attribute) 移除Session屬性
String getId() 返回Session的ID。該ID由服務器自動創建,不會重復
long getCreationTime() 返回Session的創建日期。返回類型為long,常被轉化為Date類型,例如:Date createTime = new Date(session.get CreationTime())
long getLastaccessedTime() 返回Session的最后活躍時間。返回類型為long
int getMaxInactiveInterval() 返回Session的超時時間。單位為秒。超過該時間沒有訪問,服務器認為該Session失效
void setMaxInactiveInterval(int second) 設置Session的超時時間。單位為秒
void putValue(String attribute, Object value) 不推薦的方法。已經被setAttribute(String attribute, Object Value)替代
Object getValue(String attribute) 不被推薦的方法。已經被getAttribute(String attr)替代
boolean isNew() 返回該Session是否是新創建的
void invalidate() 使該Session失效

Tomcat中Session的默認超時時間為20分鐘。通過setMaxInactiveInterval(int seconds)修改超時時間。可以修改web.xml改變Session的默認超時時間。例如修改為60分鐘:

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

注意:<session-timeout>參數的單位為分鐘,而setMaxInactiveInterval(int s)單位為秒。

2.5:Session判斷用戶

雖然Session保存在服務器,對客戶端是透明的,它的正常運行仍然需要客戶端瀏覽器的支持。這是因為Session需要使用Cookie作為識別標志。HTTP協議是無狀態的,Session不能依據HTTP連接來判斷是否為同一客戶,因此服務器向客戶端瀏覽器發送一個名為JSESSIONID的Cookie,它的值為該Session的id(也就是HttpSession.getId()的返回值)。Session依據該Cookie來識別是否為同一用戶。

該Cookie為服務器自動生成的,它的maxAge屬性一般為–1,表示僅當前瀏覽器內有效,并且各瀏覽器窗口間不共享,關閉瀏覽器就會失效。因此同一機器的兩個瀏覽器窗口訪問服務器時,會生成兩個不同的Session。但是由瀏覽器窗口內的鏈接、腳本等打開的新窗口(也就是說不是雙擊桌面瀏覽器圖標等打開的窗口)除外。這類子窗口會共享父窗口的Cookie,因此會共享一個Session。

注意:新開的瀏覽器窗口會生成新的Session,但子窗口除外。子窗口會共用父窗口的Session。例如,在鏈接上右擊,在彈出的快捷菜單中選擇“在新窗口中打開”時,子窗口便可以訪問父窗口的Session。 如果客戶端瀏覽器將Cookie功能禁用,或者不支持Cookie怎么辦?例如,絕大多數的手機瀏覽器都不支持Cookie。Java Web提供了另一種解決方案:URL地址重寫。

2.6:URL地址重寫

URL地址重寫是對客戶端不支持Cookie的解決方案。URL地址重寫的原理是將該用戶Session的id信息重寫到URL地址中。服務器能夠解析重寫后的URL獲取Session的id。這樣即使客戶端不支持Cookie,也可以使用Session來記錄用戶狀態。HttpServletResponse類提供了encodeURL(Stringurl)實現URL地址重寫,例如:

<td> <a href="<%=response.encodeURL("index.jsp?c=1&wd=test") %>">Homepage</a></td>

該方法會自動判斷客戶端是否支持Cookie。如果客戶端支持Cookie,會將URL原封不動地輸出來。如果客戶端不支持Cookie,則會將用戶Session的id重寫到URL中。重寫后的輸出可能是這樣的:

<td> <a href="index.jsp;jsessionid=0CCD096E7F8D97B0BE608AFDC3E1931E?c=1&wd=test">Homepage</a></td>

即在文件名的后面,在URL參數的前面添加了字符串“;jsessionid=XXX”。其中XXX為Session的id。分析一下可以知道,增添的jsessionid字符串既不會影響請求的文件名,也不會影響提交的地址欄參數。用戶單擊這個鏈接的時候會把Session的id通過URL提交到服務器上,服務器通過解析URL地址獲得Session的id。 如果是頁面重定向(Redirection),URL地址重寫可以這樣寫:

if(“administrator”.equals(userName)){ response.sendRedirect(response.encodeRedirectURL(“administrator.jsp”)); return;}

效果跟response.encodeURL(String url)是一樣的:如果客戶端支持Cookie,生成原URL地址,如果不支持Cookie,傳回重寫后的帶有jsessionid字符串的地址。 對于WAP程序,由于大部分的手機瀏覽器都不支持Cookie,WAP程序都會采用URL地址重寫來跟蹤用戶會話。

注意:TOMCAT判斷客戶端瀏覽器是否支持Cookie的依據是請求中是否含有Cookie。盡管客戶端可能會支持Cookie,但是由于第一次請求時不會攜帶任何Cookie(因為并無任何Cookie可以攜帶),URL地址重寫后的地址中仍然會帶有jsessionid。當第二次訪問時服務器已經在瀏覽器中寫入Cookie了,因此URL地址重寫后的地址中就不會帶有jsessionid了。

2.7:Session中禁止使用Cookie

既然WAP上大部分的客戶瀏覽器都不支持Cookie,索性禁止Session使用Cookie,統一使用URL地址重寫會更好一些。Java Web規范支持通過配置的方式禁用Cookie。下面舉例說一下怎樣通過配置禁止使用Cookie。 打開項目sessionWeb的WebRoot目錄下的META-INF文件夾(跟WEB-INF文件夾同級,如果沒有則創建),打開context.xml(如果沒有則創建),編輯內容如下:

<?xml version='1.0' encoding='UTF-8'?><Context path="/sessionWeb"cookies="false"></Context>

或者修改Tomcat全局的conf/context.xml,修改內容如下:

<!-- The contents of this file will be loaded for eachweb application --><Context cookies="false"> <!-- ... 中間代碼略 --></Context>

部署后tomcat便不會自動生成名JSESSIONID的Cookie,Session也不會以Cookie為識別標志,而僅僅以重寫后的URL地址為識別標志了。

注意:該配置只是禁止Session使用Cookie作為識別標志,并不能阻止其他的Cookie讀寫。也就是說服務器不會自動維護名為JSESSIONID的Cookie了,但是程序中仍然可以讀寫其他的Cookie。

參考文章: 深入理解 Session 與 Cookie Cookie/Session機制詳解 認識cookie與session的區別與應用 看完就徹底懂了session和cookie


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 杂多县| 松滋市| 玉环县| 杭州市| 桂阳县| 新郑市| 广平县| 玛多县| 姜堰市| 阆中市| 高陵县| 恭城| 平湖市| 阿拉尔市| 苏尼特左旗| 洛南县| 西盟| 阳信县| 阿克| 四子王旗| 华蓥市| 盐山县| 安福县| 翁源县| 托里县| 乌鲁木齐市| 永城市| 民和| 扶风县| 肥城市| 长治县| 沙雅县| 法库县| 唐山市| 新宁县| 航空| 安阳县| 丹阳市| 南乐县| 广丰县| 江西省|