1. 程式人生 > >Cookie和Session實現儲存登入狀態免登入。

Cookie和Session實現儲存登入狀態免登入。

  首先Cookie和Session都是為了狀態管理,HTTP協議是無狀態的,不能儲存每次提交的資訊,即當伺服器返回與請求相對應的應答之後,這次事務的所有資訊就丟掉了。   如果使用者發來一個新的請求,伺服器無法知道它是否與上次的請求有聯絡。   對於那些需要多次提交資料才能完成的Web操作,比如登入來說,就成問題了。所以需要狀態管理也就是通過Cookie和Session。

一.Cookie

1. 什麼是Cookie?    用我的理解來說,瀏覽器A在第一次請求伺服器B的時候,伺服器B會為該瀏覽器A建立一個Cookie,並在響應時候把這個Cookie一同返回給瀏覽器A,這樣A在請求資料不變的情況下再次

請求伺服器B的時候會帶著這個Cookie,這樣伺服器B當接收A請求時會辨識出這個Cookie,明白A是訪問過B的並可能儲存著屬於A的資料(在這個過程中存在著session的問題稍後講解)。

2. Cookie持續多久呢? 可以通過setMaxAge()方法設定Cookie存在時間。 取值說明:

0有效期,單位秒 =0失效 <0記憶體儲存

二.Session 1. 什麼是Session   我的理解,Session是為了給瀏覽器在伺服器端儲存自己獨有資料的一個集合,只是在伺服器端。通過setAttribute()方法存資料,getAttribute()方法取資料。

2.Session持續多久呢?

預設不設定的話保持30分鐘。 有兩種設定Session的方法: (1)setMaxInactiveInterval()方法,單位秒 (2)在web.xml中配置 ,單位分鐘

  <session-config>
    <session-timeout>20</session-timeout>
  </session-config>

三.使用者登陸過程中的cookie和session保持過程 過程   假設沒有設定其他cookie情況下,A在第一次訪問B時,B會為A建立一個屬於A的session,並在B響應A時通過cookie儲存sessionid響應給A。這樣A在第二次訪問B的時候,A帶著cookie(此時裡面有sessionid)請求B,B收到請求後會通過cookie的sessionid辨識出屬於A的session,這就是整個過程。

四.Cookie和Session實現使用者登入儲存使用者登入狀態一定時間免登陸。

1.設計思路:   首先,使用者登入成功後儲存使用者登陸的使用者名稱到Cookie,同時設定Cookie的有效時間,在下次使用者想免輸入登陸時,直接判斷Cookie是否含有該使用者的使用者名稱,如果有則直接登陸不需要輸入,否則需要重新輸入使用者名稱和密碼。    2.程式碼實現:   為了大家看著方便,我儘可能把所有servlet分開寫了。 (1)KeepLoginServlet(使用者登入)   

@WebServlet("/keeploginservlet")
public class KeepLoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public KeepLoginServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession();

        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        // 從session中獲取驗證碼
        String vcode = (String) session.getAttribute("vcode");

        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String code = request.getParameter("code");

        PrintWriter out = response.getWriter();

        // System.out.println("輸入的code:"+code);
        // System.out.println("生成的vcode:"+vcode);

        if (!vcode.equals(code)) {
            out.write("<html>"
                    + "<head><script type='text/javascript'> alert('驗證碼錯誤!');location='login.html';</script></head>"
                    + "<body></body></html>");
            return; // 不繼續執行,重新返回login.html頁面
        }

        if ("123".equals(username)) {
            if ("123".equals(password)) {

                // 建立cookie並將成功登陸的使用者儲存在裡面
                Cookie cookie = new Cookie("username", username);
                cookie.setMaxAge(60); // 設定一分鐘有效
                response.addCookie(cookie); // 伺服器返回給瀏覽器cookie以便下次判斷

                response.sendRedirect(request.getContextPath() + "/index.html"); // 重定向到index.html
            } else {
                out.write("<html>"
                        + "<head><script type='text/javascript'> alert('密碼錯誤!');location='login.html';</script></head>"
                        + "<body></body></html>");
                return;
            }
        } else {
            out.write("<html>"
                    + "<head><script type='text/javascript'> alert('不存在該使用者!');location='login.html';</script></head>"
                    + "<body></body></html>");
            return;
        }
    }

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

}

  在這判斷使用者輸入是否正確,因為是測試,所以使用者名稱和密碼寫死都是123,驗證碼是一個工具類下面會給出程式碼,如果使用者登入成功則將這個使用者儲存到Cookie裡,設定過期時間為1分鐘,以便下次免登陸。

(2)KeepLoginServlet(驗證碼)   這裡為了節省空間直接給出doGet方法,這裡有一個驗證碼的jar包ValidateCode .jar非常方便大家可以自行查詢。地址是(@WebServlet(“/vcodeservlet”))   

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();

        //建立驗證碼圖片流
        ValidateCode validateCode = new ValidateCode(120,50,4,20);
        validateCode.write(response.getOutputStream());

        //將驗證碼存入session中
        session.setAttribute("vcode", validateCode.getCode());
    }

(3)FindCookieServlet(判斷使用者是否可以免登陸)   這裡是實現的邏輯是:遍歷所有cookie看是否含有username,如果含有username說明使用者登陸過,可以免輸入直接登陸。地址是(@WebServlet(“/dindcookieservlet”))   

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

        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        boolean flag = false;
        PrintWriter out = response.getWriter();

        // 判斷cookie是否有username,如果有代表登陸過
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                System.out.println(URLDecoder.decode(cookie.getName(), "utf-8"));
                if (URLDecoder.decode(cookie.getName(), "utf-8").equals("username")) { // 表明已經登陸過了,就直接跳轉了
                    flag = true;
                }
            }
        }

        if(flag) {
            response.sendRedirect(request.getContextPath() + "/index.html");

        }else {
            out.write("<html>"
                    + "<head><script type='text/javascript'> alert('沒有登陸過,請登入!');location='login.html';</script></head>"
                    + "<body></body></html>");
        }


    }

(4)ReturnClearCookie(清除使用者儲存的cookie)   Cookie是沒有直接刪除指定cookie的方法的,所以我可以找到cookie裡的username並把他的有效時間設定成0秒,這樣間接實現了刪除Cookie裡的username。地址是(@WebServlet(“/returnclearcookie”))。   

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

        //這裡就是把username的cookie設定成0秒有效期,就是直接刪除掉了
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                System.out.println(URLDecoder.decode(cookie.getName(), "utf-8"));
                if (URLDecoder.decode(cookie.getName(), "utf-8").equals("username")) { // 表明已經登陸過了,就直接跳轉了
                    cookie.setMaxAge(0);
                    response.addCookie(cookie);
                }
            }
        }
response.sendRedirect(request.getContextPath()+"/login.html");
    }

(5)兩個頁面   login.html   

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登入頁面</title>
<style type="text/css">
.dv_error {
    color: red;
}
</style>
</head>
<body>
    <form action="/myday13_zhuangtaiguanli/keeploginservlet" method="post">
        <label>賬號:</label><input type="text" id="username" name="username"><br />
        <label>密碼:</label><input type="password" id="password" name="password"><br />
        <label>密碼:</label><input type="text" id="code" name="code"><img id="img1" src="/myday13_zhuangtaiguanli/vcodeservlet" onclick="changeImg()" /><a href="javascript:void(0)" onclick="changeImg()">看不清換一張</a><br />
        <input type="button" onclick="check()" value="登入">
        <label><a href="/myday13_zhuangtaiguanli/dindcookieservlet" >已經登陸,直接登陸</a></label>
    </form>
    <script type="text/javascript">
         function check(){
             var username = document.getElementById("username")
             var password = document.getElementById("password")
             var code = document.getElementById("code")
             if(username.value == ""){
                 alert("請輸入使用者名稱")
             }else if(password.value == ""){
                 alert("請輸入密碼")
             }else if(code.value == ""){
                 alert("請輸入驗證碼");
             }else{
                 document.forms[0].submit()
             }
         }
         function changeImg(){
             var img1 = document.getElementById("img1")
             img1.src="/myday13_zhuangtaiguanli/vcodeservlet?num"+Math.random();
         }
    </script>
</body>
</html>

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>歡迎登入...</h1>
<a href="/myday13_zhuangtaiguanli/returnclearcookie">退出登陸並不保留登陸資訊</a><br/>
<a href="login.html">退出登入,但5分鐘內免登陸</a>
</body>
</html>

五.測試結果 測試   這是第一次登陸成功結果,通過開發者工具可以清楚看到,Cookie儲存了username,以便下次判斷。

測試2   這是免登陸的結果截圖,可以清楚看到,Cookie裡是有username的,所以可以直接跳轉進來。

這裡寫圖片描述   這是點選清除Cookie退出或Cookie過期時,點選免輸入的結果,細心觀察可以看到,此時Cookie已經沒有username了,並且sessionid是沒有變的。所以是登陸不進去需要重新輸入的。

六.總結   在Servlet裡Cookie和Session是一個非常重要的概念,熟悉Cookie和Session的過程和應用場景是非常必要的,也要了解兩者的關係。   一口氣寫完,想必有多處不足和失誤,歡迎提出疑惑。也歡迎大家隨時溝通交流。