什麼是會話?
用戶打開浏覽器,訪問一個網站進行一系列操作,關閉浏覽器離開,完整過程 就是會話
會話過程中要解決的一些問題:
一種將用戶信息保存在客戶端技術 ,客戶端會將cookie信息自動發送給服務器。
1 import java.io.IOException; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.http.Cookie; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 public class CookieDemo1 extends HttpServlet { 10 11 public void doGet(HttpServletRequest request, HttpServletResponse response) 12 throws ServletException, IOException { 13 doPost(request, response); 14 15 } 16 17 public void doPost(HttpServletRequest request, HttpServletResponse response) 18 throws ServletException, IOException { 19 // 開始coding................ 20 /** 21 * 向浏覽器發送cookie 信息 api 演示 22 */ 23 // 1: 創建一個cookie 對象 24 // 第一個參數 cookie 名稱 第二個參數 保存該cookie 的值 cookie是不能存儲中文信息 25 Cookie cookie = new Cookie("cc", "hellocookieCC"); 26 // 默認cookie 會話結束 cookie 失效 會話機制的cookie 27 cookie.setMaxAge(3600 * 24 * 7);// 設置浏覽器保存cookie 信息的有效時間 持久化cookie 28 // 2: 發送給浏覽器 response 對象發送cookie 29 // 3: 設置cookie 訪問的有效路徑 30 cookie.setPath("/");// cookie 的有效路徑 表示 /day11/aa 31 // 下面的所有目錄都可以訪問該cookie 32 33 // 結論 cookie path 設置 / 34 // 發送cookie 到 浏覽器 35 response.addCookie(cookie); 36 37 } 38 39 }
1 import java.io.IOException; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.http.Cookie; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 public class GetCookie extends HttpServlet { 10 11 public void doGet(HttpServletRequest request, HttpServletResponse response) 12 throws ServletException, IOException { 13 doPost(request, response); 14 15 } 16 17 public void doPost(HttpServletRequest request, HttpServletResponse response) 18 throws ServletException, IOException { 19 // 開始coding................ 20 /** 21 * 獲取浏覽器保存的cookie 信息 浏覽器發送 .... 浏覽器每次發送請求,都攜帶cookie信息,這是浏覽器本身的機制 22 */ 23 // 1: 獲取cookie信息 ... 對象 request 24 Cookie[] cookies = request.getCookies();// 獲取cookie 數組 空? 25 26 for (Cookie cookie : cookies) { 27 System.out.println(cookie.getName() + "----" + cookie.getValue() 28 + "-----" + cookie.getPath()); 29 } 30 31 } 32 33 }
1 import javax.servlet.http.Cookie; 2 3 public class CookieUtils { 4 5 public static Cookie getCookie(String name, Cookie[] cookies) { 6 // 通過cookie name 在所有cookie 返回指定 的cookie 7 if (cookies == null) { 8 return null; 9 } else { 10 for (Cookie cookie : cookies) { 11 if (cookie.getName().equals(name)) { 12 return cookie; 13 } 14 } 15 } 16 return null; 17 } 18 19 }
cookie對象創建 new Cookie(name,value)
response.addCookie(cookie) 將cookie發送客戶端 保存到浏覽器中
* cookie有name和value
提供三個方法:getName 獲取cookie的名稱
getValue 獲取cookie 的值
setValue 設置cookie 的值
會話cookie:保存在浏覽器內存中,當會話結束浏覽器關閉,會話cookie信息就是丟失;
持久cookie:保存在浏覽器臨時文件緩存區中cookie(硬盤上) ,當關閉浏覽器結束會話,持久cookie不會被刪除
* 持久cookie存在過期時間,過期後會自動刪除
* 持久cookie 需要設置cookie 有效期 setMaxAge攜帶cookie 必須path一致
默認 http://localhost/day11/visit 生成cookie ----
默認path 就是/day11/ (visit資源所在目錄就是默認path)
* 只有在訪問 http://localhost/day11/ 目錄和子目錄情況下 才會攜帶cookie 信息
cookie 路徑: 設置Cookie 路徑 /day11/aa
表示在此路徑下的所有子目錄下的 都可以獲取該cookie信息
所以cc目錄下的cc.jsp可以獲取cookie信息 而 bb目錄下的獲取不到cookie 信息
CookieUtils.java——class【參考上面工具類:CookieUtils】
VisitServlet.java——servlet
1 import java.io.IOException; 2 import java.util.Date; 3 4 import javax.servlet.ServletException; 5 import javax.servlet.http.Cookie; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 10 import cn.itcast.day11.utils.CookieUtils; 11 12 public class VisitServlet extends HttpServlet { 13 14 public void doGet(HttpServletRequest request, HttpServletResponse response) 15 throws ServletException, IOException { 16 doPost(request, response); 17 18 } 19 20 public void doPost(HttpServletRequest request, HttpServletResponse response) 21 throws ServletException, IOException { 22 // 開始coding................ 23 response.setContentType("text/html;charset=utf-8"); 24 // 1: 先獲取 cookie 25 Cookie cookie = CookieUtils 26 .getCookie("lastvisit", request.getCookies()); 27 if (cookie == null) { 28 // 第一次訪問 29 response.getWriter().print("你是第一次訪問!"); 30 } else { 31 // cookie 不為空 已經訪問過... 32 String visitTime = cookie.getValue(); 33 34 response.getWriter().print( 35 "您上次訪問的時間:" 36 + 37 new Date(Long.parseLong(visitTime)).toLocaleString()); 38 39 } 40 long time = System.currentTimeMillis();//獲取當前訪問時間 41 cookie = new Cookie("lastvisit", time + "");//設置cookie的值 42 cookie.setMaxAge(3600 * 24 * 3);//設置cookie的有效時間 43 cookie.setPath("/");//設置cookie的有效路徑 44 response.addCookie(cookie);//將cookie發送給客戶端,保存在浏覽器中 45 46 } 47 48 }
*服務端向客戶端寫出一個新的cookie
默認cookie都是浏覽器內存中進行緩存的 ,當浏覽器關閉,會話結束,內存釋放
1 <%@page import="cn.itcast.day11.utils.CookieUtils"%> 2 <%@ page language="java" contentType="text/html; charset=UTF-8" 3 pageEncoding="UTF-8"%> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 8 <title>Insert title here</title> 9 </head> 10 <body> 11 12 <h2>商品列表</h2> 13 <a href="/day11/look?id=1">mac 電腦</a> 14 <a href="/day11/look?id=2">小米手機3</a> 15 <a href="/day11/look?id=3">雕牌洗衣液2瓶裝</a> 16 <a href="/day11/look?id=4">百事可樂一聽</a> 17 <hr> 18 <h3>商品浏覽記錄</h3> 19 <% 20 // java code ..... 21 Cookie cookie = CookieUtils.getCookie("ids", request.getCookies()); 22 if(cookie==null){ 23 out.print("你尚未浏覽商品"); 24 return; 25 } 26 String[] pros = {"mac 電腦","小米手機3","雕牌洗衣液2瓶裝","百事可樂一聽"}; 27 String[] ids = cookie.getValue().split(",");// 1 3 4 28 for(int i=0;i<ids.length;i++){ 29 out.print(pros[Integer.parseInt(ids[i])-1]+"<br>"); 30 } 31 %> 32 </body> 33 </html>
1 import java.io.IOException; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.http.Cookie; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 import cn.itcast.day11.utils.CookieUtils; 10 11 public class LookProductServlet extends HttpServlet { 12 13 public void doGet(HttpServletRequest request, HttpServletResponse response) 14 throws ServletException, IOException { 15 doPost(request, response); 16 17 } 18 19 public void doPost(HttpServletRequest request, HttpServletResponse response) 20 throws ServletException, IOException { 21 // 開始coding................ 22 response.setContentType("text/html;charset=utf-8"); 23 /** 24 * servlet 存放用戶浏覽商品的id 到cookie 1,2 ,3 25 */ 26 String id = request.getParameter("id");// 1 27 // 先判斷 id 28 Cookie cookie = CookieUtils.getCookie("ids", request.getCookies()); 29 if (cookie == null) { 30 // 第一查看 31 cookie = new Cookie("ids", id); 32 cookie.setMaxAge(3600 * 24 * 7); 33 cookie.setPath("/"); 34 } else { 35 // 商品浏覽 過 判斷 id 在不在已知的ids 裡面 36 String ids[] = cookie.getValue().split(",");// 1,2,3,4,5 37 if (!check(id, ids)) { 38 // 不 存在 ... 39 cookie.setValue(cookie.getValue() + "," + id); 40 cookie.setMaxAge(3600 * 24 * 7); 41 cookie.setPath("/"); 42 } 43 44 } 45 response.addCookie(cookie); 46 response.getWriter().print("查看成功<a href='/day11/product.jsp'>返回</a>"); 47 48 } 49 50 private boolean check(String id, String[] ids) { 51 for (String eachId : ids) { 52 if (eachId.equals(id)) { 53 return true; 54 } 55 } 56 return false; 57 } 58 59 }
Session :一種將用戶信息保存在服務器端技術 ,客戶端會持有Session信息對應key,通過key找到session信息
* Session 占用服務器空間,安全性更高 ,Cookie節省服務器資源,安全性差一些
Session 將用戶相關信息保存服務器端,服務器會為每個浏覽器創建單獨Session對象,每個用戶各自數據 保存各自浏覽器對應Session對象中。不同用戶獲取到各自浏覽器對應Session 保存數據。
session依賴cookie機制 實現用戶信息的保存.
通過JSESSIONID 將sessionId() 發送給浏覽器 使得浏覽器可以保存session id信息
獲取用戶的session 綁定數據.
*注意: 默認級別,發送的cookie 機制是會話級別的 浏覽器關閉session對象存在,但是cookie 保存的sessionId 會消失.
HttpSession 何時創建? session對象可以在servlet 和jsp 中創建
創建好session 容器會自動將seesionId通過cookie 機制 發送給浏覽器保存
* Session 通過cookie 傳輸 jsessionid 用來在服務器端查找對應Session對象
如何實現關閉浏覽器保留sessionid 信息 ?
解決方案:修改服務器默認的cookie機制 變成持久化cookie
1 Cookie cookie = new Cookie("JSESSIONID", session.getId());// session對應的cookie信息 2 cookie.setPath("/"); 3 cookie.setMaxAge(3600 * 24);//設置sessionId 的有效時間 4 response.addCookie(cookie);//發送給浏覽器保存sessionid 信息 5 //浏覽器獲取的cookie持久化的cookie,下次打開浏覽器就可以在服務器端找到sessio對象 (前提是session對象沒有被銷毀!)
*servlet 代碼request.getSession() 執行時創建(當前會話第一次執行)
*jsp 容器自動創建session 對象
1: 自然銷毀,默認30分鐘過期(連續不使用Session對象時間。即:session 如果一直處於休息狀態,容器主動銷毀session)
默認過期時間在tomcat/conf/web.xml 配置:
1 <session-config> 2 <session-timeout>30</session-timeout> 3 </session-config>
也可手動設置:
1 setMaxInactiveInterval(int interval)
2: 程序員主動銷毀session 對象
1 session.invalidate();//session 對象存放的數據就沒有了
3: 非正常關閉服務器(正常關閉服務器Session信息會被序列化到硬盤中 保存tomcat/work目錄)
1 session.removeAttribute();// 刪除當前Session對象中一個屬性值 2 session.invalidate();// 銷毀當前Session對象,刪除所有屬性
1 <%@ page language="java" contentType="text/html; charset=utf-8" 2 pageEncoding="utf-8"%> 3 <html> 4 <head> 5 <meta charset="UTF-8"> 6 <title>Insert title here</title> 7 <script type="text/javascript"> 8 function change() { 9 document.getElementById('img').src = '/day11/check?' 10 + new Date().getTime(); 11 } 12 </script> 13 </head> 14 <body> 15 <h3>注冊頁面</h3> 16 <h3 >${error }</h3> 17 <form action="/day11/register" method="post"> 18 用戶名<input type="text" name="name"><br> 19 密碼<input type="password" name="password"><br> 20 驗證碼<input type="text" name="checkCode"><img src="/day11/check" 21 onclick="change();" id="img"><br> 22 <input type="submit" value="注冊"> 23 </form> 24 </body> 25 </html>
1 import java.io.IOException; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.http.HttpServlet; 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletResponse; 7 8 public class RegisterServlet extends HttpServlet { 9 10 public void doGet(HttpServletRequest request, HttpServletResponse response) 11 throws ServletException, IOException { 12 doPost(request, response); 13 14 } 15 16 public void doPost(HttpServletRequest request, HttpServletResponse response) 17 throws ServletException, IOException { 18 // 開始coding................ 19 // 獲取表單提交的信息 20 request.setCharacterEncoding("utf-8"); 21 String name = request.getParameter("name"); 22 String password = request.getParameter("password"); 23 String inputCode = request.getParameter("checkCode"); 24 25 // 第一步 驗證驗證碼信息是否正確 26 // 獲取之前session 綁定驗證碼信息 比對 27 String codeSession = (String) request.getSession() 28 .getAttribute("check"); 29 // 一次驗證碼 用完就銷毀... 30 request.getSession().removeAttribute("check"); 31 // 比對 用戶輸入的code 和 session code 如果一致... 32 if (codeSession.equals(inputCode)) { 33 // 注冊事情..... 34 response.sendRedirect("/day11/login.jsp"); 35 36 } else { 37 // 驗證碼錯誤 跳回來 38 request.setAttribute("error", "驗證碼錯誤"); 39 request.getRequestDispatcher("/register.jsp").forward(request, 40 response); 41 } 42 43 } 44 45 }
* 一次性驗證碼,當驗證碼生成後,只使用一次,不管成功或者失敗,驗證碼都將失效
注意:一次驗證碼,用完就銷毀!
1 <%@page import="cn.itcast.day11.utils.CookieUtils"%> 2 <%@ page language="java" contentType="text/html; charset=UTF-8" 3 pageEncoding="UTF-8"%> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 8 <title>Insert title here</title> 9 </head> 10 <body> 11 <h2>商品列表</h2> 12 mac電腦<a href="/day11/cart?id=1"> 購買</a><br> 13 小米手機3 <a href="/day11/cart?id=2">購買</a><br> 14 雕牌洗衣液2瓶裝<a href="/day11/cart?id=3">購買</a><br> 15 百事可樂一聽 <a href="/day11/cart?id=4">購買</a><br> 16 17 <hr> 18 <a href="/day11/cart.jsp">查看購物車</a> 19 </body> 20 </html>
1 import java.io.IOException; 2 import java.util.HashMap; 3 import java.util.Map; 4 5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 10 public class CartServlet extends HttpServlet { 11 12 public void doGet(HttpServletRequest request, HttpServletResponse response) 13 throws ServletException, IOException { 14 doPost(request, response); 15 16 } 17 18 public void doPost(HttpServletRequest request, HttpServletResponse response) 19 throws ServletException, IOException { 20 // 開始coding................ 21 response.setContentType("text/html;charset=utf-8"); 22 String id = request.getParameter("id");// 3 2 3 23 // 通過id --->product 24 String pros[] = { "mac電腦", "小米手機3", "雕牌洗衣液2瓶裝", "百事可樂一聽" }; 25 String pro = pros[Integer.parseInt(id) - 1]; 26 27 // 做一個 購物車 28 Map<String, Integer> cart = (Map<String, Integer>) request.getSession() 29 .getAttribute("cart"); 30 // 2: 判斷購物車存在與否? 31 if (cart == null) { 32 // 購物車空 33 cart = new HashMap<String, Integer>(); 34 cart.put(pro, 1); 35 } else { 36 // 已經存在購物車 37 if (cart.containsKey(pro)) { 38 // 表示該購物車已經含有此商品 39 int count = cart.get(pro);// 得到該購物車商品的數量 40 // 數量+1 41 cart.put(pro, count += 1); 42 // 將已有的商品數量+1 43 } else { 44 cart.put(pro, 1); 45 } 46 47 } 48 request.getSession().setAttribute("cart", cart); 49 response.getWriter().print( 50 "購買成功!<a href='/day11/product_cart.jsp'>返回主頁</a>"); 51 } 52 53 }
1 <%@page import="java.util.*"%> 2 <%@ page language="java" contentType="text/html; charset=UTF-8" 3 pageEncoding="UTF-8"%> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 8 <title>Insert title here</title> 9 </head> 10 <body> 11 <h3>購物車列表</h3> 12 <!-- 如何從session 獲取購物車信息 --> 13 <% 14 // 1session 獲取數據 15 Map<String,Integer> cart = (Map<String,Integer>)session.getAttribute("cart"); 16 if(cart!=null){ 17 // 2: 如何迭代數據? 18 Set<String> set = cart.keySet(); 19 Iterator<String> it = set.iterator(); 20 while(it.hasNext()){ 21 String proName = it.next(); 22 int count = cart.get(proName); 23 out.print("商品名稱:"+proName+"---數量"+count+"<br>"); 24 } 25 }else{ 26 out.print("購物車無商品"); 27 } 28 %> 29 </body> 30 </html>
Servlet三種數據訪問范圍:ServletContext 、HttpSession、HttpServletRequest 1、保存ServletContext數據 ,在服務器關閉時才會刪除,生命周期最長,全局都可以訪問 (最少使用) * 應用場景:網站訪問次數、全局數據庫連接池 需要保存ServletContext 2、保存HttpSession數據 ,三種情況下丟失 ,主要保存用戶相關數據 (不建議存放大規模數據) * 應用場景: 用戶登錄信息、購物信息 保存HttpSession 3、保存HttpServletRequest,當前請求發生時產生,響應結束數據立刻釋放 (生命周期最短,最建議使用) *應用場景: Servlet獲得數據處理結果,通過請求轉發 傳遞信息給JSP顯示 三種數據范圍提供相同幾個方法 setAttribute getAttribute removeAttribute
1、Cookie和Session區別 ?
Cookie保存會話信息在客戶端,Session保存會話信息在服務器端,Session基於Cookie實現的
2、浏覽器關閉後,是不是Session對象就銷毀了 ?
不是,Session保存在服務器端,關閉浏覽器丟失jsessionid,
無法找到服務器對應Session對象了,需要等到Session過期後才會銷毀
3、會話cookie和持久cookie區別 ?
會話cookie 保存浏覽器內存緩存區中,關閉浏覽器後,會話cookie就會刪除
持久cookie 保存浏覽器臨時文件區 硬盤上,存在過期時間,當過期後會自動刪除,通過設置maxage為0刪除持久cookie
4、session的三種銷毀原因?
服務器非正常關閉、session過期、invalidate
5、如何實現關閉浏覽器再次打開,Session仍然可以訪問?
將jsessionid 對應cookie 持久化