java的會話管理:Cookie和Session

java的會話管理:Cookie和Session

1.什麼是會話

此處的是指客戶端(瀏覽器)和服務端之間的數據傳輸。例如用戶登陸,購物車等
會話管理就是管理瀏覽器客戶端和服務端之間會話過程產生的會話數據
經常使用的會話技術
以前學會了域對象的做用,因此在會話管理的時候也可使用域對象的概念來找到解決方法。
經常使用的解決方法主要有兩種:
數據保存在客戶端的Cookie技術
數據保存在服務端的Session技術css

2.Cookie技術

2.1.什麼是Cookie

Cookie是客戶端技術,程序把每一個用戶的數據以cookie的形式寫給用戶各自的瀏覽器,當用戶使用瀏覽器再去訪問服務器中的web資源時,就會帶着各自的數據去。這樣,web資源處理的就是各自用戶本身的數據了
特色是會話數據保存在瀏覽器客戶端html

2.2.Cookie技術核心API

Cookie類:用於存儲會話數據。經常使用方法以下:
1.構造Cookie對象java

Cookie(java.lang.String name, java.lang.String value)web

2.設置cookieapi

void setPath(java.lang.String uri) :設置cookie的有效訪問路徑
void setMaxAge(int expiry) : 設置cookie的有效時間
void setValue(java.lang.String newValue) :設置cookie的值瀏覽器

3.發送cookie到瀏覽器端保存緩存

void response.addCookie(Cookie cookie) : 發送cookie安全

4.服務器端接收cookie服務器

Cookie[] request.getCookies() : 接收cookiecookie

代碼示例:

/**
 * 測試Cookie的方法
 */
@WebServlet(name = "CookieDemo")
public class CookieDemo extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //1.建立Cookie對象
        Cookie cookie = new Cookie("name","eric");

        //2.設置Cookie參數
        //2.1.設置Cookie的有效路徑
        cookie.setPath("/hello");//默認就是web項目的地址
        //2.2.設置Cookie的有效時間
        cookie.setMaxAge(20);//該cookie只存活20秒,從最後不調該cookie開始計算
        cookie.setMaxAge(-1);//該cookie保存在瀏覽器內存中,關閉瀏覽器則銷燬該cookie
        cookie.setMaxAge(0);//刪除根該cookie同名的cookie

        //3.把數據發送到瀏覽器
        response.addCookie(cookie);

        //4.服務端接收來自瀏覽器的cookie
        //方法1:
//        String name = request.getHeader("cookie");
//        System.out.println(name);
        //方法2:
        Cookie[] cookies = request.getCookies();
        //注意:判斷null,不然空指針
        if(cookies!=null){
            //遍歷
            for(Cookie c:cookies){
                String name = c.getName();
                String value = c.getValue();
                System.out.println(name+"="+value);
            }
        }else{
            System.out.println("沒有接收cookie數據");
        }

    }
}

2.3.Cookie原理

1.服務器建立Cookie對象,把會話數據存儲到Cookie對象中

new Cookie("name","value");

2.服務器發送cookie信息到瀏覽器

response.addCookie(cookie);
實際上是隱藏發送了一個set-cookie名稱的響應頭

3.瀏覽器獲得服務器發送的cookie,而後保存在瀏覽器端
4.瀏覽器在下次訪問服務器時,會帶着cookie信息

包含在http的請求頭裏

5.服務器接收到瀏覽器帶來的cookie信息

request.getCookies();

2.4.Cookie的細節

1.void setPath(java.lang.String uri):設置Cookie的有效訪問路徑,有效訪問路徑指的事Cookie的有效路徑保存在哪裏,那麼瀏覽器在有效路徑下訪問服務器的時就會帶着Cookie信息,不然不帶Cookie信息,默認是在當時錢web項目的路徑下
2.void setMaxAge(int expiry):設置Cookie的有效時間
expiry能夠是正整數,負整數,和零
正整數:表示Cookie數據保存瀏覽器的緩存到硬盤中,數值表示保存的時間
負整數:表示Cookie數據保存到瀏覽器的內存中,瀏覽器關閉Cookie就丟失了
零:表示刪除同名的Cookie數據
3.Cookie數據類型只能保存非中文字符串類型的。能夠保存多個Cookie,可是瀏覽器通常只容許存放300個Cookie,每一個站點最多存放20個Cookie,每一個Cookie的大小限制爲4KB。

2.5.Cookie案例:顯示用戶上次訪問的時間

功能實現邏輯:
將時間保存在Cookie中,每次訪問從Cookie裏面調用
第一次訪問:
1.獲取當前時間,顯示到瀏覽器中
2.建立Cookie對象,時間做爲cookie值,名爲:lastTime
3.把cookie發送到瀏覽器保存
第N次訪問:
1.獲取cookie的數據,取出名爲lastTime的cookie
2.獲得cookie的值(上次訪問時間)
3.顯示上次訪問時間到瀏覽器中
4.更新名爲lastTime的cookie。值設置爲當前時間
5.把更新後的cookie發送給瀏覽器保存

代碼實現:

/**
 * 案例-用戶上次訪問的時間
 */
@WebServlet("/last")
public class HistServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");

        //獲取當前時間
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String curTime = format.format(new Date());


        //取得cookie
        Cookie[] cookies = request.getCookies();
        String lastTime = null;
        
        //第n次訪問
        if(cookies!=null){
            for (Cookie cookie : cookies) {
                if(cookie.getName().equals("lastTime")){
                    //有lastTime的cookie,已是第n次訪問
                    lastTime = cookie.getValue();//上次訪問的時間
                    //第n次訪問
                    //1.把上次顯示時間顯示到瀏覽器
                    response.getWriter().write("歡迎回來,你上次訪問的時間爲:"+lastTime+",當前時間爲:"+curTime);
                    //2.更新cookie
                    cookie.setValue(curTime);
                    cookie.setMaxAge(1*30*24*60*60);
                    //3.把更新後的cookie發送到瀏覽器
                    response.addCookie(cookie);
                    break;
                }
            }
        }

        /**
         * 第一次訪問(沒有cookie 或 有cookie,但沒有名爲lastTime的cookie)
         */
        if(cookies==null || lastTime==null){
            //1.顯示當前時間到瀏覽器
            response.getWriter().write("你是首次訪問本網站,當前時間爲:"+curTime);
            //2.建立Cookie對象
            Cookie cookie = new Cookie("lastTime",curTime);
            cookie.setMaxAge(1*30*24*60*60);//保存一個月
            //3.把cookie發送到瀏覽器保存
            response.addCookie(cookie);
        }
    }
}

2.6.Cookie案例:查看用戶瀏覽過的商品

邏輯圖

這個項目的代碼較多,按照功能的不一樣放在不一樣的包裏面
公司域名的倒寫+項目名字+功能名字
cenyu.hist.entity 存放實體對象
cenyu.hist.dao Data Access Object 數據訪問對象,主要存放實體對象的一些方法(CRUD-create,read,update,delete)
cenyu.hist.servlet 存放servlet程序
cenyu.hist.ytil 存放工具類
cenyu.hist.test 存放測試類
等等
寫的順序:實體對象-->DAO類-->Servlet程序

代碼:暫無

3.Session技術

3.1.什麼是Session

Session是服務器端技術,利用這個技術,服務器在運行時能夠爲每個用戶的數據建立一個其獨享的Session對象,因爲Session爲用戶瀏覽器獨享,因此當用戶在訪問服務器的web資源時,能夠把各自的數據放在各自的Session中,當用戶再去訪問服務器中的其餘的web資源的時候,其餘的web資源再從用戶各自的Session中取出數據爲用戶服務

3.2.Session的核心技術

Session的類是HttpSession類:用於保存會話數據
1.建立或獲得session對象
HttpSession getSession() 直接建立一個Session對象
HttpSession getSession(boolean create) 接收布爾值,設置爲true時,在沒有找到匹配Session編號的對象時新建一個Sessionu對象。若是設置false,則當找不到匹配的Session時,返回null,建議不要用
2.設置session對象
void setMaxInactiveInterval(int interval) : 設置session的有效時間
java.lang.String getId() : 獲得session編號
void invalidate() : 銷燬session對象
Session對象的方法:
1.setMaxInactiveInterval方法默認30分鐘自動回收Session對象
2.使用setMaxInactiveInterval方法修改銷燬時間
3.在web.xml文件中全局修改Session默認回收時間

<!-- 修改session全局有效時間:分鐘 -->
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>

4.經過invalidate方法,手動銷燬Session對象

3.保存會話數據到session對象
void setAttribute(java.lang.String name, java.lang.Object value) : 保存數據
java.lang.Object getAttribute(java.lang.String name) : 獲取數據
void removeAttribute(java.lang.String name) : 清除數據

4.如何避免瀏覽器的JSESSIONID的cookie隨着瀏覽器關閉而丟失的問題:
解決方法是手動發送一個硬盤保護的cookie給瀏覽器
代碼見案例:

/**
 * 測試Session的方法
 */
@WebServlet(name = "SessionServletDemo")
public class SessionServletDemo extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //1.建立Session對象
        HttpSession session = request.getSession();

        //2.保存會話數據
        session.setAttribute("name","eric");

        //3.取出會話數據
        String name = (String)session.getAttribute("name");
        System.out.println(name);

        //4.
        //拿到Session的id
        System.out.println(session.getId());
        //修改Session有效時間
        session.setMaxInactiveInterval(20);
        //銷燬session
        if (session!=null){
            session.invalidate();
        }
        //手動發送一個硬盤保存的cookie給瀏覽器
        Cookie c = new Cookie("JSESSION", session.getId());
        c.setMaxAge(60*60);
        response.addCookie(c);
    }
}

3.3.Session原理

代碼解讀:HttpSession session = request.getSession();
僞碼分析執行過程
1.第一次訪問建立Session對象,給Session對象分配一個惟一的ID,叫JSESSIONID。

new HttpSession();

2.把JSESSIONID做爲Cookie的值發送給瀏覽器保存

Cookie cookie = new Cookie("JSESSIONID", sessionID);
response.addCookie(cookie);

3.第二次訪問的時候,瀏覽器帶着JSESSIONID的cookie訪問服務器
4.服務器獲得JSESSIONID,在服務器的內存中搜索是否存放對應編號的session對象
5.若是找到對應編號的session對象,直接返回該對象
6.若是找不到對應編號session對象,建立新的session對象,繼續走1的流程

結論經過JSESSION的cookie值在服務器找session對象

3.4.Session案例:用戶登陸效果

需求:實現用戶登陸效果,若是登陸成功顯示:歡迎回來,×××。若是失敗,顯示登陸失敗
使用Session區分不一樣的用戶來實現,整個代碼實現分爲三塊,登陸表單提交以後的處理邏輯,登陸邏輯,登出邏輯:
默認登陸界面。index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>登陸頁面</title>
    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    <form action="/day12/LoginServlet" method="post">
        用戶名:<input type="text" name="userName"/>
        <br/>
        密碼:<input type="text" name="userPwd"/>
        <br/>
        <input type="submit" value="登陸"/>
    </form>
  </body>
</html>

登陸失敗頁面:fail.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>信息提示頁面</title>
    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    <font color='red' size='3'>親, 你的用戶名或密碼輸入有誤!請從新輸入!</font><br/>
    <a href="/day12/login.html">返回登陸頁面</a>
  </body>
</html>

表單提交以後的主處理邏輯:IndexServlet.java

/**
 * 用戶主頁的邏輯
 *
 */
public class IndexServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        
        
        String html = "";
        
        /**
         * 接收request域對象的數據
         */
        /*
        String loginName = (String)request.getAttribute("loginName");
        */
        
        /**
         * 2、在用戶主頁,判斷session不爲空且存在指定的屬性才視爲登陸成功!才能訪問資源。
         * 從session域中獲取會話數據
         */
        //1.獲得session對象
        HttpSession session = request.getSession(false);
        if(session==null){
            //沒有登陸成功,跳轉到登陸頁面
            response.sendRedirect(request.getContextPath()+"/login.html");
            return;
        }
        //2.取出會話數據
        String loginName = (String)session.getAttribute("loginName");
        if(loginName==null){
            //沒有登陸成功,跳轉到登陸頁面
            response.sendRedirect(request.getContextPath()+"/login.html");
            return;
        }
        
        html = "<html><body>歡迎回來,"+loginName+",<a href='"+request.getContextPath()+"/LogoutServlet'>安全退出</a></body></html>";
        
        
        writer.write(html);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

登陸處理邏輯:LoginServlet.java

/**
 * 處理登陸的邏輯
 *
 */
public class LoginServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        //1.接收參數
        String userName = request.getParameter("userName");
        String userPwd = request.getParameter("userPwd");
        
        //2.判斷邏輯
        if("eric".equals(userName)
                 && "123456".equals(userPwd)){
            //登陸成功
            /**
             * 分析:
             *    context域對象:不合適,可能會覆蓋數據。
             *    request域對象: 不合適,整個網站必須得使用轉發技術來跳轉頁面
             *    session域對象:合適。
             */
            /*
            request.setAttribute("loginName", userName);
            //request.getRequestDispatcher("/IndexServlet").forward(request, response);
            response.sendRedirect(request.getContextPath()+"/IndexServlet");
            */
            
            /**
             * 1、登陸成功後,把用戶數據保存session對象中
             */
            //1.建立session對象
            HttpSession session = request.getSession();
            //2.把數據保存到session域中
            session.setAttribute("loginName", userName);
            //3.跳轉到用戶主頁
            response.sendRedirect(request.getContextPath()+"/IndexServlet");
            
        }else{
            //登陸失敗
            //請求重定向
            response.sendRedirect(request.getContextPath()+"/fail.html");
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

退出處理邏輯:LogoutServlet.java

/**
 * 退出邏輯
 *
 */
public class LogoutServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 3、安全退出:
         *      刪除掉session對象中指定的loginName屬性便可!  
         */
        //1.獲得session對象
        HttpSession session = request.getSession(false);
        if(session!=null){
            //2.刪除屬性
            session.removeAttribute("loginName");
        }
        
        //2.回來登陸頁面
        response.sendRedirect(request.getContextPath()+"/login.html");
        
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

3.5.案例:Session實現通信錄

暫無

相關文章
相關標籤/搜索