JavaWeb-Demo4:驗證碼

Github:verification_code

一. 需求

  1. 訪問帶有驗證碼的登錄頁面 login.jsp。
  2. 用戶輸入用戶名、密碼、驗證碼。
    1. 如果用戶名或密碼輸入錯誤,跳轉至登錄頁面,提示:用戶名或密碼錯誤
    2. 如果驗證碼輸入錯誤,跳轉至登錄頁面,提示:驗證碼錯誤
    3. 如果全部輸入正確,跳轉至主頁 success.jsp,顯示:用戶名,歡迎您!

二. 分析

分析

三. 開發步驟

VerificationCodeServlet.java,參考:四. response Demo - 4. 驗證碼

package com.hjplz.servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@WebServlet("/verificationCodeServlet")
public class VerificationCodeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int width = 100; // 驗證碼圖片的寬度
        int height = 50; // 驗證碼圖片的高度

        // 1. 創建一個對象,代表在內存中的驗證碼圖片
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        // 2. 美化圖片
        // 2.1 填充背景色
        Graphics g = image.getGraphics(); // 畫筆對象
        g.setColor(Color.PINK); // 設置畫筆顏色
        g.fillRect(0, 0, width, height);

        // 2.2 畫邊框
        g.setColor(Color.BLUE);
        // 邊框佔 1 像素,所以寬高相應 - 1
        g.drawRect(0, 0, width - 1, height - 1);

        // 2.3 寫驗證碼
        StringBuilder sb = new StringBuilder();
        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        Random ran = new Random();
        // 隨機生成四個驗證碼字符
        for(int i = 1; i <= 4; i++) {
            // 生成隨機角標
            int index = ran.nextInt(str.length());
            // 獲取隨機字符
            char ch = str.charAt(index);
            sb.append(ch);

            g.drawString(ch + "", width / 5 * i, height / 2);
        }
        // 將驗證碼存入 Session 中
        String code = sb.toString();
        request.getSession().setAttribute("code_session", code);

        // 2.4 畫干擾線
        g.setColor(Color.GREEN);
        // 隨機生成 10 條幹擾線
        for(int i = 0; i < 10; i++) {
            // 隨機生成 4 個座標點
            int x1 = ran.nextInt(width);
            int x2 = ran.nextInt(width);
            int y1 = ran.nextInt(height);
            int y2 = ran.nextInt(height);
            g.drawLine(x1, x2, y1, y2);
        }

        // 3. 將圖片輸出到頁面
        ImageIO.write(image, "jpg", response.getOutputStream());
    }

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

LoginServlet.java

package com.hjplz.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 設置 request 編碼格式
        request.setCharacterEncoding("UTF-8");
        // 2. 獲取參數
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String code = request.getParameter("code");
        // 3. 獲取生成的驗證碼
        String code_session = (String)request.getSession().getAttribute("code_session");
        HttpSession session = request.getSession();
        // 刪除 session 中存儲的驗證碼
        session.removeAttribute("code_session");
        // 4. 判斷驗證碼是否正確,忽略大小寫比較
        if(code_session == null) { // 用戶已登錄(使用過此驗證碼)
            // 轉發到登錄頁面
            request.getRequestDispatcher("login.jsp").forward(request, response);
        }
        else if(code_session.equalsIgnoreCase(code)) { // 驗證碼正確
            // 判斷用戶名和密碼是否正確,應該由 UserDao 的 login() 判斷
            if("admin".equals(username) && "123".equals(password)) { // 登錄成功
                // 在 Session 中存儲用戶信息
                session.setAttribute("username", username);
                // 重定向到 success.jsp
                response.sendRedirect(request.getContextPath() + "/success.jsp");
            }
            else { // 登錄失敗
                // 在 request 中存儲信息
                request.setAttribute("login_error", "用戶名或密碼錯誤");
                // 轉發到登錄頁面
                request.getRequestDispatcher("/login.jsp").forward(request, response);
            }
        }
        else { // 驗證碼錯誤
            // 在 request 中存儲信息
            request.setAttribute("code_error", "驗證碼錯誤");
            // 轉發到登錄頁面
            request.getRequestDispatcher("/login.jsp").forward(request, response);
        }

    }

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

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>
    <style>
        div {
            color: red;
        }
    </style>
</head>
<body>
    <form action="/verification_code/loginServlet" 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="code"/></td>
            </tr>
            <tr>
                <td colspan="2"><img id="img" src="/verification_code/verificationCodeServlet"></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="登錄"></td>
            </tr>
        </table>
    </form>

    <div><%= request.getAttribute("code_error") == null ? "" : request.getAttribute("code_error")%></div>
    <div><%= request.getAttribute("login_error") == null ? "" : request.getAttribute("login_error")%></div>
</body>
<script>
    window.onload = function() {
        document.getElementById("img").onclick = function() {
            // 添加時間戳防止獲取瀏覽器緩存結果
            this.src = "/verification_code/verificationCodeServlet?time=" + new Date().getTime();
        }
    }
</script>
</html>

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>success</title>
</head>
<body>
    <h1><%= request.getSession().getAttribute("username") %>,歡迎您!</h1>
</body>
</html>

四. 項目結構

項目結構

五. 效果演示

  1. 登錄頁面 login.jsp
    1

  2. 登錄成功,重定向至 success.jsp
    在這裏插入圖片描述

  3. 驗證碼錯誤,轉發回 login.jsp
    3

  4. 用戶名或密碼錯誤,轉發回 login.jsp
    4

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章