cookie簡介: cookie來源:HTTP協議是一種無狀態協議,即本次請求與下次請求無關係。而在不同請求時需要進行數據傳遞,需要一種可以進行請求間數據傳遞的會話跟蹤技術,cookie因此而生。 cookie機制:用戶提交第一次請求後,由伺服器生成(是一種保存在客戶端的信息載體技術,cookie可 ...
cookie簡介:
cookie來源:HTTP協議是一種無狀態協議,即本次請求與下次請求無關係。而在不同請求時需要進行數據傳遞,需要一種可以進行請求間數據傳遞的會話跟蹤技術,cookie因此而生。
cookie機制:用戶提交第一次請求後,由伺服器生成(是一種保存在客戶端的信息載體技術,cookie可被清空,可失效),並將其封裝至響應頭,以響應形式發給客戶端,
客戶端收到響應後將cookie保存在客戶端。當客戶端再次發送同類請求後,在請求中會攜帶保存在客戶端的cookie數據發送給服務端。由伺服器對會話進行跟蹤。
cookie屬性:屬於web技術,非javaweb專項技術;由若幹鍵值對構成cookie("name","value");
註意:同類請求:http://localhost:8080/project/xxx/ccc/some 同類請求即資源路徑相同的請求 http://localhost:8080/project/xxx/ccc 資源路徑,(它在web.xml的<url-pattern>中),中間的project為項目名;some 資源名稱,即你寫的文件名。
只要你寫的 http://localhost:8080/project/xxx/ccc 路徑相同,則是同類路徑。
javaWeb中的cookie:
1,javaWeb中的cookie屬於一個類。
2,創建cookie:Cookie(String name,String value);例:Cookie cookie = new Cookie("student","zyz");
3,響應中添加cookie:response.addCookie("");響應中的方法。例:response.addCookie(cookie );
4,指定cookie綁定路徑:Cookie.setPath(request.getContextPath()+"xxx/ooo/aaa");
5,設置cookie有效期,此值為整數,單位秒:
cookie.setMaxAge(60*60);有效期一小時。 //該設置值 > 0,表示cookie存放在客戶端硬碟。
該設置值 < 0,與不設置一樣,將cookie存放在瀏覽器緩存。會話結束時cookie消失,即瀏覽器關了就沒了。
該設置值 = 0,表示cookie一生成就馬上失效。
6,獲取請求中的cookie:
Cookie[ ] cookies = request.getCookies();
7,遍歷cookie:
for(Cookie cookie : cookies) {
System.out.println(cookie.getName() + "===" + cookie.getValue());
if(cookies.getNmae().equals("student") && cookie.getValue().equals("zyz")) {
//你需要的操作
}else if {
//你需要的操作
}
}
cookie用法:創建cookie (some文件),響應cookie ;獲取cookie(other文件),再進行你需要的操作。 兩者在同路徑下。
cookie禁用:在瀏覽器中可以設置禁用cookie,去選“接受來自站點的cookie”禁用的是自己客戶端的cookie 。cookie被禁用後cookie仍然可以生成,但request無法獲取cookie,很多網站也將無法訪問。
javaWeb中的session (javaWeb開發中,Session是以javax.servlet.http.HttpSession的介面對象形式出現)
session的三個域書性空間對比:
1,ServletContext,置入其中的域屬性是整個應用範圍的,可以完成跨會話共用數據。應用啟動時創建,域屬性空間創建,不刪除則一直存在整個應用。空間很長。
2,HttpSession,置入其中的域屬性是會話範圍的,可以完成跨請求共用數據。
3,HrrpServletRequest,置入其中的域屬性是請求範圍的,可以跨servlet共用數據,但這寫servlet必須在同一請求中。生命周期很短,域屬性空間也很短。
三者使用原則:保證需求前提下,優先使用最小,節省伺服器記憶體,保證數據安全性。ServletContext > HttpSession > HrrpServletRequest,
session簡介
來源:也是web開發的會話跟蹤技術,同樣是伺服器生成。不同在cookie是將會話狀態保存在客戶端,session則是將會話狀態保存在服務端。
什麼是會話:用戶打開瀏覽器,發出第一次請求,到瀏覽器關閉,表示一次會話完成。
HttpSession的三個方法:
public void setAttribute(String name,Object value) {} 用於向session的域屬性空間中放入指定名稱,指定值的域屬性。
public void getAttribute(String name) {} 用於從session的域屬性空間中讀取指定名稱的域屬性。
public void removeAttribute(String name) {} 用於向session的域屬性空間中刪除指定名稱的域屬性。
在session與空間中存放數據:
首先要獲取了session對象才能存放數據。 HttpSession session=request.getSession();
在此註意獲取session對象要使用的方法,方法有兩個,特性如下:
1,getSession();無參
2,getSession(true/false);
true:如果有已創建的session就用已創建的,若沒有就新建
flase:如果有已創建的session就用已創建的,若沒有就不新建,返回null
一般情況下:1,向session域空間中寫入數據用getSession(true),即getSession();方法。因為要創建session對象存儲數據。
2,而從session域空間中讀數據則用getSession(false);方法。 讀取數據是要讀取先前創建的session對象中的數據,若選用true就會新建session對象,那session中就沒有數據了。
現在要在session域中寫入屬性。但是現沒有session,所以要創建就getSession(true);true可以不寫。
session的工作機制
1,寫入session列表:請求到達時將jsessionID和session對象寫到session列表中。
(伺服器對當前應用中的session以Map形式管理,Map稱為session列表。Map的key是一個32位隨機串即jsessionID,value則為session對象的引用,
用戶首次提交請求時,服務端servlet中執行到request.getSession()方法後自動生成Map.Entry對象,key據演算法生成jsessionID,value則時新創建的Httosession對象;)
2,伺服器生成併發送Cookie:在將session信息寫入session列表後,系統還會自動將jsessionID作為name,32位隨機串作為value,以Cookie的形式存放到響應頭中,並隨即響應,將cookie發送至客戶端;
3,客戶端接收併發送客戶端:客戶端接收到cookie後將其存入瀏覽器緩存,即客戶端瀏覽器不關閉,瀏覽器中cookie不消失。當用戶第二次請求時,會將緩存中的cookie伴隨請求頭部信息一塊發送都服務端。
4,送session列表中查找:服務端從請求中讀取到客戶發送的cookie,根據cookie的jsessionID的值,從Map中查找相應key所對應的value,即session對象,再對session對象的域屬性進行讀寫操作。
總結:servlet中獲取session,在session中寫入屬性,底層伺服器檢測到getSession後生成隨機字元串,再創建session對象,然後以32位隨機字元串為key,以session對象為value放入session列表中即Map中,
用戶首次請求servlet,伺服器再放入session列表後將32為隨機串包裝成cookie發送給客戶端瀏覽器(cookie的name==jsessionID,value==32位隨機串),客戶端瀏覽器接收cookie將其保存再緩存中。
當再次客戶端請求讀取數據時,會將瀏覽器緩存中cookie里的jsessionID放到請求頭部信息中發送給伺服器,伺服器拿到jsessionID後就去session列表中查找,
找到後key後就找到了key所對應的value(存放有域屬性的session),然後從中讀數據。
session失效
在web.xml中可以通過<session-config/>標簽設置session的超時時間,單位分鐘。預設session超時時間為30分鐘,這個時間指的是最後一次訪問開始計時,在指定時常內一直未被訪問的時常;
<session-config/>
<session-timeout>120</session-timeout>
<session-config/>
若未到超時時限,HttpSession中方法,invalide()可實現失效;
cookie禁用
首先生成隨機串,寫入session列表,隨機串包裝成cookie==jsessionID,放入響應頭,發送客戶端,這是服務端的cookie。客戶端接收cookie放入緩存,客戶端第二次請求時會將緩存中的cookie發送給伺服器,
好的,問題來了,如果客戶端禁用了cookie,那服務端發來的帶有cookie的響應,客戶端不會接收,不接收客戶端又提交一次請求,提交給服務端的這個請求沒有jsessionID大的cookie,服務端會將其看成第一次請求,
就會再次生成隨機串,包裝成cookie,生成session,發送給客戶端,客戶端因為session禁用,又不會接收,再一次請求服務端又看成第一次請求,就成迴圈,問題就大了。
問題:那麼cookie禁用了就不能是實現會話跟蹤了嗎?session就不能用了嗎?
能用。 禁用cookie,客戶端不接收服務端發送過來的cookie。但是會生成jsessionID,根據此次生成的jsessionID,再一次提交請求,session 還是會變,但是不會再重新生成新的cookie(也就時伺服器生成32位隨機數)。
//例:
http://localhost:8080/sessionandcookie/SomeSession:jsessionid=881CDDC1766E28391FS3E3E3B16669(這是上次會話生成的jsessionID,記錄下來,根據這個地址進去)
根據這個帶有jsessionID的地址進去提交請求,第一次sessionID是很變,但是不會生成cookie,也不會攜帶有jsessionID。
再一次刷新,會發現session也不會變,而後刷新多少次都不會變。因為根據jsessionID已經實現了會話跟蹤。
假設: 如果上一個人進入網頁或者某寶購物後,關閉瀏覽器走了,我們獲取了他網頁的jsessionID,那我們就能進入本次會話,簡單說就是進入他某寶賬戶,修改某些東西也是可以的。
但是這也就牽扯但一個問題。會話什麼時候結束?關閉了瀏覽器那算不算會話結束?
什麼是會話:
就客戶端而言:用戶打開瀏覽器,發出第一次請求,到瀏覽器關閉,表示一次會話完成。
服務端:
第一次請求開始,session失效時候會話結束。
關閉瀏覽器後伺服器的session依舊沒有失效,此次會話依舊可以進入。所以在使用非私人手機或電腦時要退出賬戶,數據解綁,session失效。
cookie禁用後重定向時的session跟蹤
上面談到,cookie禁用後的session跟蹤需要jsessionID進行跟蹤,但是這也意味著jsessionID暴露在地址欄,這會跟危險。
那怎麼才能不暴露jsessionID,而又能在cookie被禁用的情況下進行會話跟蹤呢?在此引入重定向。
例1:
RedirectServlet_1文件
HttoSession session = request.getSession(); //獲取session對象
session.setAttribute("user" , "student"); //寫入數據
System.out.println("RedirectServlet_1 session =" +session);
respone.sendRedirect(request.getContextPath() + "/RedirectServlet_2");
RedirectServlet_2
HttoSession session = request.getSession(false); //獲取session對象
System.out.print("RedirectServlet_2 : session = " + session);
//從session中獲取指定屬性
String user = null;
if(session != null) {
user = (String ) session.getAttribute("user");
}
PrintWriter out = respone.getWriter();
out.println("RedirectServlet_2 : user = " + user);
這個例子是cookie被禁用後使用重定向失敗的例子,結果為:
RedirectServlet_2 : user = null
響應頭信息為:
http://localhost:/cookieandsession/RedirectServlet_1 //響應有cookie(cookie==jsessionID),響應有信息session;
http://localhost:/cookieandsession/RedirectServlet_2 //響應沒有cookie(cookie==jsessionID),響應為null;
重定向時候又重新提交了一次請求;
這個案例失敗了,沒有跟蹤到會話;
例2:
RedirectServlet_1文件
HttoSession session = request.getSession(); //獲取session對象
session.setAttribute("user" , "student"); //寫入數據
System.out.println("RedirectServlet_1 session =" +session);
//加上這個方法
String url = request.getContextPath() + "/RedirectServlet_2";
url = response.encodeRedirectURL(url); //解決cookie禁用後session的跟蹤問題;
response.sendRedirect(url);
這個例子是cookie被禁用後使用重定向成功的例子,結果為:
RedirectServlet_2 : user = null
響應頭信息為:
http://localhost:/cookieandsession/RedirectServlet_1 //響應有cookie(cookie==jsessionID),響應有信息session;
http://localhost:/cookieandsession/RedirectServlet_2 //響應有cookie(cookie==jsessionID),響應為student;
此次重定向的請求cookie的jsessionID一樣。
如果cookie沒有被禁用,結果也是如此。只要加了這個方法不管cookie是否被禁用session都可以被禁用。但是最好不要禁用cookie,禁用後看似安全其實不安全。
cookie被禁用後進行session跟蹤,jsessionID也就暴露了,並不安全。
cookie禁用後非重定向的session跟蹤
超鏈接URL的重寫:
HttpServletResponse具有一個方法 encodeURL(),可以完成對類似超鏈接的非重定向頁面跳轉的URL重寫,即在其具體路徑後會自動添加jsessionID。
cookie沒有被禁用時
例1:
RedirectServlet_1文件
HttoSession session = request.getSession(); //獲取session對象
session.setAttribute("user" , "student"); //寫入數據
respone.setContentType("/text/html;charset = utf -8");
PrintWriter out = respone.getWriter();
out.println("<a href = 'RedirectServlet_2'>跳轉</a>到RedirectServlet_2");
省略RedirectServlet_2,與上一致
輸出結果:RedirectServlet_2 :user: = student
cookie被禁用時
沒有使用encode URL();方法
輸出結果:RedirectServlet_2 :user: =null
使用encode URL();方法
例1:
RedirectServlet_1文件
HttoSession session = request.getSession(); //獲取session對象
session.setAttribute("user" , "student"); //寫入數據
respone.setContentType("/text/html;charset = utf -8");
PrintWriter out = respone.getWriter();
String url = "RedirectServlet_2";
//解決cookie禁用後,非重定向時的session跟蹤問題;
url = response.encodeURL(url);
out.println("<a href = 'RedirectServlet_2'>跳轉</a>到RedirectServlet_2");
省略RedirectServlet_2,與上一致
輸出結果:RedirectServlet_2 :user: = student
以上為學習b站大佬後的筆記,大佬寫的很詳盡,再次附上學習地址 https://www.bilibili.com/video/BV1s4411z7zq