1. 程式人生 > >為什麼伺服器能夠為不同的瀏覽器使用者提供不同session

為什麼伺服器能夠為不同的瀏覽器使用者提供不同session

公眾號檢視文章

Session的實現原理

用現象說明問題,我在ServletSessonTest01中的程式碼設定了Session的屬性

 1public class ServletSessonTest01 extends HttpServlet {
 2    @Override
 3    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 4        //從request獲得Session物件
 5        HttpSession httpSession = req.getSession();
 6        //設定Session的屬性
 7        httpSession.setAttribute("name","九月");
 8        //設定Session最長超時時間為60秒,這裡的單位是秒
 9        httpSession.setMaxInactiveInterval(660);
10    }
11}

接著在ServletSessonTest02把Session的屬性取出來,能取到在ServletSessonTest01中Session設定的屬性.

 1public class ServletSessonTest02 extends HttpServlet {
 2    @Override
 3    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 4        //從request獲取HttpSession物件
 5        HttpSession httpSession = req.getSession();
 6        //獲取從ServletSessonTest01設定的Session物件值
 7        String value = (String) httpSession.getAttribute("name");
 8        System.out.println("value: "+value);
 9        //獲取Sessio超時時間
10        int maxInactiveInterval = httpSession.getMaxInactiveInterval();
11        System.out.println("getMaxInactiveInterval: "+maxInactiveInterval);
12
13    }
14}

我在瀏覽器中新建一個會話,再次訪問ServletSessonTest02,發現報了空指標異常的錯誤.

伺服器是如何實現一個session為一個使用者瀏覽器服務的?換個說法是為什麼伺服器能夠為不同的使用者瀏覽器提供不同session?
HTTP協議是無狀態的,Session不能依據HTTP連線來判斷是否為同一個使用者。於是,伺服器向用戶瀏覽器傳送了一個名為JESSIONID的Cookie,它的值是Session的id值。其實Session依據Cookie來識別是否是同一個使用者。

簡單來說:Session 之所以可以識別不同的使用者,依靠的就是Cookie該Cookie是伺服器自動頒發給瀏覽器的,不用我們手工建立的。該Cookie的maxAge值預設是-1,也就是說僅當前瀏覽器使用,不將該Cookie存在硬碟中

思路流程:當我們訪問Servlet的時候,伺服器就會建立一個Session物件,執行我們的程式程式碼,並自動頒發個Cookie給使用者瀏覽器

當我們用同一個瀏覽器訪問ServletSessonTest02的時候,瀏覽器會把Cookie的值通過http協議帶過去給伺服器,伺服器就知道用哪一個Session。

而當我們使用新會話的瀏覽器(通過另外開啟其他瀏覽器測試)訪問ServletSessonTest02的時候,該新瀏覽器並沒有Cookie,伺服器無法辨認使用哪一個Session,所以就獲取不到值

瀏覽器禁用了Cookie,Session還能用嗎?

上面說了Session是依靠Cookie來識別使用者瀏覽器的。如果我的使用者瀏覽器禁用了Cookie了呢?絕大多數的手機瀏覽器都不支援Cookie,那我的Session怎麼辦?

我們來看看情況是怎麼樣的。使用者瀏覽器訪問ServletSessonTest01的時候,伺服器向用戶瀏覽器頒發了一個Cookie。

當用戶瀏覽器訪問ServletSessonTest02的時候,由於我們禁用了Cookie,所以使用者瀏覽器並沒有把Cookie帶過去給伺服器,我們實現不了記住密碼或者給使用者展示之前瀏覽過的商品等一些業務功能。

瀏覽器禁用了Cookie,Session好像不能用了。但是Java Web提供瞭解決方法,URL地址重寫
HttpServletResponse類提供了兩個URL地址重寫的方法:

1encodeURL(String url)
2encodeRedirectURL(String url)

需要值得注意的是:這兩個方法會自動判斷該瀏覽器是否支援Cookie,如果支援Cookie,重寫後的URL地址就不會帶有jsessionid了【當然了,即使瀏覽器支援Cookie,第一次輸出URL地址的時候還是會出現jsessionid(因為沒有任何Cookie可帶)】

對URL進行重寫,看看能不能恢復沒有禁掉Cookie之前的效果。
原則:把Session的屬性帶過去【傳遞給】另外一個Servlet,都要URL地址重寫

 1    @Override
 2    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 3        //從request獲得Session物件
 4        HttpSession httpSession = req.getSession();
 5        //設定Session的屬性
 6        httpSession.setAttribute("name","九月");
 7        //設定Session最長超時時間為60秒,這裡的單位是秒
 8        httpSession.setMaxInactiveInterval(660);
 9        String url = "/ServletSessonTest02";
10        resp.sendRedirect(resp.encodeURL(url));
11    }

URL地址重寫的原理:將Session的id資訊重寫到URL地址中。伺服器解析重寫後URL,獲取Session的id。這樣一來,即使瀏覽器禁用掉了Cookie,但Session的id通過伺服器端傳遞,還是可以使用Session來記錄使用者的狀態。

 

“掃碼關注“