1.會話技術簡介
1.1 存儲客戶端的狀態
例如網站的購物系統,用戶將購買商品的信息存儲到哪裏?由於Http協議是無狀態的,也就是說每一個客戶訪問服務器端資源時,服務器並不知道該客戶端是誰,因此須要會話技術識別客戶端的狀態。會話技術是幫助服務器記住客戶端狀態(區分客戶端)html
1.2 會話技術
從打開一個瀏覽器訪問某個網站,到關閉這個瀏覽器的整個過程,稱爲一次會話。會話技術就是記錄此次會話中客戶端的狀態與數據的。
會話技術分爲Cookie和Session:
Cookie:數據存儲在客戶端本地,減小服務器端的存儲的壓力,但安全性很差,客戶端能夠清除cookie
Session:將數據存儲到服務器端,安全性相對好,但增長服務器的壓力java
2.Cookie技術
Cookie技術是將用戶的數據存儲到客戶端的技術,咱們分爲兩方面學習:
第一,服務器端怎樣將一個Cookie發送到客戶端
第二,服務器端怎樣接受客戶端攜帶的Cookieweb
2.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信息
示例:
cookie.setPath("/WEB16");---------表明訪問WEB16應用中的任何資源都攜帶cookie
cookie.setPath("/WEB16/cookieServlet");----------表明訪問WEB16中的cookieServlet時才攜帶cookie信息瀏覽器
(4)向客戶端發送cookie
response.addCookie(Cookie cookie)安全
(5)刪除客戶端的cookie
若是想刪除客戶端的已經存儲的cookie信息,那麼就使用同名同路徑的持久化時間爲0的cookie進行覆蓋便可:cookie.setMaxAge(0)服務器
//刪除客戶端保存 name=zhangsan的cookie信息 Cookie cookie = new Cookie("name",""); //將path設置成與要刪除cookie的path一致 cookie.setPath("/WEB16"); //設置時間是0 cookie.setMaxAge(0); response.addCookie(cookie);
2.2 服務器接收客戶端的cookie
客戶端的cookie信息是以請求頭的方式發送到服務器端的:
(1)經過request得到全部的cookie:Cookie [ ] cookies=request.getCookies()cookie
(2)遍歷cookies數組,經過cookie的名稱得到想要的cookie
for(Cookie cookie : cookies){ if(cookie.getName().equal(cookieName)){ String cookieValue = cookie.getValue(); } }
3.session技術
Session技術是將數據存儲在服務器端的技術,會爲每一個客戶端都建立一塊內存空間,存儲客戶的數據,但客戶端須要每次都攜帶一個標識ID去服務器中尋找屬於本身的內存空間。因此說Session的實現是基於Cookie,Session須要藉助於Cookie存儲客 戶的惟一性標識JSESSIONID。
在Session這咱們須要學習以下三個問題:
怎樣得到屬於本客戶端的session對象(服務器內對應的內存區域)?
怎樣向session中存取數據(session也是一個域對象)?
session對象的生命週期?
(1)得到session對象
HttpSession session = request.getSession();
此方法會得到專屬於當前會話的Session對象,若是服務器端沒有該會話的Session對象,會建立一個新的Session返回,若是已經有了屬於該會話的Session,直接將已有的Session返回(實質就是根據JSESSIONID判斷該客戶端是否在服務器上已經存在session了)
(2)向session中存取數據
Session也是存儲數據的區域對象,因此session對象也具備以下三個方法:
session.setAttribute(String name,Object obj);
session.getAttribute(String name);
session.removeAttribute(String name);
(3)Session對象的生命週期(面試筆試)
session的做用範圍:默認在一次會話中,也就是說在一次會話中任何資源公用一個session對象
建立:第一次執行request.getSession()時建立
銷燬:
1.服務器(非正常)關閉時
2.session過時/失效(默認30分鐘)
過時/失效問題:時間的起算點從什麼時候開始計算30分鐘?從不操做服務器端的資源開始計時
能夠在工程的web.xml中進行配置來更改失效時間
<session-config>
<session-timeout>30</session-timeout>
</session-config>
3.手動銷燬session
session.invalidate();
面試題:瀏覽器關閉,session就銷燬了? 不對
案例:
顯示上次的訪問時間:
package com.itheima.lastaccesstime; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; 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); } }
驗證碼驗證:
先在產生驗證碼的servlet中,把驗證碼添加到session裏。
// 將驗證碼內容保存session request.getSession().setAttribute("checkcode_session", word);
package com.itheima.login; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; 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"); //得到生成圖片的文字的驗證碼 String checkCode_session = (String) request.getSession().getAttribute("checkcode_session"); //比對頁面的和生成圖片的文字的驗證碼是否一致 if(!checkCode_session.equals(checkCode_client)){ request.setAttribute("loginInfo", "您的驗證碼不正確"); request.getRequestDispatcher("/login.jsp").forward(request, response); return; } //得到頁面的用戶名和密碼進行數據庫的校驗 //...... } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }