JavaWeb學習筆記五 會話技術Cookie&Session
什麽是會話技術? 例如網站的購物系統,用戶將購買的商品信息存儲到哪裏?因為Http協議是無狀態的,也就是說每個客戶訪問服務器端資源時,服務器並不知道該客戶端是誰,所以需要會話技術識別客戶端的狀態。會話技術是幫助服務器記住客戶端狀態(區分客戶端)。
從打開一個瀏覽器訪問某個站點,到關閉這個瀏覽器的整個過程,成為一次會話。會話技術就是記錄這次會話中客戶端的狀態與數據的。會話技術分為Cookie和Session:
Cookie:數據存儲在客戶端本地,減少服務器端的存儲的壓力,安全性不好,客戶端可以清除cookie。
Session:將數據存儲到服務器端,安全性相對好,增加服務器的壓力。
Cookie技術
Cookie技術是將用戶的數據存儲到客戶端的技術,我們分為兩方面學習:
服務器端向客戶端發送一個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的最大有效時間 //cookie.setMaxAge(60*60); //設置為-1 , 就是相當於默認有效時間, 瀏覽器關閉就消失. //cookie.setMaxAge(-1); // 標示cookie的有效時間為0.發送到瀏覽器就消失了. //利用有效時間為0 這件事,我們可以做刪除cookie的操作. // 因為同一個路徑 ,不能存在相同的cookie(鍵相同). // 我們可以通過覆蓋的方式,設置有效時間為0. 刪除cookie //cookie.setMaxAge(0);
發送cookie完整代碼實例如下:
//1、創建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 //2、將cookie中存儲的信息發送到客戶端---頭 response.addCookie(cookie);
服務器端怎麽接受客戶端攜帶的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(); } }
完整示例:
//獲得客戶端攜帶的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); } } }
練習:獲取用戶上一次最後訪問的時間
//獲得當前時間 Date date = new Date(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String currentTime = format.format(date); //1、創建Cookie 記錄當前的最新的訪問時間 Cookie cookie = new Cookie("lastAccessTime",currentTime); cookie.setMaxAge(60*10*500); response.addCookie(cookie); //2、獲得客戶端攜帶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); }View Code
Session技術
Session技術是將數據存儲在服務器端的技術,會為每個客戶端都創建一塊內存空間存儲客戶的數據,但客戶端需要每次都攜帶一個標識ID去服務器中尋找屬於自己的內存空間。所以說Session的實現是基於Cookie,Session需要借助於Cookie存儲客 戶的唯一性標識JSESSIONID。
獲得Session對象
HttpSession session = request.getSession();
此方法會獲得專屬於當前會話的Session對象,如果服務器端沒有該會話的Session 對象會創建一個新的Session返回,如果已經有了屬於該會話的Session直接將已有 的Session返回(實質就是根據JSESSIONID判斷該客戶端是否在服務器上已經存在 session了)
怎樣向session中存取數據(session也是一個域對象)
Session也是存儲數據的區域對象,所以session對象也具有如下三個方法:
session.setAttribute(String name,Object obj);
session.getAttribute(String name);
session.removeAttribute(String name);
Session對象的一些方法
HttpSession session = request.getSession(); System.out.println(session.getCreationTime()); //創建時間 System.out.println(session.getLastAccessedTime());//最後一次訪問session的時間 System.out.println(session.getId() );//獲得sessionID System.out.println(session.getMaxInactiveInterval());//獲得最大存活時間
//setMaxInactiveInterval(int interval)
//invalidate 立即銷毀session
System.out.println(session.isNew());//查看當前獲得的session是否是新的.只有在第一訪問服務器,session是新的.
session.invalidate();
Session對象的生命周期
創建:第一次執行request.getSession()時創建
銷毀:
- 服務器(非正常)關閉時
- session過期/失效(默認30分鐘)
時間的起算點從何時開始計算30分鐘?
從不操作服務器端的資源開始計時,可以在工程的web.xml中進行配置
<session-config> <session-timeout>30</session-timeout> </session-config>
手動銷毀session
session.invalidate();
作用範圍
默認在一次會話中,也就是說在,一次會話中任何資源公用一個session對象。
瀏覽器關閉,session就銷毀了?
沒有,存在於瀏覽器上的唯一標識符JSESSIONID(sessionid)消失了,但是服務器中存放的sessionid並沒有立馬銷毀。
- 當在同一個瀏覽器中同時打開多個標簽,發送同一個請求或不同的請求,仍是同一個session;
- 當不在同一個窗口中打開相同的瀏覽器時,發送請求,仍是同一個session;
- 當使用不同的瀏覽器時,發送請求,即使發送相同的請求,是不同的session;
- 當把當前某個瀏覽器的窗口全關閉,再打開,發起相同的請求時,是不同的session。
驗證碼案例:
package session; import cn.dsna.util.images.ValidateCode; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * Created by yang on 2017/7/24. */ public class SessionDemo extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { //1 生成驗證碼 ValidateCode code = new ValidateCode(200, 80, 4, 100); //2 將驗證碼保存到session中 System.out.println(code.getCode()); request.getSession().setAttribute("code", code.getCode()); //3 將驗證碼圖片輸出到 瀏覽器 resp.setContentType("image/jpeg"); code.write(resp.getOutputStream()); } }SessionDemo
<%-- Created by IntelliJ IDEA. User: yang Date: 2017/7/23 Time: 11:34 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="/DServlet" method="post"> 驗證碼: <input type="text" name="code"/><img src="/SessionDemo" width="150" id="one" onclick="fun1();"/> <a href="javaScript:void(0)" onclick="fun1();">看不清換一張</a><br> <input type="submit" value="登錄"/> <br> </form> <%=request.getAttribute("error")==null?"":(String)request.getAttribute("error") %> </body> </html> <script type="text/javascript"> function fun1() { //1 獲得img對象 var img = document.getElementById("one"); //2 改變img對象 src屬性 img.src = "/SessionDemo?abc=" + new Date(); } </script>index.jsp
package session; import cn.dsna.util.images.ValidateCode; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * Created by yang on 2017/7/24. */ public class DServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { //1 獲得表單提交的驗證碼 String code1 = request.getParameter("code"); //2 獲得session中的正確驗證碼 String code2 = (String) request.getSession().getAttribute("code"); //3 比對是否一致 if(code1!=null && code2!=null && code1.equals(code2)){ //正確==> 成功頁面 resp.sendRedirect("/index.jsp"); }else{ //不正確==> 回到表單 頁面 ,提示錯誤 request.setAttribute("error", "驗證碼錯誤!請重新輸入"); request.getRequestDispatcher("/index.jsp").forward(request, resp); } } }DServlet
JavaWeb學習筆記五 會話技術Cookie&Session