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

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