本節內容:html
1. 存儲客戶端的狀態java
例如網站的購物系統,用戶將購買的商品信息存儲到哪裏?web
由於Http協議是無狀態的,也就是說每一個客戶訪問服務器端資源時,服務器並不知道該客戶端是誰,因此須要會話技術識別客戶端的狀態。面試
會話技術是幫助服務器記住客戶端狀態(區分客戶端)數據庫
2. 會話技術數組
從打開一個瀏覽器訪問某個站點,到關閉這個瀏覽器的整個過程,稱爲一次會話。會話技術就是記錄此次會話中客戶端的狀態與數據的。瀏覽器
會話技術分爲Cookie和Session:tomcat
Cookie技術是將用戶的數據存儲到客戶端的技術:安全
1. 服務器端向客戶端發送一個Cookie服務器
(1)建立Cookie:
Cookie cookie = new Cookie(String cookieName,String cookieValue);
【示例】:
Cookie cookie = new Cookie("username","zhangsan");
該cookie會以響應頭的形式發送給客戶端:
注意:Cookie中不能存儲中文。
(2)設置Cookie在客戶端的持久化時間
cookie.setMaxAge(int seconds); ---時間爲秒
注意:若是不設置持久化時間,cookie會存儲在瀏覽器的內存中,瀏覽器關閉 cookie信息銷燬(會話級別的cookie),若是設置持久化時間,cookie信息會被持久化到瀏覽器的磁盤文件裏。
【示例】:
cookie.setMaxAge(10*60);
設置cookie信息在瀏覽器的磁盤文件中存儲的時間是10分鐘,過時瀏覽器 自動刪除該cookie信息
(3)設置Cookie的攜帶路徑
cookie.setPath(String path);
注意:若是不設置攜帶路徑,那麼該cookie信息會在訪問產生該cookie的web資源所在的路徑都攜帶cookie信息。
好比:某個網站,你訪問http://localhost:8080/WEB16/demo/sendCookie,這時服務器往客戶端寫了cookie,而後你在訪問http://localhost:8080/WEB16/index.jsp時,是不會攜帶該cookie的。你訪問http://localhost:8080/WEB16/demo/*下的資源會攜帶該cookie。
【示例】:
cookie.setPath("/WEB16"); //表明訪問WEB16應用中的任何資源都攜帶cookie。 cookie.setPath("/WEB16/cookieServlet"); //表明訪問WEB16中的cookieServlet時才攜帶cookie信息。
(4)向客戶端發送cookie
response.addCookie(Cookie cookie);
(5)刪除客戶端的cookie:
若是想刪除客戶端的已經存儲的cookie信息,那麼就使用同名同路徑的持久化時間爲0的cookie進行覆蓋便可。
【示例】:
public class SendCookieServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //一、建立cookie對象 Cookie cookie = new Cookie("name","zhangsan"); //1.1 爲cookie設置持久化時間 ---- cookie信息在硬盤上保存的時間 cookie.setMaxAge(10*60);//10分鐘 ---- 時間設置爲0表明刪除該cookie //1.2 爲cookie設置攜帶的路徑 //cookie.setPath("/WEB16/sendCookie");//訪問sendCookie資源時才攜帶這個cookie cookie.setPath("/WEB16");//訪問WEB16下的任何資源時都攜帶這個cookie //cookie.setPath("/");//訪問服務器下的全部的資源都攜帶這個cookie //二、將cookie中存儲的信息發送到客戶端---頭 response.addCookie(cookie); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
public class RemoveCookieServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //刪除客戶端保存 name=zhangsan的cookie信息 Cookie cookie = new Cookie("name",""); //將path設置成與要刪除cookie的path一致 cookie.setPath("/WEB16"); //設置時間是0 cookie.setMaxAge(0); response.addCookie(cookie); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
2. 服務器端怎麼接受客戶端攜帶的Cookie
cookie信息是以請求頭的方式發送到服務器端的:
(1)經過request得到全部的Cookie:
Cookie[] cookies = request.getCookies();
(2)遍歷Cookie數組,經過Cookie的名稱得到咱們想要的Cookie
for(Cookie cookie : cookies){ if(cookie.getName().equal(cookieName)){ String cookieValue = cookie.getValue(); } }
public class GetCookieServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //得到客戶端攜帶的cookie的數據 Cookie[] cookies = request.getCookies(); //Cookie cookie = new Cookie("name","zhangsan"); //經過cookie名稱得到想要的cookie if(cookies!=null){ for(Cookie cookie : cookies){ //得到cookie的名稱 String cookieName = cookie.getName(); if(cookieName.equals("name")){ //得到該cookie的值 String cookieValue = cookie.getValue(); System.out.println(cookieValue); } } } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
public class LastAccessTimeServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //得到當前時間 Date date = new Date(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String currentTime = format.format(date); //一、建立Cookie 記錄當前的最新的訪問時間 Cookie cookie = new Cookie("lastAccessTime",currentTime); cookie.setMaxAge(60*10*500); response.addCookie(cookie); //二、得到客戶端攜帶cookie ---- lastAccessTime String lastAccessTime = null; Cookie[] cookies = request.getCookies(); if(cookies!=null){ for(Cookie coo : cookies){ if("lastAccessTime".equals(coo.getName())){ lastAccessTime = coo.getValue(); } } } response.setContentType("text/html;charset=UTF-8"); if(lastAccessTime==null){ response.getWriter().write("您是第一次訪問"); }else{ response.getWriter().write("您上次的訪問的時間是:"+lastAccessTime); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
Session技術是將數據存儲在服務器端的技術,會爲每一個客戶端都建立一塊內存空間 存儲客戶的數據,但客戶端須要每次都攜帶一個標識ID去服務器中尋找屬於本身的內 存空間。因此說Session的實現是基於Cookie,Session須要藉助於Cookie存儲客戶端的惟一性標識JSESSIONID。這個JSESSIONID是Tomcat容器幫咱們設置到cookie中的。
在Session中須要解決以下三個問題:
1. 得到Session對象
HttpSession session = request.getSession(); //request對象內部維護着session區域的引用。session區域比request區域大,經過小的能夠得到大的
此方法會得到專屬於當前會話的Session對象,若是服務器端沒有該會話的Session對象會建立一個新的Session返回,若是已經有了屬於該會話的Session直接將已有 的Session返回(實質就是根據JSESSIONID判斷該客戶端是否在服務器上已經存在 session了)。
2. 怎樣向session中存取數據(session也是一個域對象)
Session也是存儲數據的區域對象,因此session對象也具備以下三個方法:
3. Session對象的生命週期(面試題/筆試題)
建立:第一次執行request.getSession()時建立。
銷燬:
1) 服務器(非正常)關閉時
2) session過時/失效(默認30分鐘,tomcat全局的web.xml裏配置的是30min)
時間的起算點:從不操做服務器端的資源開始計時,計算30分鐘?
能夠在工程的web.xml中進行配置:
<session-config> <session-timeout>30</session-timeout> </session-config>
3)手動銷燬session
session.invalidate();
Session域對象做用範圍:
默認在一次會話中,也就是說在一次會話中任何資源公用一個session對象。
【示例】:
public class SessionServlet1 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //建立屬於該客戶端(會話)的私有的session區域 /* request.getSession()方法內部會判斷 該客戶端是否在服務器端已經存在session * 若是該客戶端在此服務器不存在session 那麼就會建立一個新的session對象 * 若是該客戶端在此服務器已經存在session 得到已經存在的該session返回 */ HttpSession session = request.getSession(); session.setAttribute("name", "jerry"); String id = session.getId();//該session對象的編號id response.getWriter().write("JSESSIONID:"+id); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
public class SessionServlet2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //從session中得到存儲的數據 HttpSession session = request.getSession(); Object attribute = session.getAttribute("name"); response.getWriter().write(attribute+""); //防止獲取的 attribute爲null,沒法轉換爲String,因此+"" } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
面試題:瀏覽器關閉,session就銷燬了? 不對。session是存在服務器端的,客戶端關閉,不影響服務器端的session。session銷燬有本身的方式。
4. JSESSIONID持久化
默認一關閉瀏覽器,cookie裏的JSESSIONID就沒了。能夠手動設置JSESSIONID,並設置其失效時間。這樣打開瀏覽器,再去請求時就會攜帶JSESSIONID,這就是session持久化。session要是不持久化,若是想往購物車加東西,關了瀏覽器,再打開,購物車裏東西就沒有了。
public class SessionServlet1 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //建立屬於該客戶端(會話)的私有的session區域 /* request.getSession()方法內部會判斷 該客戶端是否在服務器端已經存在session * 若是該客戶端在此服務器不存在session 那麼就會建立一個新的session對象 * 若是該客戶端在此服務器已經存在session 得到已經存在的該session返回 */ HttpSession session = request.getSession(); session.setAttribute("name", "jerry"); String id = session.getId();//該session對象的編號id //手動建立一個存儲JSESSIONID的Cookie 爲該cookie設置持久化時間 Cookie cookie = new Cookie("JSESSIONID",id); cookie.setPath("/WEB16/"); cookie.setMaxAge(60*10); response.addCookie(cookie); response.getWriter().write("JSESSIONID:"+id); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
頁面加載生成驗證碼時,將驗證碼中的字符存於session域,校驗驗證碼時,獲取客戶端用戶輸入的驗證碼與從session域中取出的驗證碼字符進行對比。
public class LoginServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); //驗證碼校驗 //得到頁面輸入的驗證碼 String checkCode_client = request.getParameter("checkCode"); //得到生成圖片的驗證碼中的文字,從session域中獲取 String checkCode_session = (String) request.getSession().getAttribute("checkcode_session"); //比對頁面的和生成圖片的文字的驗證碼是否一致 if(!checkCode_session.equals(checkCode_client)){ request.setAttribute("loginInfo", "您的驗證碼不正確"); //這些錯誤信息不建議存在session中 request.getRequestDispatcher("/login.jsp").forward(request, response); //轉發 return; //這樣就不執行下面的代碼了 } //得到頁面的用戶名和密碼進行數據庫的校驗 //...... } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }