梅州市万年长

使用JSP+JavaScript实现验证码登录功能

2026-04-02 19:23:01 浏览次数:1
详细信息

1. 项目结构

webapp/
├── WEB-INF/
│   └── web.xml
├── index.jsp
├── login.jsp
├── loginServlet.jsp
├── captcha.jsp
└── success.jsp

2. 生成验证码的Servlet (captcha.jsp)

<%@ page contentType="image/jpeg" %>
<%@ page import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>
<%!
// 随机生成颜色
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);
}
%>
<%
// 设置页面不缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);

// 在内存中创建图像
int width = 80, height = 30;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

// 获取图形上下文
Graphics g = image.getGraphics();

// 生成随机类
Random random = new Random();

// 设定背景色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height);

// 设定字体
g.setFont(new Font("Times New Roman", Font.PLAIN, 24));

// 画边框
g.setColor(new Color(255, 255, 255));
g.drawRect(0, 0, width - 1, height - 1);

// 随机产生155条干扰线,使图像中的验证码不易被其他程序探测到
g.setColor(getRandColor(160, 200));
for (int i = 0; i < 155; i++) {
    int x = random.nextInt(width);
    int y = random.nextInt(height);
    int xl = random.nextInt(12);
    int yl = random.nextInt(12);
    g.drawLine(x, y, x + xl, y + yl);
}

// 取随机产生的验证码(4位数字)
String sRand = "";
for (int i = 0; i < 4; i++) {
    String rand = String.valueOf(random.nextInt(10));
    sRand += rand;
    // 将验证码显示到图像中
    g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
    g.drawString(rand, 13 * i + 6, 24);
}

// 将验证码存入SESSION
session.setAttribute("captcha", sRand);

// 图像生效
g.dispose();

// 输出图像到页面
ImageIO.write(image, "JPEG", response.getOutputStream());
response.getOutputStream().flush();
response.getOutputStream().close();

out.clear();
out = pageContext.pushBody();
%>

3. 登录页面 (login.jsp)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <title>验证码登录</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }

        .login-container {
            background-color: white;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            width: 350px;
        }

        h2 {
            text-align: center;
            color: #333;
            margin-bottom: 30px;
        }

        .form-group {
            margin-bottom: 20px;
        }

        label {
            display: block;
            margin-bottom: 5px;
            color: #555;
            font-weight: bold;
        }

        input[type="text"],
        input[type="password"] {
            width: 100%;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
            font-size: 14px;
        }

        .captcha-group {
            display: flex;
            gap: 10px;
            align-items: flex-end;
        }

        .captcha-input {
            flex: 1;
        }

        .captcha-img {
            height: 40px;
            border: 1px solid #ddd;
            border-radius: 4px;
            cursor: pointer;
        }

        .refresh-btn {
            background: none;
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 5px 10px;
            cursor: pointer;
            font-size: 12px;
        }

        .refresh-btn:hover {
            background-color: #f5f5f5;
        }

        .submit-btn {
            width: 100%;
            padding: 12px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            font-weight: bold;
        }

        .submit-btn:hover {
            background-color: #0056b3;
        }

        .error-message {
            color: red;
            text-align: center;
            margin-top: 15px;
            font-size: 14px;
            display: none;
        }

        .message {
            color: #28a745;
            text-align: center;
            margin-top: 15px;
            font-size: 14px;
        }
    </style>
</head>
<body>
    <div class="login-container">
        <h2>用户登录</h2>

        <form id="loginForm" method="post" action="loginServlet.jsp">
            <div class="form-group">
                <label for="username">用户名:</label>
                <input type="text" id="username" name="username" 
                       placeholder="请输入用户名" required>
            </div>

            <div class="form-group">
                <label for="password">密码:</label>
                <input type="password" id="password" name="password" 
                       placeholder="请输入密码" required>
            </div>

            <div class="form-group">
                <label for="captcha">验证码:</label>
                <div class="captcha-group">
                    <div class="captcha-input">
                        <input type="text" id="captcha" name="captcha" 
                               placeholder="请输入验证码" required>
                    </div>
                    <div>
                        <img id="captchaImage" src="captcha.jsp" 
                             class="captcha-img" alt="验证码" 
                             onclick="refreshCaptcha()">
                    </div>
                    <button type="button" class="refresh-btn" 
                            onclick="refreshCaptcha()">
                        刷新
                    </button>
                </div>
            </div>

            <button type="submit" class="submit-btn">登录</button>

            <div id="errorMessage" class="error-message"></div>

            <%-- 显示消息 --%>
            <%
                String message = (String) session.getAttribute("message");
                if (message != null) {
                    String messageClass = message.contains("成功") ? "message" : "error-message";
            %>
                <div class="<%= messageClass %>" style="display: block;">
                    <%= message %>
                </div>
            <%
                    session.removeAttribute("message");
                }
            %>
        </form>
    </div>

    <script>
        // 刷新验证码
        function refreshCaptcha() {
            var captchaImage = document.getElementById('captchaImage');
            // 添加时间戳防止缓存
            captchaImage.src = 'captcha.jsp?t=' + new Date().getTime();
            document.getElementById('captcha').value = '';
        }

        // 表单提交验证
        document.getElementById('loginForm').onsubmit = function(e) {
            e.preventDefault();

            var username = document.getElementById('username').value;
            var password = document.getElementById('password').value;
            var captcha = document.getElementById('captcha').value;
            var errorMessage = document.getElementById('errorMessage');

            // 清空错误消息
            errorMessage.textContent = '';
            errorMessage.style.display = 'none';

            // 简单的前端验证
            if (!username.trim()) {
                showError('请输入用户名');
                return false;
            }

            if (!password.trim()) {
                showError('请输入密码');
                return false;
            }

            if (!captcha.trim()) {
                showError('请输入验证码');
                return false;
            }

            if (captcha.length !== 4) {
                showError('验证码必须是4位数字');
                return false;
            }

            // 如果验证通过,提交表单
            this.submit();
        };

        function showError(message) {
            var errorMessage = document.getElementById('errorMessage');
            errorMessage.textContent = message;
            errorMessage.style.display = 'block';
        }

        // 输入验证码后自动去除空格
        document.getElementById('captcha').oninput = function() {
            this.value = this.value.replace(/\s/g, '');
        };

        // 页面加载时自动聚焦到用户名输入框
        window.onload = function() {
            document.getElementById('username').focus();
        };
    </script>
</body>
</html>

4. 登录处理Servlet (loginServlet.jsp)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
// 设置字符编码
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");

// 获取表单数据
String username = request.getParameter("username");
String password = request.getParameter("password");
String captchaInput = request.getParameter("captcha");

// 获取session中的验证码
String captchaSession = (String) session.getAttribute("captcha");

// 验证验证码
boolean isCaptchaValid = false;
if (captchaSession != null && captchaInput != null) {
    isCaptchaValid = captchaSession.equalsIgnoreCase(captchaInput);
}

// 清除session中的验证码(一次性使用)
session.removeAttribute("captcha");

if (!isCaptchaValid) {
    // 验证码错误
    session.setAttribute("message", "验证码错误,请重新输入");
    response.sendRedirect("login.jsp");
    return;
}

// 这里可以添加数据库验证(示例使用硬编码验证)
boolean isValidUser = false;
if ("admin".equals(username) && "123456".equals(password)) {
    isValidUser = true;
}

if (isValidUser) {
    // 登录成功
    session.setAttribute("username", username);
    session.setAttribute("message", "登录成功!");
    response.sendRedirect("success.jsp");
} else {
    // 登录失败
    session.setAttribute("message", "用户名或密码错误");
    response.sendRedirect("login.jsp");
}
%>

5. 登录成功页面 (success.jsp)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <title>登录成功</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }

        .success-container {
            background-color: white;
            padding: 40px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            text-align: center;
        }

        h2 {
            color: #28a745;
            margin-bottom: 20px;
        }

        .welcome-message {
            color: #333;
            font-size: 18px;
            margin-bottom: 30px;
        }

        .logout-btn {
            background-color: #dc3545;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
        }

        .logout-btn:hover {
            background-color: #c82333;
        }

        .back-btn {
            background-color: #6c757d;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            margin-left: 10px;
        }

        .back-btn:hover {
            background-color: #5a6268;
        }
    </style>
</head>
<body>
    <div class="success-container">
        <h2>登录成功!</h2>
        <div class="welcome-message">
            欢迎您,<strong><%= session.getAttribute("username") %></strong>!
        </div>
        <button class="logout-btn" onclick="logout()">退出登录</button>
        <button class="back-btn" onclick="goBack()">返回登录页</button>
    </div>

    <script>
        function logout() {
            if (confirm('确定要退出登录吗?')) {
                window.location.href = 'index.jsp';
            }
        }

        function goBack() {
            window.location.href = 'login.jsp';
        }
    </script>
</body>
</html>

6. 首页 (index.jsp)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <title>首页</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            padding-top: 100px;
            background-color: #f4f4f4;
        }

        .container {
            max-width: 600px;
            margin: 0 auto;
            padding: 30px;
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }

        h1 {
            color: #333;
        }

        .login-btn {
            background-color: #007bff;
            color: white;
            border: none;
            padding: 15px 30px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 18px;
            margin-top: 30px;
        }

        .login-btn:hover {
            background-color: #0056b3;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>欢迎来到验证码登录演示系统</h1>
        <p>这是一个使用JSP + JavaScript实现的验证码登录功能演示</p>

        <%
            String username = (String) session.getAttribute("username");
            if (username != null) {
        %>
            <p>当前已登录用户: <strong><%= username %></strong></p>
            <button class="login-btn" onclick="window.location.href='success.jsp'">
                进入系统
            </button>
        <%
            } else {
        %>
            <button class="login-btn" onclick="window.location.href='login.jsp'">
                前往登录
            </button>
        <%
            }
        %>
    </div>
</body>
</html>

7. web.xml配置(可选)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <display-name>CaptchaLoginDemo</display-name>

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

功能说明:

验证码生成

前端功能

后端验证

安全性考虑

测试账号:

这个实现包含了完整的验证码登录流程,可以直接部署到Tomcat服务器上运行。

相关推荐