1. 程式人生 > >JavaWeb(九)HttpSession和登陸案例

JavaWeb(九)HttpSession和登陸案例

HttpSession入門

1. HttpSession概述

  1. HttpSession是由JavaWeb提供的,用來會話跟蹤的類,儲存在伺服器端!
  2. HttpSession是Servlet三大域物件之一(request、session、application(ServletContext)),所以它也有setAttribute()getAttribute()removeAttribute()方法
  3. HttpSession底層依賴Cookie,或是URL重寫!
    一個會話內只有一個session,比如說第一次訪問伺服器時,把session拿過來存點東西。當第二次訪問時,獲取的還是這個session(期間瀏覽器沒有關閉)。一個請求內一個request,一個會話內一個session

2. HttpSession的作用

  1. 會話範圍:會話範圍是某個使用者從首次訪問伺服器開始,到該使用者關閉瀏覽器結束!
    >會話:一個使用者對伺服器多次連貫性請求!所謂連貫性請求,就是該使用者多次請求中間沒有關閉瀏覽器
  2. 伺服器會為每個客戶端建立一個session物件,session就好比客戶在伺服器端的賬戶,它被伺服器儲存到一個Map中,這個Map被稱為session快取!
    >Servlet中得到session物件:HttpSession session = request.getSession();
    >jsp中得到session物件:session是jsp內建物件,不用建立就可以直接使用!
  3. session域相關方法(只要是域就都有這三個方法):
    > void setAttribute(String name,Object value);
    > Object getAttribute(String name);
    > void removeAttribute(String name,);

案例1

演示session會話的多次請求中共享資料
1. AServlet:向session域中儲存資料
2. BServlet:從session域中獲取資料
3. 演示:
> 第一個請求:訪問AServlet

public class AServlet
extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response){ doGet(request,response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) { //獲取session HttpSession session = request.getSession(); //向session域中儲存資訊 session.setAttribute("wangyue","age5"); } }

首先訪問這個Servlet

> 第二個請求:訪問BServlet

public class BServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response){
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response){
        response.setContentType("text/html;charset=utf-8");
        HttpSession session = request.getSession();
        //get返回的是Object物件,所以向下轉型
        String value = (String)session.getAttribute("wangyue");
        response.getWriter().print("<h1 style='color:red' align='center'>" + value + "</h1>");
        }
    }

可以看到當訪問BServlet的時候:(只要瀏覽器不關閉,訪問時就一直有值)
這裡寫圖片描述

案例2

儲存使用者登入資訊

  1. 案例相關頁面和Servlet:
    > login.jsp:登入頁面
    > succ1.jsp:只有登入成功費能訪問的頁面
    > succ2.jsp:只有登入成功費能訪問的頁面
    > LoginServlet:校驗使用者是否登入成功!
  2. 各頁面和Servlet內容:
    > login.jsp:提供登入表單,提交表單請求LoginServlet
    > LoginServlet:獲取請求引數,校驗使用者是否登陸成功
    <>失敗:儲存錯誤資訊到request域,轉發到login.jsp(這個頁面顯示request域中的錯誤資訊)
    <>成功:儲存使用者資訊到session域中,重定向到succ1.jsp頁面,顯示session域中的使用者資訊
    > succ1.jsp:從session域中獲取使用者資訊,如果不存在,顯示“您還沒有登入”。存在則顯示使用者資訊
    > succ2.jsp:從session域中獲取使用者資訊,如果不存在,顯示“您還沒有登入”。存在則顯示使用者資訊

使用者只要沒有關閉瀏覽器,這個session就一直存在,那麼儲存在session中的使用者資訊也就一起存在!那麼使用者訪問succ1和succ2就會通過!

首先寫login.jsp:

%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登陸頁面</title>
</head>
<body>
<h1 style="color: orange" align="center">請提交登陸資訊</h1>
<%
    /*
    讀取Cookie,如果存在則顯示到使用者名稱中!
     */
    String username = "";
    Cookie[] cooks = request.getCookies();
    for (Cookie cook: cooks
         ) {
        if ("username".equals(cook.getName()))
            username = cook.getValue();
    }
%>
<%
    String error = (String)request.getAttribute("error");
    if (! (error==null)){
        out.print("<b><font color='red'>" + error + "</font></b>");
    }
%>
<form action="/my2/LoginServlet" method="post">
        使用者名稱:<input type="text" name="username" value="<%=username%>"/><br/>
        密碼:<input type="password" name="password"/><br/>
        <input type="submit" value="提交">
</form>
</body>
</html>

然後是LoginServlet:

public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response){
        //處理中文問題
        request.setCharacterEncoding("utf-8");
        //獲取資訊
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //校驗使用者名稱和密碼是否正確
        if ("jjd".equalsIgnoreCase(username)) {     //登陸失敗
            request.setAttribute("error","使用者名稱或密碼錯誤");
            RequestDispatcher rd1 = request.getRequestDispatcher("/login.jsp"); //得到轉發器,注意路徑上不加專案名!
            rd1.forward(request,response);  //轉發
        }
        else{   //登陸成功
            Cookie cook = new Cookie("username",username);  //建立一個Cookie儲存到本地,下次訪問時,直接將使用者名稱顯示
            cook.setMaxAge(60*60*24);   //設定儲存時間
            response.addCookie(cook);   //儲存Cookie

            HttpSession session = request.getSession(); //獲取session物件
            session.setAttribute("username",username);  //向session域中儲存資訊
            session.setAttribute("password",password);
            response.sendRedirect("/my2/succ1.jsp");    //重定向到succ1.jsp
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response){
        doPost(request,response);
    }
}

然後是succ1.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>顯示資訊</title>
</head>
<body>
    <h1 align="center">succ1</h1>
    <%
        String username = (String)session.getAttribute("username");
        String password = (String)session.getAttribute("password");
    %>
    <%
        if (username==null || password==null){
            request.setAttribute("error","請登陸後檢視");
            RequestDispatcher rd = request.getRequestDispatcher("/login.jsp");
            rd.forward(request,response);
            return;
        }
    %>
    <p align="center">您的使用者名稱是:<%=username%></p>
    <p align="center">您的密碼是:<%=password%></p><hr/>
    <a href="/my2/succ2.jsp" target="_blank">點選這裡可以訪問succ2!</a>
</body>
</html>

然後是succ2.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登陸成功</title>
</head>
<body>
    <%
        String username = (String) session.getAttribute("username");
        String password = (String) session.getAttribute("password");
    %>
    <%
        if (username==null || password==null){
            request.setAttribute("error","請登陸後檢視");
            RequestDispatcher dr = request.getRequestDispatcher("/login.jsp");
            dr.forward(request,response);
            return;
        }
    %>
    <h1 align="center">恭喜你!通關啦!</h1>

</body>
</html>

HttpSession原理

request.getSession()方法:伺服器不會馬上建立session,只有在第一次獲取session時才會建立!即request.getSession()

  1. 獲取Cookie中sessionId:
    <>如果jsessionId不存在,建立session,把session儲存起來,把新建立的sessionId儲存到Cookie中;
    <>如果sessionId存在,通過sessionId查詢session物件,如果沒有查詢到,建立建立session,把session儲存起來,把新建立的sessionId儲存到Cookie中;
    <>如果sessionId存在,通過sessionId查詢到了session物件,那麼就不會再建立session物件了;在伺服器端儲存的最大時間是30分鐘
    <>返回session
  2. 如果建立了新的session,瀏覽器會得到一個包含了sessionId的Cookie,這個Cookie的生命值是-1,只要不關閉瀏覽器,這個Cookie就會一直存在
  3. 下次請求時,再次執行request.getSession()方法時,因為可以通過Cookie中的sessionId找到session物件,所以與上次訪問時是同一個session物件。
  4. request.getSession(false)request.getSession(true)request.getSession(),後面兩個方法的效果相同
    第一個方法:如果session快取中(如果Cookie不存在),不存在session,那麼返回null,並且不建立session

HttpSession的其他方法

  1. String getId():獲取sessionId;
  2. int getMaxInactiveInterval():獲取session的最大不活動時間(秒),預設為30分鐘。當session在30分鐘內沒有使用,那麼Tomcat會在session池中移除這個session
  3. void invalidate():讓session失效!呼叫這個方法會讓session失效,當session失效後,客戶端再次請求,伺服器會為客戶端建立一個新的session並在響應中的Cookie新增這個session
  4. boolean isNew():檢視session是否為新。當客戶端第一次請求時,伺服器為客戶端建立session,但這時伺服器還沒有響應客戶端,也就是還沒有把sessionId傳送回來

JSESSIONID是由UUID產生的,Java的util包中提供了產生32位十六進位制數的方法:

public void fun{
    //呼叫這個靜態方法就會產生UUID的例項
    UUID uuid = UUID.randomUUID();
    //這樣就產生了JSESSIONID
    String str = uuid.toString();
    //將其中的"-"去掉
    String s = str.replace("-","").toUpperCase();
}

在web.xml中配置session的最大不活動時間

數字代表的是時間

<session-config>
    <session-timeout>30</session-timeout>
</session-config>

URL重寫(理解)

就是把所有的頁面中的路徑,都使用response.encodeURL(String url)處理一下。下面是這個方法的原理(把Cookie程式設計請求引數!)

  1. session依賴Cookie,目的是讓客戶端發出請求時歸還sessionId,這樣才能找到相應的session
  2. 如果客戶端禁用了Cookie,那麼就無法得到sessionId,那麼session就無用了!
  3. 也可以使用URL重寫來代替Cookie
    >讓網站的所有超連結、表單中都新增一個特殊的請求引數,即sessionId
    >這樣伺服器可以通過獲取請求引數得到sessionId,從而找到session物件。
  4. response.encodeURL(String url)這個方法會對url進行智慧的重寫:當請求中沒有歸還sessionId這個Cookie,那麼這個方法就會重寫url,當然這個url是指向本站的url

本人是菜鳥一枚,當做學習筆記寫部落格。謝謝各路大咖駐足審閱