1. 程式人生 > >Session概述(java)

Session概述(java)

數據存儲 pragma eas 思想 查找 rgb play 服務 esp

JavaWeb Session

轉載於:https://www.cnblogs.com/aaron911/p/7889353.html

1. Session概述

1.1. 什麽是Session

Session一般譯為會話,是解決Http協議的無狀態問題的方案,可以將一次會話中的數據存儲在服務器端的內存中,保證在下一次的會話中可以使用。

在客戶端瀏覽器第一次向服務器端發送請求時,服務器端會為這個客戶端創建獨有的Session,並具有唯一的Session ID,存儲在服務器端的內存中。在客戶端第二次訪問服務器端時,會攜帶Session ID在請求中,服務器端會根據Session ID查找對應的Session信息,進行進一步地操作。

在JavaEE中提供了javax.servlet.http.HttpSession接口,通過該接口可以將共享的數據內容存儲在HttpSession對象中,從而解決Http協議的無狀態問題。

1.2. 百度百科

Session直接翻譯成中文比較困難,一般都譯成時域。在計算機專業術語中,Session是指一個終端用戶與交互系統進行通信的時間間隔,通常指從註冊進入系統到註銷退出系統之間所經過的時間。以及如果需要的話,可能還有一定的操作空間。

具體到Web中的Session指的就是用戶在瀏覽某個網站時,從進入網站到關閉這個網站所經過的這段時間,也就是用戶瀏覽這個網站所花費的時間。因此從上述的定義中我們可以看到,Session實際上是一個特定的時間概念。

需要註意的是,一個Session的概念需要包括特定的客戶端,特定的服務器端以及不中斷的操作時間。A用戶和C服務器建立連接時所處的Session同B用戶和C服務器建立連接時所處的Session是兩個不同的Session。

1.3. 維基百科

會話(session)是一種持久網絡協議,在用戶(或用戶代理)端和服務器端之間創建關聯,從而起到交換數據包的作用機制,session在網絡協議(例如telnet或FTP)中是非常重要的部分。

在不包含會話層(例如UDP)或者是無法長時間駐留會話層(例如HTTP)的傳輸協議中,會話的維持需要依靠在傳輸數據中的高級別程序。例如,在瀏覽器和遠程主機之間的HTTP傳輸中,HTTP cookie就會被用來包含一些相關的信息,例如session ID,參數和權限信息等。

1.4. Session與Cookie的區別

Session與Cookie都是解決Http協議的無狀態問題,但是兩者之間還是存在一定區別的:

  • Cookie數據存儲在客戶端的瀏覽器內存中或本地緩存文件中,Session數據存儲在服務器端的內存中。
  • Cookie數據存儲安全性較低,Session數據存儲安全性較高。
  • Session數據存儲在服務器端內存中,訪問增多時,降低服務器端性能。而Cookie則不會對服務器端性能造成影響。
  • 單個Cookie存儲的數據最大是4KB,一個網站只能存儲20個Cookie。Session則沒有這個問題。
  • Session在關閉瀏覽器時失效,而持久Cookie則可以存儲更長有效時間。

總的來說,Session與Cookie各有優勢,不能簡單來說誰更優。具體用法要考慮具體案例情況而定。

2. Session入門

2.1. Session常用API

在JavaEE提供的javax.servlet.http.HttpSession接口,是Web應用程序開發使用Session的接口,該接口提供了很多API方法,而常用的方法有以下幾個:

Method Summary

Object

getAttribute(String name)
Returns the object bound with the specified name in this session, or null if no object is bound under the name.

Enumeration

getAttributeNames()
Returns an Enumeration of String objects containing the names of all the objects bound to this session.

void

removeAttribute(String name)
Removes the object bound with the specified name from this session.

void

setAttribute(String name, Object value)
Binds an object to this session, using the name specified.

  • 通過Request對象獲得HttpSession對象。
HttpSession session = request.getSession();
  • 通過HttpSession對象設置和獲取共享數據內容。
session.setAttribute("name", "longestory");
String name = (String)session.getAttribute("name");

2.2. 第一個Session

掌握了如何獲取Session對象及向Session對象中設置及獲取共享數據內容,下面我們就來利用HttpSession對象實現數據內容共享。

  • 創建一個Servlet用於向HttpSession對象中存儲共享數據內容。
技術分享圖片
public class FirstServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        session.setAttribute("name", "longestory");
        System.out.println("已經成功向HttpSession對象中存儲了共享數據內容name=longestory...");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
技術分享圖片
  • 創建另一個Servlet用於從HttpSession對象中獲取儲存的共享數據內容。
技術分享圖片
public class SecondServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        
        HttpSession session = request.getSession();
        String name = (String)session.getAttribute("name");
        
        out.println("<h1>你存儲的共享數據內容為name="+name+"</h1>");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
技術分享圖片
  • 配置Web工程的web.xml文件。
技術分享圖片
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name>
  <servlet>
    <servlet-name>FirstServlet</servlet-name>
    <servlet-class>app.java.session.FirstServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>SecondServlet</servlet-name>
    <servlet-class>app.java.session.SecondServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>FirstServlet</servlet-name>
    <url-pattern>/first</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>SecondServlet</servlet-name>
    <url-pattern>/second</url-pattern>
  </servlet-mapping>    
</web-app>
技術分享圖片

2.3. Session其他API

在JavaEE的javax.servlet.http.HttpSession接口提供了除常用方法外,還有很多其他方法可供使用:

Method Summary

long

getCreationTime()
Returns the time when this session was created, measured in milliseconds since midnight January 1, 1970 GMT.

String

getId()
Returns a string containing the unique identifier assigned to this session.

long

getLastAccessedTime()
Returns the last time the client sent a request associated with this session, as the number of milliseconds since midnight January 1, 1970 GMT, and marked by the time the container received the request.

int

getMaxInactiveInterval()
Returns the maximum time interval, in seconds, that the servlet container will keep this session open between client accesses.

ServletContext

getServletContext()
Returns the ServletContext to which this session belongs.

void

invalidate()
Invalidates this session then unbinds any objects bound to it.

boolean

isNew()
Returns true if the client does not yet know about the session or if the client chooses not to join the session.

void

setMaxInactiveInterval(int interval)
Specifies the time, in seconds, between client requests before the servlet container will invalidate this session.

  • String getId():獲取sessionId;
  • long getCreationTime():返回session的創建時間,返回值為當前時間的毫秒值;
  • long getLastAccessedTime():返回session的最後活動時間,返回值為當前時間的毫秒值;
  • boolean isNew():查看session是否為新。當客戶端第一次請求時,服務器為客戶端創建session,但這時服務器還沒有響應客戶端,也就是還沒有把sessionId響應給客戶端時,這時session的狀態為新;
  • int getMaxInactiveInterval():獲取session可以的最大不活動時間(秒),默認為30分鐘。當session在30分鐘內沒有使用,那麽Tomcat會在session池中移除這個session;
  • void setMaxInactiveInterval(int interval):設置session允許的最大不活動時間(秒),如果設置為1秒,那麽只要session在1秒內不被使用,那麽session就會被移除;
  • void invalidate():讓session失效!調用這個方法會被session失效,當session失效後,客戶端再次請求,服務器會給客戶端創建一個新的session,並在響應中給客戶端新session的sessionId。

下面我們通過一個Servlet將上述中的一些方法進行測試,這裏理解性記憶就好,後面案例中用到哪個方式再具體掌握。

  • 創建一個Servlet用於測試HttpSession對象的方法。
技術分享圖片
public class ThreeServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Calendar calendar = Calendar.getInstance();

        HttpSession session = request.getSession();
        System.out.println("Session的ID為"+session.getId());
        
        calendar.setTimeInMillis(session.getCreationTime());
        System.out.println("Session的創建時間為"+formatter.format(calendar.getTime()));
        
        calendar.setTimeInMillis(session.getLastAccessedTime());
        System.out.println("Session的最後活動時間為"+formatter.format(calendar.getTime()));
        
        System.out.println("當前Session是否為新的?"+session.isNew());
        System.out.println("Session的默認活動時間為"+session.getMaxInactiveInterval()/60+"分鐘");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
技術分享圖片
  • 配置Web工程的web.xml文件。
技術分享圖片
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name>
  <servlet>
    <servlet-name>ThreeServlet</servlet-name>
    <servlet-class>app.java.session.ThreeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ThreeServlet</servlet-name>
    <url-pattern>/three</url-pattern>
  </servlet-mapping>    
</web-app>
技術分享圖片

2.4. Servlet三大域對象

現在掌握了HttpSession對象的基本使用方法,到目前為止,Servlet的三大域對象都已經掌握。Servlet的三大域對象分別為HttpServletRequest對象、ServletContext對象及HttpSession對象:

  • HttpServletRequest:一個請求創建一個request對象,所以在同一個請求中可以共享request,例如一個請求從AServlet轉發到BServlet,那麽AServlet和BServlet可以共享request域中的數據;
  • ServletContext:一個應用只創建一個ServletContext對象,所以在ServletContext中的數據可以在整個應用中共享,只要不啟動服務器,那麽ServletContext中的數據就可以共享;
  • HttpSession:一個會話創建一個HttpSession對象,同一會話中的多個請求中可以共享session中的數據。

3. Session詳解

3.1. Session的實現原理

通過HttpSession對象實現了在多次會話中共享數據內容,HttpSession對象底層到底是如何實現這樣的效果?下面我們來討論一下。

  • 利用MyEclipse工具的Debug模式進行調試代碼,在request.getSession()處打上斷點。
  • Debug模式啟動Tomcat服務器,並訪問對應的Servlet,抓取獲取的Session內容。

技術分享圖片

會發現實際得到的是org.apache.catalina.session.StandardSession對象,該對象是由Tomcat服務器的Session池創建,並為該對象創建唯一的ID值。

  • 通過IE瀏覽器的HttpWatch工具抓取請求響應協議內容。

會發現服務器端向客戶端進行響應時,向客戶端發送了一個Cookie信息,具體內容如下:

Set-Cookie: JSESSIONID=0BD17B07E383FA86703B370560E823F2; Path=/11_session/; HttpOnly
  • 客戶端再次訪問對應Servlet時,通過IE瀏覽器的HttpWatch工具抓取請求響應協議內容。

會發現客戶端向服務器端發送請求時,向服務器端發送了一個Cookie信息,具體內容如下:

Cookie: JSESSIONID=0BD17B07E383FA86703B370560E823F2

通過上述操作,我們會發現在第一次請求時,服務器端向客戶端響應Cookie信息,在第二次請求時,客戶端向服務器端發送了Cookie信息。進而可以總結出Session的實現原理如下:

技術分享圖片

因為Session使用的是會話Cookie,所以當瀏覽器關閉後,Session會失效。重新打開瀏覽器訪問對應Servlet時,服務器端會重新創建Session對象。可以使用持久Cookie來延長Session的有效時間。

3.2. 禁用Cookie後的Session

通過Session的實現原理可以知道,Session的實現是基於Cookie的。如果瀏覽器禁用Cookie的話,Session是否還是有效的呢?下面我們具體操作來看一看。

  • 打開IE瀏覽器的“工具”->“Internet選項”->“隱私”選項,阻止所有Cookie。
  • 這時重新啟動Tomcat服務器,訪問對應的Servlet。

這個問題是否可以解決呢?答案是可以的,可以利用URL重寫方式來解決,具體操作如下:

  • 通過Response對象的encodeURL()方法將URL進行重寫。
String url = request.getRequestURI();
url = response.encodeURL(url);
response.getWriter().println("<a href=‘" + url + "‘>second</a>");

禁用Cookie解決Session的問題,這種解決方案是具有理論意義的,但不具備實際意義。因為大部分的網站都是基於Cookie完成數據共享的,例如京東網站或淘寶網站等。如果瀏覽器禁用Cookie,網站會提示相關信息。

3.3. Session的生命周期

關於Sessioin的生命周期,在之前的內容都有學習到,只是沒有專門歸納總結。下面總結一下Session的生命周期,主要是Session的創建和銷毀。

  • Session的創建:在客戶端第一次向服務器端發送請求,並執行request.getSession()方法時。
  • Session的銷毀:
    • 不正常關閉瀏覽器時。(正常關閉瀏覽器,Session信息被序列化到硬盤中,保存在Tomcat服務器安裝目錄/work目錄)
    • Session信息過期時(Session默認的有效時間為30分鐘)。

      可以利用setMaxInactiveInterval(int interval)方法設置Session的有效時間。

    • 在服務器端程序中執行session.invalidate()方法,手動銷毀Session對象。

4. Session案例

4.1. 商品購物車案例

利用Session實現商品購物車的邏輯功能,具體操作如下:

  • 創建一個JSP頁面用於顯示商品信息。
技術分享圖片
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="java.util.Map"%>
<%@ page import="java.util.Set"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP ‘show.jsp‘ starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
  </head>
  <body>
    <!-- 商品列表 -->
    <h1>商品列表</h1>
    Java編程思想<a href="/session/show?id=1">購買</a><br>
    Java設計模式<a href="/session/show?id=2">購買</a><br>
    Java語言入門<a href="/session/show?id=3">購買</a><br>
    Oracle數據庫<a href="/session/show?id=4">購買</a><br>
    MySQL數據庫<a href="/session/show?id=5">購買</a><br>
    <!-- 購物車記錄 -->
    <h1>購物車記錄</h1>
    <h2><a href="/session/clear">清空購物車</a></h2>
    <%
        Map<String,Integer> map = (Map<String,Integer>)request.getSession().getAttribute("cart"); 
        if(map == null){
            // 購物車對象不存在
            out.println("<h2>購物車無任何商品信息!</h2>");
        }else{
            // 購物車對象已經存在
            Set<String> keySet = map.keySet();
            for(String productName: keySet){
                int number = map.get(productName);// 購買數量
                out.println("商品名稱: " + productName +", 購買數量:" + number + "<br/>");
            }
        }
    %>
  </body>
</html>
技術分享圖片
  • 創建一個Servlet用於處理添加購物車的邏輯。
技術分享圖片
public class ShowServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 獲得購買商品 id
        String id = request.getParameter("id");
        // 獲得id 對應商品名稱
        String[] names = { "Java編程思想", "Java設計模式", "Java語言入門", "Oracle數據庫", "MySQL數據庫" };
        String productName = names[Integer.parseInt(id) - 1];
        // 判斷Session中購物車是否存在
        HttpSession session = request.getSession();
        Map<String, Integer> cart = (Map<String, Integer>) session.getAttribute("cart");
        if (cart == null) {
            // 購物車不存在
            cart = new HashMap<String, Integer>();
        }
        // 判斷購買商品是否存在於購物車中,商品名稱就是map的key
        if (cart.containsKey(productName)) {
            // 商品已經在購物車中
            int number = cart.get(productName);// 取出原來數量
            cart.put(productName, number + 1);// 數量+1 放回購物車
        } else {
            // 商品不在購物車中
            cart.put(productName, 1);// 保存商品到購物車,數量為1
        }
        // 將購物車對象保存Session
        session.setAttribute("cart", cart);
        // 給用戶提示
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().println("商品已經添加到購物車!<a href=‘/session/cart/show.jsp‘>返回</a>");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
技術分享圖片
  • 創建一個Servlet用於處理清空購物車記錄的邏輯。
技術分享圖片
public class ClearServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 獲取購物車Session對象
        HttpSession session = request.getSession();
        // 刪除購物車cart對象
        session.removeAttribute("cart");
        // 跳轉show.jsp
        response.sendRedirect("/session/cart/show.jsp");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
技術分享圖片
  • 配置Web工程的web.xml文件。
技術分享圖片
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name>
  <servlet>
    <servlet-name>ShowServlet</servlet-name>
    <servlet-class>app.java.session.ShowServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>ClearServlet</servlet-name>
    <servlet-class>app.java.session.ClearServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ShowServlet</servlet-name>
    <url-pattern>/show</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>ClearServlet</servlet-name>
    <url-pattern>/clear</url-pattern>
  </servlet-mapping>    
</web-app>
技術分享圖片

4.2. 一次驗證碼登錄案例

所謂一次驗證碼,就是驗證碼生成後,只能使用一次,不管成功或者失敗,驗證碼都將失效。具體實現步驟如下:

  • 創建一個JSP頁面用於顯示用戶登錄信息。
技術分享圖片
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP ‘login.jsp‘ starting page</title>
  </head>
  <script type="text/javascript">
    function change(){
        document.getElementById("myimg").src = "/session/checkimg?timeStamp="+new Date().getTime();
    }
  </script>
  <body>
    <h1>登陸頁面</h1>
    <h2 style="color:red;">${requestScope.msg }</h2>
    <form action="/11_session/login" method="post">
        <table>
            <tr>
                <td>用戶名</td>
                <td><input type="text" name="username" /></td>
            </tr>
            <tr>
                <td>密碼</td>
                <td><input type="password" name="password"/> </td>
            </tr>
            <tr>
                <td>驗證碼</td>
                <td><input type="text" name="checkcode" /> <img src="/session/checkimg" onclick="change();" id="myimg" style="cursor: pointer;"/></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="登陸" /></td>
            </tr>
        </table>
    </form>
  </body>
</html>
技術分享圖片
  • 創建一個Servlet用於生成驗證碼圖片。
技術分享圖片
public class CheckImgServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int width = 120;
        int height = 30;
        // 步驟一 繪制一張內存中圖片
        BufferedImage bufferedImage = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
        // 步驟二 圖片繪制背景顏色 ---通過繪圖對象
        Graphics graphics = bufferedImage.getGraphics();//得到畫圖對象 - 畫筆
        // 繪制任何圖形之前 都必須指定一個顏色
        graphics.setColor(getRandColor(200, 250));
        graphics.fillRect(0, 0, width, height);
        // 步驟三 繪制邊框
        graphics.setColor(Color.WHITE);
        graphics.drawRect(0, 0, width - 1, height - 1);
        // 步驟四 四個隨機數字
        Graphics2D graphics2d = (Graphics2D) graphics;
        // 設置輸出字體
        graphics2d.setFont(new Font("宋體", Font.BOLD, 18));
        String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
        Random random = new Random();// 生成隨機數
        // 為了將驗證碼保存Session
        StringBuffer buffer = new StringBuffer();
        // 定義x坐標
        int x = 10;
        for (int i = 0; i < 4; i++) {
            // 隨機顏色
            graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
            // 旋轉 -30 --- 30度
            int jiaodu = random.nextInt(60) - 30;
            // 換算弧度
            double theta = jiaodu * Math.PI / 180;
            // 生成一個隨機數字
            int index = random.nextInt(words.length());//生成隨機數0到 length-1
            // 獲得字母數字
            char c = words.charAt(index);
            // 將生成漢字 加入buffer
            buffer.append(c);
            // 將c 輸出到圖片
            graphics2d.rotate(theta, x, 20);
            graphics2d.drawString(String.valueOf(c), x, 20);
            graphics2d.rotate(-theta, x, 20);
            x += 30;
        }
// 將驗證碼內容保存session
    request.getSession().setAttribute("checkcode_session",buffer.toString());
        // 步驟五 繪制幹擾線
        graphics.setColor(getRandColor(160, 200));
        int x1;
        int x2;
        int y1;
        int y2;
        for (int i = 0; i < 30; i++) {
            x1 = random.nextInt(width);
            x2 = random.nextInt(12);
            y1 = random.nextInt(height);
            y2 = random.nextInt(12);
            graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
        }
        // 將上面圖片輸出到瀏覽器 ImageIO
        graphics.dispose();// 釋放資源
        ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    /**
     * 取其某一範圍的color
     * 
     * @param fc
     *            int 範圍參數1
     * @param bc
     *            int 範圍參數2
     * @return Color
     */
    private Color getRandColor(int fc, int bc) {
        // 取其隨機顏色
        Random random = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }
}
技術分享圖片
  • 創建一個Servlet用於處理登錄驗證邏輯。
技術分享圖片
public class LoginServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 獲得用戶名、密碼和 驗證碼
        request.setCharacterEncoding("utf-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String checkcode = request.getParameter("checkcode");
        // 判斷驗證碼是否正確
        String checkcode_session = (String) request.getSession().getAttribute("checkcode_session");
        request.getSession().removeAttribute("checkcode_session");
        if (checkcode_session == null || !checkcode_session.equals(checkcode)) {
            // 驗證碼輸入錯誤
            request.setAttribute("msg", "驗證碼輸入錯誤!");
    request.getRequestDispatcher("/login/login.jsp").forward(request,response);
            return;
        }
        // 判斷用戶名和密碼是否正確 ,假設用戶名和密碼都是admin/admin
        if ("admin".equals(username) && "admin".equals(password)) {
            // 登陸成功
            // 將登陸信息保存session
            request.getSession().setAttribute("username", username);
            response.sendRedirect("/session/login/welcome.jsp");
        } else {
            // 登陸失敗
            request.setAttribute("msg", "用戶名或者密碼錯誤!");
         request.getRequestDispatcher("/login/login.jsp").forward(request,response);
        }
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
技術分享圖片
  • 創建一個JSP頁面用於顯示歡迎信息。
技術分享圖片
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP ‘welcome.jsp‘ starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
  </head>
  <body>
    <h1>登陸後的歡迎頁面</h1>
    <%
        String username = (String)request.getSession().getAttribute("username");
        if(username == null){
            // 未登陸
            out.println("您還未登陸,<a href=‘/session/login/login.jsp‘>去登陸</a>");
        }else{
            // 已經登陸
            out.println("歡迎您,"+username);
        }
    %>
  </body>
</html>
技術分享圖片

Session概述(java)