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