天天看點

會話管理---Cookie與Session

原文連結:

http://www.cnblogs.com/lxboy2009/p/5943759.html

會話可簡單了解為:使用者開一個浏覽器,點選多個超連結,通路伺服器多個web資源,然後關閉浏覽器,整個過程稱之為一個會話。

儲存會話資料的兩種技術:Cookie,Session

Cookie是用戶端技術,程式把每個使用者的資料以cookie的形式寫給使用者各自的浏覽器。當使用者使用浏覽器再去通路伺服器中的web資源時,就會帶着各自的資料去。這樣,web資源處理的就是使用者各自的資料了。

Session是伺服器端技術,利用這個技術,伺服器在運作時可以為每一個使用者的浏覽器建立一個其獨享的session對象,由于session為使用者浏覽器獨享,是以使用者在通路伺服器的web資源時,可以把各自的資料放在各自的session中,當使用者再去通路伺服器中的其它web資源時,其它web資源再從使用者各自的session中取出資料為使用者服務。

Cookie應用

會話管理---Cookie與Session
//顯示使用者上次通路的時間
public class CookieDemo1 extends HttpServlet {

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

        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        
        PrintWriter  out = response.getWriter();
        out.write("您上次通路時間是:");
        //1.擷取使用者上次通路的時間,顯示
        Cookie cookies[] = request.getCookies();
        for(int i=0;cookies!=null && i<cookies.length;i++){
            Cookie cookie = cookies[i];
            if(cookie.getName().equals("lastAccessTime")){
                long time = Long.parseLong(cookie.getValue());
                Date date = new Date(time);
                out.write(date.toLocaleString());
            }
        }
        
        //2.把本次的時間以cookie的形式回寫給客戶機   (lastAccessTime)
        Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+"");
        cookie.setMaxAge(100);//設定有效期,cookie将寫到硬碟上,不設定有效期,cookie的有效期是會話範圍,cookie僅存儲在浏覽器緩存中,浏覽器一關閉,cookie就沒了。
        response.addCookie(cookie);
        
    }

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

}      
會話管理---Cookie與Session

Cookie細節:

  1. 一個Cookie隻能辨別一種資訊,它至少含有一個辨別該資訊的名稱(NAME)和設定值(VALUE)。 

  2. 一個WEB站點可以給一個WEB浏覽器發送多個Cookie,一個WEB浏覽器也可以存儲多個WEB站點提供的Cookie。

  3. 浏覽器一般隻允許存放300個Cookie,每個站點最多存放20個Cookie,每個Cookie的大小限制為4KB。

  4. 如果建立了一個cookie,并将他發送到浏覽器,預設情況下它是一個會話級别的cookie(即存儲在浏覽器的記憶體中),使用者退出浏覽器之後即被删除。若希望浏覽器将該cookie存儲在磁盤上,則需要使用maxAge,并給出一個以秒為機關的時間。将最大時效設為0則是指令浏覽器删除該cookie。

   5. 注意,删除cookie時,path必須一緻,否則不會删除

設定Session,與NET平台不同

String data = "abcd";
HttpSession session = request.getSession();
session.setAttribute("data", data);
              

取出Session

HttpSession  session = request.getSession();
//session.invalidate();  摧毀session
        
String data = (String) session.getAttribute("data");
response.getWriter().write(data);      

session實作會話過程資料共享的原理:

Session是基于Cookie的、伺服器建立每個session的時候,會為每個session配置設定一個ID号,即 JSESSIONID,伺服器會以cookie的方式把session 的id号寫給浏覽器、是以session是基于cookie的。當浏覽器再次通路的時候,會帶着session id号的cookie過來 ,這就是session實作共享的原理。伺服器寫這個cookie的時候,是沒有寫有效期的,是以當浏覽器關閉的時候,cookie也就沒了,session也就結束了,即會話過程。

多浏覽器共享Session

由上面的分析可以,關閉浏覽器後,session将消失,那麼如何做到多浏覽器共享一個session呢(即關閉浏覽器後,再打開一個浏覽器後session還存在)?

隻要手動的寫入cookie,并設定有效期即可。用這個cookie來覆寫伺服器寫給浏覽器的。可以通過httpwatch來觀察伺服器寫給浏覽器的内容。

解決方案如下:名字必須是JSESSIONID,因為伺服器寫給浏覽器的cookie的名字就是這個 。

HttpSession session = request.getSession();
        Cookie cookie = new Cookie("JSESSIONID",session.getId());
        cookie.setMaxAge(30*60);
        cookie.setPath("/day07");//因為伺服器寫給浏覽器的也有設定path,是以要想自己寫的cookie覆寫伺服器寫的,必須跟伺服器寫的一緻。
        response.addCookie(cookie);      

Session是基于Cookie的,那如果浏覽器禁用了cookie後怎麼辦?  會出現空指針異常。

因為禁用了cookie,伺服器寫cookie的時候,浏覽器會拒絕,下次再來通路的時候是沒有帶cookie的,而在背景有使用這個cookie,是以會出現空指針異常。

解決方法:不以cookie的方式把JSESSIONID帶給伺服器,而是把JSESSIONID以url的方式帶到伺服器,

即URL重寫:URL重寫解決了禁用cookie後,Session的共享問題。

String url  = response.encodeRedirectURL("/day07/servlet/ListCartServlet");    //實作 url重寫
response.sendRedirect(url);      
encodeRedirectURL方法會自動的在URL後面加上JSEEIONID的參數。      

一般涉及到會話的超連結都要使用url重寫,來解決浏覽器禁用cookie的問題。

String url = "/day07/servlet/BuyServlet?id="+book.getId();
url = response.encodeURL(url);  //得到重寫後的url      
encodeURL      
encodeRedirectURL

上面兩個都是url重寫,重定向的url重寫使用下面一個,其他的url重寫使用上面一個。

      

   response. encodeRedirectURL(java.lang.String url) 

   用于對sendRedirect方法後的url位址進行重寫。

   response. encodeURL(java.lang.String url)

   用于對表單action和超連結的url位址進行重寫 

URL重寫會自己判斷浏覽器是否禁用了cookie,如果沒有禁用cookie,不會在超連結後面加上JSESSIONID的參數帶給伺服器,隻有禁用了Cookie才會帶。



Session的失效時間可以在web.xml檔案中修改      

<session-config>

  <session-timeout>10</session-timeout>    //10分鐘

</session-config>

session在10分鐘内沒有在被使用,伺服器就會摧毀session。

使用者登入儲存登入标記,存入session

會話管理---Cookie與Session
public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //request.getAttribute("username");  //從域中取username
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        
        //檢測使用者名和密碼在資料庫中是否存在
        List<User> list = DB.getAll();
        for(User user : list){
            if(user.getUsername().equals(username)  && user.getPassword().equals(password)){
                //從資料庫中找到比對使用者,讓使用者登陸成功
                request.getSession().setAttribute("user", user);
                response.sendRedirect("/day07/index.jsp");
                return;
            }
        }
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("使用者名或密碼錯誤!!");
    }      
會話管理---Cookie與Session
會話管理---Cookie與Session
//登出登陸使用者
public class LogoutServlet extends HttpServlet {

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

        HttpSession session = request.getSession(false);
        if(session!=null){
            session.removeAttribute("user");
        }
        
        response.sendRedirect("/day07/index.jsp");
    }

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

}      
會話管理---Cookie與Session

兩者差別:

request.getSession();如果伺服器記憶體中沒有session,伺服器會建立一個session,如果有session,會傳回該session      
request.getSession(false);隻檢索伺服器記憶體中有沒有session,如果沒有也不建立session了,如果有,則傳回該sessio      

繼續閱讀