JavaWeb Session

1. Session概述

1.1. 什麼是Session

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

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

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

1.2. 百度百科

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

具體到Web中的Session指的就是用戶在瀏覽某個網站時,從進入網站到關閉這個網站所通過的這段時間,也就是用戶瀏覽這個網站所花費的時間。所以從上述的定義中咱們能夠看到,Session其實是一個特定的時間概念。數據庫

須要注意的是,一個Session的概念須要包括特定的客戶端,特定的服務器端以及不中斷的操做時間。A用戶和C服務器創建鏈接時所處的SessionB用戶和C服務器創建鏈接時所處的Session是兩個不一樣的Sessionapache

1.3. 維基百科

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

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

1.4. SessionCookie的區別

SessionCookie都是解決Http協議的無狀態問題,可是二者之間仍是存在必定區別的:api

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

總的來講,SessionCookie各有優點,不能簡單來講誰更優。具體用法要考慮具體案例狀況而定。瀏覽器

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

JavaEEjavax.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分鐘。當session30分鐘內沒有使用,那麼Tomcat會在session池中移除這個session
  • void setMaxInactiveInterval(int interval):設置session容許的最大不活動時間(秒),若是設置爲1秒,那麼只要session1秒內不被使用,那麼session就會被移除;
  • void invalidate():讓session失效!調用這個方法會被session失效,當session失效後,客戶端再次請求,服務器會給客戶端建立一個新的session,並在響應中給客戶端新sessionsessionId

下面咱們經過一個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,那麼AServletBServlet能夠共享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>
相關文章
相關標籤/搜索