JavaWeb中的Cookie和Session解讀
Cookie
Cookie是servlet發(fā)送到Web瀏覽器的少量信息,該信息由瀏覽器保存,然后發(fā)送回服務(wù)器。一般情況下,Cookie是以鍵值對(duì)進(jìn)行表示的(key-value),Cookie的值可以唯一地標(biāo)識(shí)客戶端,因此Cookie常用于會(huì)話管理。servlet通過使用HttpServletResponse#addCookie方法將cookie發(fā)送到瀏覽器,該方法將字段添加到http響應(yīng)頭,以便一次一次地將cookie發(fā)送到瀏覽器,每個(gè)Cookie的大小限定為4kb。
創(chuàng)建Cookie
客戶端沒有Cookie -> 服務(wù)器創(chuàng)建Cookie -> 通知客戶端保存Cookie -> 通過響應(yīng)頭Set-Cookie通知客戶端保存Cookie(Set-Cookie:key=value) ->客戶端收到響應(yīng)后發(fā)現(xiàn)set-cookie響應(yīng)頭,查看有沒有Cookie,如果沒有就創(chuàng)建如果有就修改。
package com.pero.servlet.cookie_session; import jakarta.servlet.*; import jakarta.servlet.http.*; import java.io.IOException; import java.lang.reflect.Method; public abstract class BaseServlet extends HttpServlet { protected void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); String action = request.getParameter("action"); try { Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class); method.invoke(this,request,response); } catch (Exception e) { throw new RuntimeException(e); } } }
package com.pero.servlet.cookie_session; import jakarta.servlet.*; import jakarta.servlet.http.*; import java.io.IOException; public class CookieServlet extends BaseServlet { protected void createCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //創(chuàng)建Cookie Cookie cookie = new Cookie("key","value"); //通知客戶端保存 response.addCookie(cookie); response.getWriter().write("Cookie創(chuàng)建成功"); } }
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="pragma" content="no-cache" /> <meta http-equiv="cache-control" content="no-cache" /> <meta http-equiv="Expires" content="0" /> <meta http-equiv="content-type" content="text/html;charset=UTF-8"> <title>Cookie</title> <base href="http://localhost:8080/cookie_session/" rel="external nofollow" rel="external nofollow" > <style type="text/css"> ul li{ list-style: none; } </style> </head> <body> <iframe name="target" width="500" height="500" style="..."></iframe> <div style="..."> <ul> <li><a href="cookieServlet?action=createCookie" rel="external nofollow" target="target">Cookie的創(chuàng)建</a></li> <li><a href="cookieServlet?action=getCookie" rel="external nofollow" target="target">Cookie的獲取</a></li> <li><a href="cookieServlet?action=updateCookie" rel="external nofollow" target="target">Cookie值的修改</a></li> <li>Cookie的存活周期</li> <li> <ul> <li><a href="cookieServlet?action=defaultLifeCookie" rel="external nofollow" target="target">Cookie的默認(rèn)存活時(shí)間(會(huì)話)</a></li> <li><a href="cookieServlet?action=deleteNowCookie" rel="external nofollow" target="target">Cookie立即刪除</a></li> <li><a href="cookieServlet?action=life5Cookie" rel="external nofollow" target="target">Cookie存活5秒</a></li> </ul> </li> <li><a href="cookieServlet?action=pathCookie" rel="external nofollow" target="target">Cookie的路徑設(shè)置</a></li> <li><a href="" target=" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" target">Cookie的用戶登錄練習(xí)</a></li> </ul> </div> </body> </html>
服務(wù)器獲取Cookie
客戶端有了Cookie的值 -> 通過請(qǐng)求頭:Cookie:key=value 把Cookie信息發(fā)送給服務(wù)器 -> 服務(wù)器獲取客戶端發(fā)送過來的Cookie只需要一行代碼{request.getCookies():返回Cookie[]數(shù)組}
package com.pero.servlet.cookie_session; import com.pero.servlet.util.CookieUtil; import jakarta.servlet.*; import jakarta.servlet.http.*; import java.io.IOException; public class CookieServlet extends BaseServlet { protected void getCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie[] cookies = request.getCookies(); for (Cookie cookie : cookies) { //getName()獲取Cookie的Key值,getValue()方法獲取Cookie的value值 response.getWriter().write("Cookie{" + cookie.getName() + ":" + cookie.getValue() + "} <br/>"); } Cookie iWantCookie = CookieUtil.findCookie("key",cookies); //如果不等于null意味著找到了Cookie if (iWantCookie != null){ response.getWriter().write("找到了Cookie"); } } ... }
package com.pero.servlet.util; import jakarta.servlet.http.Cookie; public class CookieUtil { /** * 查找指定名稱的Cookie對(duì)象 * @param name * @param cookies * @return */ public static Cookie findCookie(String name,Cookie[] cookies){ if (name == null || cookies == null || cookies.length ==0){ return null; } for (Cookie cookie : cookies) { if (name.equals(cookie.getName())){ return cookie; } } return null; } }
Cookie值的修改
package com.pero.servlet.cookie_session; import com.pero.servlet.util.CookieUtil; import jakarta.servlet.*; import jakarta.servlet.http.*; import java.io.IOException; public class CookieServlet extends BaseServlet { protected void updateCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //方法一: //創(chuàng)建需要修改的同名Cookie對(duì)象 //在構(gòu)造器中同時(shí)賦予新的Cookie值 // Cookie cookie = new Cookie("key","newValue"); //調(diào)用response.addCookie(Cookie) // response.addCookie(cookie); // response.getWriter().write("key的Cookie的值已經(jīng)修改"); //方法二 //查找需要修改的Cookie對(duì)象 Cookie cookie = CookieUtil.findCookie("key",request.getCookies()); //調(diào)用setValue()方法付于心的Cookie值 if (cookie != null){ cookie.setValue("NewCookie"); } //調(diào)用response.addCookie(cookie)通知客戶端保存修改 response.addCookie(cookie); } ... }
Cookie的生命控制
Cookie的生命控制指的是如何管理Cookie什么時(shí)候被銷毀(刪除)。setMaxAge();整數(shù)表示在指定秒數(shù)后過期,負(fù)數(shù)表示瀏覽器一關(guān)Cookie就會(huì)被刪除(程序默認(rèn)),0表示立刻刪除Cookie。
package com.pero.servlet.cookie_session; import com.pero.servlet.util.CookieUtil; import jakarta.servlet.*; import jakarta.servlet.http.*; import java.io.IOException; public class CookieServlet extends BaseServlet { protected void life5Cookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie cookie = new Cookie("life5","life5"); cookie.setMaxAge(5); //設(shè)置Cookie5秒后刪除 response.addCookie(cookie); response.getWriter().write("創(chuàng)建了5秒鐘的Cookie"); } protected void deleteNowCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //查找需要?jiǎng)h除的Cookie Cookie cookie = CookieUtil.findCookie("key",request.getCookies()); if (cookie != null){ //設(shè)置cookie.setMaxAge(0);立刻銷毀Cookie cookie.setMaxAge(0); //response.addCookie();瀏覽器保存 response.addCookie(cookie); response.getWriter().write("key的Cookie已經(jīng)被刪除"); } } protected void defaultLifeCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie cookie = new Cookie("defaultLife","defaultLife"); cookie.setMaxAge(-1); //設(shè)置存活時(shí)間為瀏覽器退出后Cookie被銷毀 response.addCookie(cookie); } ... }
Cookie有效路徑Path的設(shè)置
Cookie的path屬性可以有效的過濾那些Cookie可以發(fā)送給服務(wù)器那些不發(fā)送,path屬性是通過請(qǐng)求的地址來進(jìn)行過濾。
package com.pero.servlet.cookie_session; import com.pero.servlet.util.CookieUtil; import jakarta.servlet.*; import jakarta.servlet.http.*; import java.io.IOException; public class CookieServlet extends BaseServlet { protected void pathCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie cookie = new Cookie("path","path"); //getContextPath()得到工程路徑 cookie.setPath(request.getContextPath() + "/file"); response.addCookie(cookie); response.getWriter().write("創(chuàng)建了一個(gè)帶有Path路徑的Cookie"); } ... }
Cookie練習(xí)免用戶名登陸
第一次登錄時(shí):客戶端(瀏覽器)第一次訪問,服務(wù)器返回給客戶端登陸頁面,填寫用戶名和密碼后提交給服務(wù)器,服務(wù)器獲取用戶名和密碼,判斷用戶名和密碼是否正確,正確允許登錄,錯(cuò)誤不允許登錄,把用戶名保存為Cookie發(fā)送給客戶端,瀏覽器有了用戶名和Cookie信息;
第二次登陸時(shí):客戶端(瀏覽器)第二次訪問服務(wù)器會(huì)把Cookie信息發(fā)給服務(wù)器,服務(wù)器返回給客戶端帶用戶名的登錄界面。
package com.pero.servlet.cookie_session; import jakarta.servlet.*; import jakarta.servlet.http.*; import java.io.IOException; public class LoginServlet extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); if ("root".equals(username) && "root".equals(password)){ //登陸成功 Cookie cookie = new Cookie("username", username); cookie.setMaxAge(60*60*24*7); //cookie一周內(nèi)有效 response.addCookie(cookie); System.out.println("登陸成功"); }else { System.out.println("登陸失敗"); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2023/3/16 Time: 18:35 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="http://localhost:8080/cookie_session/loginServlet" method="get"> 用戶名:<input type="text" name="username" value="${cookie.username.value}"> 密 碼:<input type="password" name="password"> <input type="submit" value="登錄"> </form> </body> </html>
Session
Session是一個(gè)接口(HttpSession),Session是會(huì)話,用來維護(hù)一個(gè)客戶端和服務(wù)器之間關(guān)聯(lián)的一種技術(shù),每個(gè)客戶端都有自己的一個(gè)Session會(huì)話,Session會(huì)話中經(jīng)常用來保存用戶登錄之后的信息。
創(chuàng)建Session和獲取
- request.getSession():第一次調(diào)用是創(chuàng)建Session會(huì)話,之后都是調(diào)用,獲取前面創(chuàng)建好的Session會(huì)話對(duì)象;
- isNew():判斷是不是新創(chuàng)建出來的Session,true表示新創(chuàng)建,false表示獲取之前創(chuàng)建的;
- getId():得到Session會(huì)話的id值,每一個(gè)會(huì)話都有一個(gè)id值,這個(gè)id值是唯一的。
package com.pero.servlet.cookie_session; import jakarta.servlet.*; import jakarta.servlet.http.*; import java.io.IOException; public class SessionServlet extends BaseServlet { protected void createOrGetSession(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //創(chuàng)建和獲取Session會(huì)話對(duì)象 HttpSession session = request.getSession(); //判斷當(dāng)前Session會(huì)話是否是新創(chuàng)建出來的 boolean isNew = session.isNew(); //獲取Session會(huì)話的唯一標(biāo)識(shí) String id = session.getId(); response.getWriter().write("得到的Session的ID:" + id + " <br/>"); response.getWriter().write("Session是否為新創(chuàng)建的:" + isNew + " <br/>"); } }
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="pragma" content="no-cache"/> <meta http-equiv="cache-control" content="no-cache"/> <meta http-equiv="Expires" content="0"/> <meta http-equiv="content-type" content="text/html;charset=UTF-8"> <title>Session</title> <base href="http://localhost:8080/cookie_session/" rel="external nofollow" rel="external nofollow" > <style type="text/css"> ul li { list-style: none; } </style> </head> <body> <iframe name="target" width="500" height="500" style="..."></iframe> <div style="..."> <ul> <li><a href="sessionServlet?action=createOrGetSession" rel="external nofollow" target="target">Session的創(chuàng)建和獲取</a></li> <li><a href="" target=" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" target">Session域數(shù)據(jù)的存儲(chǔ)</a></li> <li><a href="" target=" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" target">Session域數(shù)據(jù)的獲取</a></li> <li>Session的存活周期</li> <li> <ul> <li><a href="" target=" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" target">Session默認(rèn)超時(shí)配置</a></li> <li><a href="" target=" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" target">Session5秒超時(shí)銷毀</a></li> <li><a href="" target=" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" target">Session立刻銷毀</a></li> </ul> </li> <li><a href="" target=" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" target">瀏覽器和Session綁定的原理</a></li> </ul> </div> </body> </html>
Session域中數(shù)據(jù)的存取
package com.pero.servlet.cookie_session; import jakarta.servlet.*; import jakarta.servlet.http.*; import java.io.IOException; public class SessionServlet extends BaseServlet { protected void getAttributeSession(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); Object attribute = session.getAttribute("key"); response.getWriter().write("從Session中獲取key的值為:" + attribute); } protected void setAttributeSession(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); session.setAttribute("key","value"); response.getWriter().write("已經(jīng)向Session中存儲(chǔ)值"); } ... }
Session生命周期
Session超時(shí)是指客戶端兩次請(qǐng)求的最大間隔時(shí)間。
- public void setMaxInactiveInterval(int interval):設(shè)置Session超時(shí)時(shí)間(以秒為單位),超過指定時(shí)長Session會(huì)被銷毀,值為正數(shù)的時(shí)候,設(shè)定Session的超市時(shí)長,值為負(fù)數(shù)的時(shí)候,Session永不超時(shí);
- public void invalidate():讓Session會(huì)話立刻超時(shí)無效;
- public int getMaxInactiveInterval():獲取Session的超時(shí)時(shí)間;
Session的默認(rèn)超時(shí)時(shí)長為:Session的默認(rèn)超時(shí)時(shí)長為1800秒。
package com.pero.servlet.cookie_session; import jakarta.servlet.*; import jakarta.servlet.http.*; import java.io.IOException; public class SessionServlet extends BaseServlet { protected void defaultLife(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); int maxInactiveInterval = session.getMaxInactiveInterval(); response.getWriter().write("Session的默認(rèn)超時(shí)時(shí)長為" + maxInactiveInterval + "秒"); } ... }
如果調(diào)整web工程的超時(shí)時(shí)長,可以在web.xml中進(jìn)行配置。
<!-- 表示當(dāng)前web工程創(chuàng)建出來的所有Session默認(rèn)是20分鐘超時(shí)時(shí)長 --> <session-config> <session-timeout>10</session-timeout> </session-config>
也可以通過setMaxInactiveInterval(int interval)設(shè)置Session超時(shí)時(shí)間
package com.pero.servlet.cookie_session; import jakarta.servlet.*; import jakarta.servlet.http.*; import java.io.IOException; public class SessionServlet extends BaseServlet { protected void life5Session(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); //設(shè)置當(dāng)前Session5秒后超時(shí) session.setMaxInactiveInterval(5); response.getWriter().write("當(dāng)前Session已經(jīng)設(shè)置為5秒后超時(shí)"); } ... }
設(shè)置Session立刻超時(shí)
package com.pero.servlet.cookie_session; import jakarta.servlet.*; import jakarta.servlet.http.*; import java.io.IOException; public class SessionServlet extends BaseServlet { protected void shutDownSession(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); //設(shè)置當(dāng)前Session立刻超時(shí) session.invalidate(); response.getWriter().write("當(dāng)前Session立刻超時(shí)關(guān)閉"); } ... }
瀏覽器和Session之間關(guān)聯(lián)的技術(shù)
Session技術(shù)底層是基于Cookie技術(shù)實(shí)現(xiàn)的。
到此這篇關(guān)于JavaWeb中的Cookie和Session解讀的文章就介紹到這了,更多相關(guān)Cookie和Session解讀內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java面向?qū)ο笤O(shè)計(jì)原則之迪米特法則分析詳解
這篇文章主要為大家介紹了java面向?qū)ο笤O(shè)計(jì)原則之迪米特法則的示例分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,學(xué)有所得2021-10-10Java中LinkedHashSet、LinkedHashMap源碼詳解
這篇文章主要介紹了Java中LinkedHashSet、LinkedHashMap源碼詳解,LinkedHashMap是一個(gè)以雙向鏈表的方式將Entry節(jié)點(diǎn)鏈接起來的HashMap子類,它在HashMap的基礎(chǔ)上實(shí)現(xiàn)了更多的功能,具有順序存儲(chǔ)和遍歷的特性,需要的朋友可以參考下2023-09-09關(guān)于feign對(duì)x-www-form-urlencode類型的encode和decode問題
這篇文章主要介紹了關(guān)于feign對(duì)x-www-form-urlencode類型的encode和decode問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Spring Security添加驗(yàn)證碼的兩種方式小結(jié)
使用spring security的時(shí)候,框架會(huì)幫我們做賬戶密碼的驗(yàn)證,但是如我們需要添加一個(gè)驗(yàn)證碼,就需要對(duì)配置文件進(jìn)行修改,這篇文章主要給大家介紹了關(guān)于Spring Security添加驗(yàn)證碼的兩種方式,需要的朋友可以參考下2021-10-10阿里nacos+springboot+dubbo2.7.3統(tǒng)一處理異常的兩種方式
本文主要介紹了阿里nacos+springboot+dubbo2.7.3統(tǒng)一處理異常的兩種方式,文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03MyBatis與SpringMVC相結(jié)合實(shí)現(xiàn)文件上傳、下載功能
這篇文章主要介紹了MyBatis與SpringMVC相結(jié)合實(shí)現(xiàn)文件上傳、下載功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06