cookie和session

本節內容:html

  • 會話技術簡介
  • Cookie技術
  • 案例一:記錄用戶的上次訪問時間
  • Session技術
  • 案例二:實現驗證碼的校驗

 

1、會話技術簡介

1. 存儲客戶端的狀態java

例如網站的購物系統,用戶將購買的商品信息存儲到哪裏?web

由於Http協議是無狀態的,也就是說每一個客戶訪問服務器端資源時,服務器並不知道該客戶端是誰,因此須要會話技術識別客戶端的狀態。面試

會話技術是幫助服務器記住客戶端狀態(區分客戶端)數據庫

 

2. 會話技術數組

從打開一個瀏覽器訪問某個站點,到關閉這個瀏覽器的整個過程,稱爲一次會話。會話技術就是記錄此次會話中客戶端的狀態與數據的。瀏覽器

會話技術分爲Cookie和Session:tomcat

  • Cookie:數據存儲在客戶端本地,減小服務器端的存儲的壓力,安全性很差,客戶端能夠清除cookie
  • Session:將數據存儲到服務器端,安全性相對好,增長服務器的壓力

 

2、Cookie技術

Cookie技術是將用戶的數據存儲到客戶端的技術:安全

  1. 服務器端怎樣將一個Cookie發送到客戶端
  2. 服務器端怎樣接受客戶端攜帶的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);
    }
}
SendCookieServlet.java
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);
    }
}
RemoveCookieServlet.java

 

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);
    }
}
GetCookieServlet.java

 

3、案例一:記錄用戶的上次訪問時間

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);
    }
}
LastAccessTimeServlet.java

 

4、Session技術

Session技術是將數據存儲在服務器端的技術,會爲每一個客戶端都建立一塊內存空間 存儲客戶的數據,但客戶端須要每次都攜帶一個標識ID去服務器中尋找屬於本身的內 存空間。因此說Session的實現是基於Cookie,Session須要藉助於Cookie存儲客戶端的惟一性標識JSESSIONID。這個JSESSIONID是Tomcat容器幫咱們設置到cookie中的。

在Session中須要解決以下三個問題:

  • 怎樣得到屬於本客戶端的session對象(內存區域)?
  • 怎樣向session中存取數據(session也是一個域對象)?
  • session對象的生命週期?

1. 得到Session對象

HttpSession session = request.getSession(); //request對象內部維護着session區域的引用。session區域比request區域大,經過小的能夠得到大的

此方法會得到專屬於當前會話的Session對象,若是服務器端沒有該會話的Session對象會建立一個新的Session返回,若是已經有了屬於該會話的Session直接將已有 的Session返回(實質就是根據JSESSIONID判斷該客戶端是否在服務器上已經存在 session了)。

 

2. 怎樣向session中存取數據(session也是一個域對象)

Session也是存儲數據的區域對象,因此session對象也具備以下三個方法:

  • session.setAttribute(String name,Object obj);
  • session.getAttribute(String name);
  • session.removeAttribute(String name);

 

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);
    }
}
SessionServlet1.java
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);
    }
}
SessionServlet2.java

 

面試題:瀏覽器關閉,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);
    }
}
SessionServlet1.java

 

5、案例二:實現驗證碼的校驗

頁面加載生成驗證碼時,將驗證碼中的字符存於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);
    }
}
LoginServlet.java
相關文章
相關標籤/搜索