利用servlet+Javabean+JSP 实现用户登陆案例

JavaWeb—用户登陆案例

项目描述

​ 完成用户登录功能,登录界面必须要有账号、密码、验证码。

项目要求

​ 后端技术要求为 Servlet.登录验证通过数据库进行验证数据库操作使用原生JDBC,前端 htmljsp、css、js 都可以,不能使用框架。代码需满足 Java 编程规范,注释需要清晰明了。

实现效果

登陆首页

登陆首页

验证码输入错误

验证码错误

登陆失败

账号密码错误

登陆成功

登陆成功

项目代码:

sheep_login.jsp

<%--
  Created by IntelliJ IDEA.
  User: Allen xu
  Date: 2023/11/25
  Time: 20:21
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<title>SheepGameStation - Game Login</title>
<style>
    body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        background: linear-gradient(to right, #008000, #ADFF2F);
        margin: 0;
        font-family: Arial, sans-serif;
    }
    .login-form {
        width: 300px;
        background-color: #ffffff;
        padding: 30px;
        border-radius: 10px;
        box-shadow: 0px 0px 20px 5px #00000050;
        text-align: center;
    }
    .login-form input {
        width: calc(100% - 20px);
        padding: 10px;
        margin-bottom: 10px;
        border: none;
        border-bottom: 1px solid #008000;
        outline: none;
        transition: border-bottom 0.3s ease;
    }
    .login-form input:focus {
        border-bottom: 2px solid #ADFF2F;
    }
    .login-form button {
        width: 100%;
        padding: 10px;
        border-radius: 5px;
        border: none;
        color: #ffffff;
        background: linear-gradient(to right, #008000, #ADFF2F);
    }
    .login-form h1, .login-form h3 {
        margin: 5px 0;
        color: #008000;
    }
    .captcha-container {
        display: flex;
        justify-content: center;
        align-items: center;
        margin-bottom: 10px;
    }
    .captcha-image {
        width: 150px;
        height: auto;
        margin-bottom: 10px;
        display: none; /* Initially hide the captcha */
    }
    .refresh-captcha {
        padding: 10px;
        margin-left: 10px;
        border-radius: 5px;
        border: none;
        color: #ffffff;
        background: linear-gradient(to right, #008000, #ADFF2F);
        cursor: pointer;
    }
</style>
<!--body元素加载完成后,会自动执行名为showUsernamePlaceholder的JavaScript函数-->
<body οnlοad="showUsernamePlaceholder()">
<!-- 登录表单的容器 -->
<div class="login-form">
    <!-- 游戏平台的标题 -->
    <h1>SheepGameStation</h1>
    <!-- 游戏平台的副标题 -->
    <h3>羊了个羊游戏平台</h3>
    <!-- 登录表单的标题 -->
    <h2>Game Login</h2>
    <!-- 登录表单,提交时会发送POST请求到SheepServlet -->
    <form action="SheepServlet" method="post">
        <!-- 用户名输入框 -->
        <input id="username" type="text" name="username" required>
        <!-- 密码输入框 -->
        <input id="password" type="password" name="password" required>
        <!-- 验证码的容器 -->
        <div class="captcha-container">
            <!-- 验证码的画布 -->
            <canvas id="captchaCanvas" class="captcha-image" width="150" height="60"></canvas>
            <!-- 刷新验证码的按钮,点击时会调用generateCaptcha函数 -->
            <button class="refresh-captcha" οnclick="generateCaptcha()">Refresh</button>
        </div>
        <!-- 验证码输入框 -->
        <input id="captcha" class="captcha" type="text" placeholder="Enter Captcha" required>
        <!-- 错误消息的div,如果Servlet设置了错误消息,就会显示 -->
        <div id="errorMessage" style=" background-image: linear-gradient(to right, #FFA500, #FF0000); /* 紫金渐变背景 */
                color: white; /* 白色字体 */
                margin-bottom: 10px; /* 底部间距 */
                display: <%=(request.getAttribute("errorMessage") != null) ? "block" : "none"%>; /* 根据错误消息的有无决定显示与否 */
                padding: 5px; /* 内边距 */
                text-align: center; /* 文本居中 */
                font-family: Arial, sans-serif; /* 字体 */
                font-size: 14px; /* 字体大小 */
                border-radius: 5px;
                border-bottom: 1px solid #ffffff; /* 下划线 */">
            <!-- 显示来自Servlet的错误消息 -->
            <%= request.getAttribute("errorMessage") %>
        </div>
        <!-- 登录按钮,点击时会提交表单 -->
        <button id="loginButton" type="submit">Login</button>
    </form>
</div>
</body>

<script>
    // 获取HTML元素
    var username = document.getElementById('username');
    var password = document.getElementById('password');
    var captchaInput = document.getElementById('captcha');
    var captchaCanvas = document.getElementById('captchaCanvas');
    var ctx = captchaCanvas.getContext('2d');

    // 定义占位符文本
    var usernameText = 'Please enter username';
    var passwordText = 'Please enter password';

    // 定义计数器
    var i = 0;
    var j = 0;

    // 显示用户名输入框的占位符
    function showUsernamePlaceholder() {
        if (i < usernameText.length) {
            username.placeholder += usernameText.charAt(i);
            i++;
            setTimeout(showUsernamePlaceholder, 100);
        } else {
            // 当用户名占位符显示完毕,显示密码输入框的占位符
            showPasswordPlaceholder();
        }
    }

    // 显示密码输入框的占位符
    function showPasswordPlaceholder() {
        if (j < passwordText.length) {
            password.placeholder += passwordText.charAt(j);
            j++;
            setTimeout(showPasswordPlaceholder, 100);
        } else {
            // 当密码占位符显示完毕,生成验证码
            captchaInput.placeholder = 'Enter Captcha';
            generateCaptcha();
            captchaCanvas.style.display = 'inline-block';
        }
    }

    // 用于保存当前生成的验证码
    var currentCaptcha = '';

    // 生成验证码
    function generateCaptcha() {
        // 清除画布
        ctx.clearRect(0, 0, captchaCanvas.width, captchaCanvas.height);
        var chars = '0123456789';
        currentCaptcha = '';
        var colors = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF']; // 添加颜色数组
        for (var k = 0; k < 6; k++) {
            // 生成随机数字
            var digit = chars[Math.floor(Math.random() * chars.length)];
            currentCaptcha += digit;
            // 设置随机颜色和字体大小
            ctx.fillStyle = colors[k];
            ctx.font = (Math.random() * 10 + 20) + 'px Arial';
            // 保存当前状态并旋转文字
            ctx.save();
            ctx.translate(25 * k + 10, 40);
            ctx.rotate(Math.random() - 0.5);
            // 绘制文字并恢复状态
            ctx.fillText(digit, 0, 0);
            ctx.restore();
        }
        // 绘制干扰线
        for (var l = 0; l < 6; l++) {
            ctx.beginPath();
            ctx.moveTo(Math.random() * captchaCanvas.width, Math.random() * captchaCanvas.height);
            ctx.lineTo(Math.random() * captchaCanvas.width, Math.random() * captchaCanvas.height);
            ctx.strokeStyle = '#888';
            ctx.stroke();
        }
    }



    // 处理用户输入账号密码并且发出登录请求的函数
    function loginToSheepServlet() {
        // 获取并清理输入框的值
        var usernameValue = username.value.trim();
        var passwordValue = password.value.trim();
        var userInput = captchaInput.value.trim();

        // 检查用户输入的验证码是否正确
        if (userInput === currentCaptcha) {
            // 获取表单元素
            var form = document.querySelector('form');
            // 创建一个新的FormData对象
            var formData = new FormData(form);

            // 创建一个新的XMLHttpRequest对象
            var xhr = new XMLHttpRequest();
            // 初始化一个POST请求
            xhr.open('POST', '/SheepServlet', true);
            // 设置请求头
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            // 发送请求
            xhr.send(formData);
            // 设置状态改变的回调函数
            xhr.onreadystatechange = function () {
                // 当请求完成时
                if (xhr.readyState === XMLHttpRequest.DONE) {
                    // 如果响应状态码为200
                    if (xhr.status === 200) {
                        console.log("登陆成功")
                    } else{
                        // 处理其他状态码的情况
                        console.log("登陆失败")
                    }
                }
            };
        } else {
            // 如果验证码错误,显示警告信息并重新生成验证码
            alert('验证码错误,请重试。');
            generateCaptcha();
            captchaInput.value = '';
        }
    }

    // 当点击登录按钮时,调用loginToSheepServlet函数
    document.getElementById('loginButton').addEventListener('click', function (event) {
        // 阻止默认提交行为
        // event.preventDefault();
        loginToSheepServlet();
    });

</script>
</body>
</html>

User.java

package com.hbnu.sheep;

/**
 * User类用于封装数据
 * @author Allen xu
 * {@code @date} 2023/11/26 9:14
 * @version 1.0
 */
public class User {
    // 用户名
    private String username;
    // 密码
    private String password;

    /**
     * 获取用户名
     * @return 用户名
     */
    public String getUsername() {
        return username;
    }

    /**
     * 设置用户名
     * @param username 用户名
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * 获取密码
     * @return 密码
     */
    public String getPassword() {
        return password;
    }

    /**
     * 设置密码
     * @param password 密码
     */
    public void setPassword(String password) {
        this.password = password;
    }
}

SheepServlet.java

package com.hbnu.sheep;
/**
 * @author Allen xu
 * {@code @date} 2023/11/26 9:14
 * @version 1.0
 */
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.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

// 使用@WebServlet注解定义Servlet的访问URL
@WebServlet("/SheepServlet")
public class SheepServlet extends HttpServlet {

    // 重写doPost方法,处理POST请求
    protected void doPost(HttpServletRequest request, HttpServletResponse response){
        // 从请求中获取用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        //获取数据库连接
        try {
            // 加载数据库驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 数据库连接URL
            String url = "jdbc:mysql://localhost:3306/你的数据库名?useSSL=false&serverTimezone=UTC";
            // 数据库用户名
            String user_sql = "root";
            // 数据库密码
            String sqlps = "123456";
            // 获取数据库连接
            Connection connection = DriverManager.getConnection(url, user_sql, sqlps);
            // 创建PreparedStatement对象,用于执行SQL查询
            PreparedStatement preparedStatement = connection.prepareStatement("select * from user where account=? and password=?");
            // 设置查询参数
            preparedStatement.setString(1,username);
            preparedStatement.setString(2,password);
            // 执行查询并获取结果
            ResultSet resultSet = preparedStatement.executeQuery();
            if(resultSet.next()){
                //登陆成功设置返回状态200
                response.setStatus(HttpServletResponse.SC_OK);
                //如果验证账号密码成功,将账户存储到javabean中
                User user = new User();
                user.setUsername(username);

                // 将 User 对象存储在 Session 中
                HttpSession session = request.getSession();
                session.setAttribute("loggedInUser", user);

                // 重定向到成功页面
                response.sendRedirect("/success.jsp");
            }else {
                // 如果验证失败,设置错误信息并转发到登录页面
                request.setAttribute("errorMessage", "用户名或密码错误,请重试。");
                request.getRequestDispatcher("/sheeplogin.jsp").forward(request, response);
            }

        } catch (Exception e) {
            // 如果出现异常,抛出运行时异常
            throw new RuntimeException(e);
        }
    }
}

success.jsp

<%--
  Created by IntelliJ IDEA.
  User: Allen xu
  Date: 2023/11/26
  Time: 11:39
  To change this template use File | Settings | File Templates.
--%>
<%-- IntelliJ IDEA创建的模板注释 --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- 使用jsp:useBean标签在session范围内创建一个User对象 -->
<jsp:useBean id="loggedInUser" scope="session" class="com.hbnu.sheep.User"/>

<html>
<head>
  <!-- 设置页面标题 -->
  <title>Success Page</title>
  <!-- 设置页面样式 -->
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background: linear-gradient(to right, #008000, #ADFF2F);
      margin: 0;
      font-family: Arial, sans-serif;
    }
    .success-message {
      text-align: center;
      padding: 20px;
      background-color: #ffffff;
      border-radius: 10px;
      box-shadow: 0px 0px 20px 5px #00000050;
    }
    h1 {
      color: #008000;
    }
  </style>
</head>
<body>
<!-- 显示成功信息 -->
<div class="success-message">
  <!-- 使用jsp:getProperty标签获取User对象的username属性,并显示在欢迎消息中 -->
  <h1>Welcome, <jsp:getProperty name="loggedInUser" property="username" /></h1>
  <p>You are now logged in!</p>
</div>
</body>
</html>

项目文档:

一、项目概述

1.1 项目背景

本项目是一个基于JavaWeb的用户登录系统,通过用户输入用户名和密码进行验证,验证成功后将用户信息存储在Session中,并重定向到成功页面。

1.2 项目结构
  • User类:用于封装用户数据,包括用户名和密码。
  • SheepServlet类:处理用户登录请求,连接数据库验证用户身份。
  • success.jsp:登录成功后跳转的页面,显示欢迎消息。
  • sheeplogin.jsp:用户登录页面,包含用户名、密码输入框和验证码功能。

二、项目详细分析

2.1 User

User类用于封装用户数据,包含用户名和密码。通过提供获取和设置方法,实现对用户信息的操作。

2.2 SheepServlet
2.2.1 处理POST请求

doPost方法中,获取用户输入的用户名和密码,连接数据库验证用户身份。

2.2.2 数据库连接

通过JDBC连接MySQL数据库,执行SQL查询语句验证用户名和密码是否匹配。

2.2.3 登录成功

如果验证成功,设置返回状态为200,将用户信息存储在User对象中,并存储在Session中,然后重定向到success.jsp页面。

2.2.4 登录失败

如果验证失败,设置错误信息,并转发到sheeplogin.jsp页面。

2.3 success.jsp

在成功页面,使用JSP标签从Session中获取loggedInUser对象,显示欢迎消息。

三、操作文档

3.1 项目部署
  1. 确保已配置好Java开发环境和MySQL数据库。
  2. 导入项目到IDE中。
  3. 配置数据库连接信息(url、用户名、密码)。
  4. 启动项目,确保Tomcat服务器正常运行。
3.2 登录流程
  1. 访问sheeplogin.jsp页面。
  2. 输入用户名、密码,生成验证码。
  3. 点击登录按钮,触发loginToSheepServlet函数。
  4. 检查验证码,正确则发送POST请求到SheepServlet
  5. SheepServlet连接数据库验证用户身份,成功则重定向到success.jsp,否则返回登录页面并显示错误消息。
3.3 注意事项
  1. 确保MySQL数据库已创建名为sheepgamestation-user的数据库。
  2. 确保数据库中存在user表,包含accountpassword字段。
3.4 修改页面样式
  1. 修改success.jspsheeplogin.jsp中的CSS样式,调整页面布局和颜色。
  2. 修改sheeplogin.jsp中的JavaScript函数,定制页面交互效果。
3.5 高级配置
  1. 实现用户注册功能,包括数据库插入新用户信息。
  2. 使用HTTPS协议加强安全性。
  3. 添加密码加密功能,存储加密后的密码。
  4. 浏览器会提示密码泄露

四、程序架构

思维导图:请添加图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Allen--xu

目前打算送外卖,筹资买个爱玛

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值