1. 程式人生 > >[Servlet&JSP] HttpSession會話管理

[Servlet&JSP] HttpSession會話管理

index web.xml als 接受 type code title other red

我們能夠將會話期間必須共享的資料保存在HttpSession中,使之成為屬性。假設用戶關掉瀏覽器接受Cookie的功能。HttpSession也能夠改用URL重寫的方式繼續其會話管理功能。

HttpSession的使用

在Servlet/JSP中。假設要進行會話管理,能夠使用HttpServletRequest的getSession()方法取得HttpSession對象。語句例如以下:

HttpSession session = request.getSession();

getSession()方法有兩個版本號,還有一個版本號能夠傳入布爾值,默覺得true。表示若尚未存在HttpSession實例。則直接建立一個新的對象。若傳入為false,表示若尚未存在HttpSession實例。則直接返回null。

HttpSession上最經常使用的方法時setAttribute()與getAttribute(),能夠在對象中設置和取得屬性。默認在關閉瀏覽器前。所取得的HttpSession都是形同的實例。假設想要在此次會話期間直接讓眼下的HttpSession失效。則能夠運行HttpSession的invalidate()方法。一個使用的時機就是實現註銷機制。一個示比例如以下:

Login.java:

@WebServlet("/login.do")
public class Login extends HttpServlet{
    protected void processRequest
(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); if ("abc".equals(username) && "123".equals(password)) { request.getSession().setAttribute("login"
, username); request.getRequestDispatcher("user.jsp") .forward(request, response); } else { response.sendRedirect("login.html"); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }

在登錄時,假設username和password正確,就會取得HttpSession並設置一個login屬性,用以代表用戶完畢登錄的動作。

對於其它的Servlet/JSP。假設能夠從HttpSession取得login屬性,基本就能夠確定是個已登錄的用戶,這類用來識別用戶是否登錄的屬性。通常稱為登錄字符(Login Token)。在上例中,登錄成功後會轉發到用戶界面。

User.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<[email protected] prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
    <c:choose>
        <c:when test="${sessionScope.login == null}">
            <jsp:include page="login.html" />
        </c:when>
        <c:otherwise>
            <h1>Welcome! ${sessionScope.login}!</h1>
            <a href="logout.do">Sign out</a>
        </c:otherwise>
    </c:choose>
</body>
</html>

Login.html

<body>
    <form action="login.do" method="post">
        username:<input type="text" name="username" /><br />
        password:<input type="password" name="password" /><br />
        <input type="submit" value="Sign in" />
    </form>
</body>

Logout.java:

@WebServlet("/logout.do")
public class Logout extends HttpServlet{
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        request.getSession().invalidate();
        response.sendRedirect("login.html");
    }
}

指定HttpSession的invalidate()之後,容器就會銷毀並回收HttpSession對象。假設再次運行HttpServletRequest的getSession()。則說的取得的HttpSession就是另外一個新的對象了。

HttpSession會話管理原理

當運行HttpServletRequest的getSession()時,web容器會建立HttpSession對象。每一個HttpSession都會有一個特殊的ID。稱之為Session ID。能夠運行HttpSession的getID()能夠取得Session ID。

這個Session ID默認會使用Cookie將其存放至瀏覽器。

在Tomcat中,Cookie的名稱是JSESSIONID,數字則是getID()所取得的Session ID。

每一個HttpSession都有個特殊的Session ID,當瀏覽器請求應用程序時,會將Cookie中存放的Session ID一並發送給應用程序,web容器依據Session ID來取出相應的HttpSession對象,如此就能夠取得各個瀏覽器的會話數據。

所以使用HttpSession來進行會話管理時,設置為屬性的數據是保存在server端的,而Session ID默認使用Cookie存放於瀏覽器中。web容器儲存Session ID的Cookie被設置為關閉則瀏覽器就會失效,又一次打開瀏覽器請求應用程序時,通過getSession()所取得的是新的HttpSession對象。

因為HttpSession會占用內存空間,所以HttpSession得屬性中盡量不要保存耗資源的大型對象,必要時可將屬性移除,或者不需使用HttpSession時。運行invalidate()讓HttpSession失效。

關閉瀏覽器時會立即失效的是瀏覽器上的Cookie,而不是HttpSession。

能夠運行HttpSession的setMaxInactiveInterval()方法,設置瀏覽器在多久沒有請求應用程序的情況下,HttpSession就會自己主動失效,設置的單位是”秒”。也能夠在web.xml中設置HttpSession默認的失效時間,但要註意的時,這裏設置的時間單位是”分鐘”。比如:

<web-app ...>
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
</web-app>

保存Session ID的Cookie被設置為關閉瀏覽器就失效。

關閉瀏覽器後若希望保存信息,必須通過自行操作Cookie來達成。比如完畢自己主動登錄機制。

HttpSession與URL重寫

假設在用戶禁用Cookie的情況下,仍打算運用HttpSession來進行會話管理。那麽能夠搭配URL重寫的方式。向瀏覽器響應一段超鏈接。超鏈接URL後附加Session ID。當用戶點擊超鏈接時。則將Session ID以GET請求方式發送給web應用程序。

假設要使用URL重寫的方式來發送Session ID。則能夠使用HttpServletRequest的encodeURL()協助產生所需的URL重寫。

當容器嘗試取得HttpSession實例時,若能夠從HTTP請求中取得帶有Session ID的Cookie,encodeURL()會將設置給它的URL原封不動的輸出;若無法從HTTP請求中取得帶有Session ID的Cookie(一般是瀏覽器禁用Cookie的情況),encodeURL()會自己主動產生帶有Session ID的URL重寫。

假設有運行encdeURL(),在瀏覽器第一次請求站點時,容器並不知道瀏覽器是否禁用Cookie,所以容器的做法是Cookie(發送set-cookie標頭)與URL重寫都做,因此若Servlet有下面語句,不管瀏覽器是否禁用Cookie,第一次請求時。都會顯示編上Session ID的URL。

request.getSession();
out.println(response.encodeURL("index.jsp"));

當再次請求時,假設瀏覽器沒有禁用Cookie,則容器能夠從Cookie(從cookie標頭)中取得Session ID。此時encodeURL()就僅僅會輸出index.jsp。假設瀏覽器禁用Cookie,則encodeURL()就會繼續在URL上編上Session ID

HttpServletResponse的還有一個方法encodeRedirectURL()方法。能夠在要去瀏覽器重定向時,在URL上編上Session ID。

[Servlet&amp;JSP] HttpSession會話管理