目录
1、致谢
2、前言
3、系统实机演示
4、系统分析与设计
(1)主要软件与工具
(2)系统分析
(3)系统规划
5、系统设计与构建
(1)JavaWeb创建
(2)JavaWeb运行
(3)先期依赖准备:
6、代码与关键注释、文件简析
(1)数据库
(2)前端
index.jsp和styleIndex.css:
forgetPassword.jsp和styleForgetPassword.css、sendMail.js:
mainPage.jsp和styleMainPage.css:
(3)后端(Servlet):
SignServlet.java:
EmailServlet.java:
LogoutServlet.java:
(4)后端(Util)
MailUtil.java
JDBCUtil.java
VcodeUtil.java
User.java
(5)后端(DAO)
DAO.java:
(6)配置文件
web.xml:
7、系统完成形式与参考代码
1、致谢
特别感谢CSDN用户 水金猪肚鸡 对本文“6、代码与关键注释、文件简析(1)数据库”新建数据表内容中指令错误的斧正!
特别感谢CSDN用户 ruwosigui 对本文“5、系统设计与构建(1)JavaWeb创建”中两处链接失效问题的指出!
特此感谢!
同时欢迎各位同志对此文章错误与遗漏之处提出批评建议!
2、前言
首先,关于源码的获取,本人提供了三种方式:
- 直接从文章里面Ctrl+C,Ctrl+V,然后按照我已给的文件结构搞一下即可;
- 通过积分下载上传到CSDN的资源;
- 点开本人的主页,点击“查看详细资料”,添加好友获取源码文件(如果有问题同样可以通过这里问),本人承诺无特殊情况,三小时内将无条件提供源码(所谓特殊情况仅指时间上的,毕竟挂上去的是我的副号,获取信息可能不及时,见谅)。
(另外,私信没法发文件,真的不要再从私信问我要源码了,我也只能给你再指回到我的个人简介那里去)
注:关于第二个获取方式……实际上用第三种方式就行,和第二种方式获得的文件没任何区别,再不济可以用第一种,真的真的没必要用第二种(但是做慈善的话我也欢迎,毕竟我也需要一点积分用来下载资源)
一切的一切要从我心血来潮脑子一热报了专业选修——Java说起,我承认我报的时候草率了,我承认我低估了它的难度。但是还是得写的好一点,毕竟期末结课嘛,写的好一点,多一点总归没坏处,于是就有了今天这篇改自我的实验报告和代码的JavaWeb登录注册系统。
本系统基本实现了登录注册所需的功能,包括但不限于登录检查、注册检查、多登录方式提供、邮箱验证码获取与校验等功能,还加写了一个登录后注销账户的功能。
系统总共分三个界面:
- 第一个是负责注册和常规密码登录的界面;
- 第二个是负责邮箱验证码登录的界面;
- 第三个是主界面,没有实际意义,就是登陆成功后总得跳转个界面,这个界面上我也没完全空着,加了个注销。
3、系统实机演示
实机演示视频https://live.csdn.net/v/269198?spm=1001.2014.3001.5501
4、系统分析与设计
(1)主要软件与工具
工具:HUAWEI MATEBOOK D14(Windows 10)
软件:IntelliJ IDEA 2022.3,MySQL 8.0.28,Adobe Photoshop 2021,Microsoft Edge
(2)系统分析
登录注册系统需要具有的基本功能包括登录和注册两个部分。其中:
- 显性需求:提供注册信息写入服务,提供注册信息格式错误排查服务,提供登录检查服务;
- 隐性需求:注册部分应当考虑到用户对于自己设置的密码是否存在无意的输入错误(需求:需要二次确认密码);登录部分应到考虑到用户是否会忘记密码(需求:需要提供多种登录验证方式);
- 除此之外,还有一些便于后续开发而提供的需求,包括保存session以便向其他网页传递用户基本信息。
(3)系统规划
系统主要包括:数据库(MySQL)、后端诸项(Servlet,Util等)、前端诸项(JSP,CSS,JS)。
a. 数据库:
需要在MySQL中新建用于存储用户信息(包含用户邮箱和密码字段)的数据库(database test)及其数据表(table user)。为了保障其他数据库的安全性,因此新建访问该数据库的用户("java"@"%")并赋以相应权限(all on test.*)。
b. 前端:
需要设计三个界面,即:登录注册界面(index.jsp)、忘记密码登录界面(forgetPassword .jsp)、主界面(mainPage.jsp),及其附带的.js和.css文件。其中:
- 登录注册界面需要提供注册和常规账号密码登录两个子系统,并使用滑块进行子系统的切换。其中登录部分包含登录按钮、用于输入登录信息的两个输入框、用于切换到忘记密码登录界面的链接;注册部分则包含注册按钮,用于注册的三个输入框;除此之外还包括用于切换模式的两个按钮。
- 主界面为验证登录成功的跳转界面,本身无特殊价值和功能,仅加入了注销账户(即删除账户)的按钮,一键注销账户并同时跳转回登录注册界面。
- 忘记密码登录界面需要提供忘记密码登录服务,包含获取验证码的动态按钮、验证登录的按钮以及用于输入信息的两个输入框。
c. 后端:
- DAO:
-
Util:
- MailUtil.java:提供邮件发送的相关配置和邮件内容的拟写。
- JDBCUtil.java:提供数据库连接的相关配置。
- VCodeUtil.java:随机生成若干位包含大小写字母/数字验证码。
- User.java:提供存储临时用户、写入信息的方法从而便于传递参数。
-
Servlet:
- SignServlet.java:对应index.jsp,负责获取前端输入值并按照输入的信息判断启动相应的验证过程完成登录验证或注册。
- EmailServlet.java:对应forgetPassword.jsp,负责接收前端输入值并按照按键调用相应的方法(邮箱验证与验证码生成、发送,或核验验证码)。
- LogoutServlet.java:对应mainPage.jsp,主要目的是按照按键读取存储登录账户邮箱的session并注销该账户。
d. DAO.java:提供对数据库中的数据进行增删改查的方法。
e. 配置文件
web.xml:提供Servlet配置,并设置初始界面为index.jsp(登录注册界面)(注:这个东西极其重要,一开始的时候Servlet忘了在这里配置,结果前后端连不上,浪费了四五个小时。如何配置可以参考我后面的代码,也可以去其他博主那里查,但是务必要做好,做不好有的是哭的时候)。
5、系统设计与构建
(1)JavaWeb创建
关于JavaWeb创建的问题,由于我是基于IDEA做的,因此我就只给出IDEA创建JavaWeb项目的方法,链接如下:
IDEA社区版创建JavaWeb项目
IDEA专业版创建JavaWeb项目
一般来讲用IDEA专业版更保险,更舒适,更便捷,但是要花钱。不花钱的办法也有三个,其一是申请JetBrains的免费教育许可证(需要学生或教师身份),其二是破解(方法自己查),其三是利用一个月的试用期完成代码(你只有一个月)。
(2)JavaWeb运行
JavaWeb运行可以参见之前创建JavaWeb项目中给出的流程,由于我本人对于IDEA没有很熟悉,因此不过多评述,一切参照其他操作。
(3)先期依赖准备:
-
依赖包下载方式:
- 点开本人的主页,点击“查看详细资料”,添加好友获取依赖包(如果有问题同样可以通过这里问),本人承诺无特殊情况,三小时内将无条件提供依赖包(所谓特殊情况仅指时间上的,毕竟挂上去的是我的副号,获取信息可能不及时,见谅)。
- 源码里面包含所需的包,理论上无需单独下载。
- 通过本人CSDN资源免积分下载:
Activation-1.1.jar
javax.mail-1.6.2.jar
mysql-connector-j-8.0.31.jar
fastjson-2.0.21.jar
(那个fastJSON的本项目不需要)
-
依赖包添加:
- 第一步,按照之前给出的项目文件架构,在根目录下新建lib文件夹
- 把下载好的依赖包(.jar文件)扔进去
- 在IDEA里左侧的文件结构栏,右键.jar文件,点击“add as library”即可
6、代码与关键注释、文件简析
(注:注释是英文的,问就是写程序一直来回切换中英文实在过于麻烦,不想看英文的参见此处,包你满意)
(1)数据库
- 新建数据库test:
create database test;
- 新建用户java,密码为java,设置允许任何主机访问:
create user "java"@"%" identified by "java";
- 授予用户java对test数据库的所有数据表的全部权限:
grant all on test.* to "java"@"%";
- 在test库中新建数据表user:
create table user(
user_email char(100) primary key,
user_password char(50)
);
(2)前端
-
index.jsp和styleIndex.css:
JSP文件将登录和注册分置于两个表单,分别设置提交按钮进行表单的提交,从而保障一个servlet可以对应两个功能而不产生数据输入的冲突。利用嵌入的JS进行表单提交的中继。
添加用于切换登录/注册的按钮,切换动作通过更换各层的z-index和使用上层overlay进行不需要的模块的遮盖和切换滑块的移动。
使用轮播图进行背景的更换和展示,具体内容参考自他人代码。
index.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SIGN UP & SIGN IN</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<link rel="stylesheet" href="styleIndex.css">
<script type="text/javascript">
window.onload = function () {
const signInBtn = document.getElementById("SignIn");
const signUpBtn = document.getElementById("SignUp");
const container = document.querySelector(".container");
// Submit information form
document.getElementById("form1");
document.getElementById("form2");
// Listen for switching action events and start related operations
signInBtn.addEventListener("click", () => {
container.classList.remove("right-panel-active");
});
signUpBtn.addEventListener("click", () => {
container.classList.add("right-panel-active");
});
}
</script>
</head>
<body>
<div class="container right-panel-active">
<%--Sign in--%>
<div class="container_form container--signin">
<form action="SignServlet" method="post" class="form" id="form1">
<h2 class="form_title">Sign In</h2>
<label for="user_email_1"></label>
<input type="email" id="user_email_1" name="user_email_1" required="required" placeholder="Email" class="input" />
<label for="user_password_1"></label>
<input type="password" id="user_password_1" name="user_password_1" required="required" placeholder="Password" class="input" />
<a href="forgetPassword.jsp" class="link">Forgot password?</a>
<button type="submit" class="btn" id="login">Sign In</button>
</form>
</div>
<%--Sign up--%>
<div class="container_form container--signup">
<form action="SignServlet" method="post" class="form" id="form2">
<h2 class="form_title">Sign Up</h2>
<label for="user_email_2"></label>
<input type="email" id="user_email_2" name="user_email_2" required="required" placeholder="Email" class="input" />
<label for="user_password_2"></label>
<input type="password" id="user_password_2" name="user_password_2" required="required" placeholder="Password" class="input" />
<label for="user_password_confirm"></label>
<input type="password" id="user_password_confirm" name="user_password_confirm" required="required" placeholder="Confirm Password" class="input" />
<button type="submit" class="btn" id="register">Sign Up</button>
</form>
</div>
<%--Layer button--%>
<div class="container_overlay">
<div class="overlay">
<div class="overlay_panel overlay--left">
<button class="btn" id="SignIn">Sign In</button>
</div>
<div class="overlay_panel overlay--right">
<button class="btn" id="SignUp">Sign Up</button>
</div>
</div>
</div>
</div>
<%--Background carousel chart--%>
<div class="slidershow">
<div class="slidershow--image" style="background-image: url('https://images.unsplash.com/photo-1575138312433-d42e9f176f6b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MXwxfDB8MXxhbGx8fHx8fHx8fA&ixlib=rb-1.2.1&q=80&w=1080&utm_source=unsplash_source&utm_medium=referral&utm_campaign=api-credit');"></div>
<div class="slidershow--image" style="background-image: url('https://images.unsplash.com/photo-1668952410266-e86775275752?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=720&ixid=MnwxfDB8MXxyYW5kb218MHx8fHx8fHx8MTY3MDMxMjQ0MQ&ixlib=rb-4.0.3&q=80&w=1080');"></div>
<div class="slidershow--image" style="background-image: url('https://images.unsplash.com/photo-1668016910564-3314f9fbd0bb?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=720&ixid=MnwxfDB8MXxyYW5kb218MHx8fHx8fHx8MTY3MDMxMjgxMA&ixlib=rb-4.0.3&q=80&w=1080');"></div>
<div class="slidershow--image" style="background-image: url('https://images.unsplash.com/photo-1669833526714-0bfa8a3b5cae?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=720&ixid=MnwxfDB8MXxyYW5kb218MHx8fHx8fHx8MTY3MDMxMzM5OA&ixlib=rb-4.0.3&q=80&w=1080')"></div>
</div>
</body>
</html>
styleIndex.css
/*Declaration: As for this code mainly refers to the achievements of others, some comments may have errors. Sorry about this.*/
:root {
--white: #e9e9e9;
--gray: #333;
--blue: #095c91;
--blue-r: #315a7491;
--lightblue: #0393a3;
--button-radius: 0.7rem;
--max-width: 758px;
--max-height: 420px;
font-size: 16px;
font-family: "Microsoft YaHei", tahoma, arial, sans-serif, "Hiragino Sans GB";
}
body {
align-items: center;
background-color: var(--white);
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
display: grid;
height: 100vh;
place-items: center;
}
.form_title {
font-weight: 300;
margin: 0 0 1.25rem;
}
/*the link jumping to the forgetPassword page*/
.link {
color: var(--gray);
font-size: 0.9rem;
margin: 1.5rem 0;
text-decoration: none;
text-align: justify;
}
.container {
background-color: rgba(255, 255, 255, 0.1);
border-radius: var(--button-radius);
box-shadow: 0 0.9rem 1.7rem rgba(0, 0, 0, 0.25), 0 0.7rem 0.7rem rgba(0, 0, 0, 0.22);
height: var(--max-height);
max-width: var(--max-width);
overflow: hidden;
position: relative;
width: 100%;
z-index: 5;
}
/*Set moving elements*/
.container_form {
height: 100%;
position: absolute;
top: 0;
transition: transform 0.6s ease-in-out;
}
/*signin part*/
.container--signin {
left: 0;
width: 50%;
z-index: 10;
}
/*signin part's moving settings*/
.container.right-panel-active .container--signin {
transform: translateX(100%);
}
/*the same principal as above*/
.container--signup {
left: 0;
opacity: 0;
width: 50%;
z-index: 9;
}
.container.right-panel-active .container--signup {
-webkit-animation: show 0.6s;
animation: show 0.6s;
opacity: 1;
transform: translateX(100%);
z-index: 11;
}
/*Child body of "body". Set its style and move method*/
.container_overlay {
height: 100%;
left: 50%;
overflow: hidden;
position: absolute;
top: 0;
transition: transform 0.6s ease-in-out;
width: 50%;
z-index: 100;
}
.container.right-panel-active .container_overlay {
transform: translateX(-100%);
}
/*Child container of "container". Set its style and move method*/
.overlay {
background-color: rgba(255, 255, 255, 0.1);
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
height: 100%;
left: -100%;
position: relative;
transform: translateX(0);
transition: transform 0.6s ease-in-out;
width: 200%
}
.container.right-panel-active .overlay {
transform: translateX(50%);
}
/*Set move method of every single module for the button*/
.overlay_panel {
align-items: center;
display: flex;
flex-direction: column;
height: 100%;
justify-content: center;
position: absolute;
text-align: center;
top: 0;
transform: translateX(0);
transition: transform 0.6s ease-in-out;
width: 50%;
}
.overlay--left {
transform: translateX(-20%);
}
.container.right-panel-active .overlay--left {
transform: translateX(0);
}
.overlay--right {
right: 0;
transform: translateX(0);
}
.container.right-panel-active .overlay--right {
transform: translateX(20%);
}
.btn {
background-color: var(--blue);
background-image: linear-gradient(90deg, var(--blue) 0%, var(--lightblue) 74%);
border-radius: 20px;
border: 1px solid var(--blue-r);
color: var(--white);
cursor: pointer;
font-size: 0.8rem;
font-weight: bold;
letter-spacing: 0.1rem;
padding: 0.9rem 4rem;
text-transform: uppercase;
transition: transform 80ms ease-in;
}
.form > .btn {
margin-top: 1.5rem;
}
.btn:active {
transform: scale(0.95);
}
.btn:focus {
outline: none;
}
.form {
background-color: var(--white);
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 0 3rem;
height: 100%;
text-align: center;
}
.input {
background-color: #fff;
border: 1px solid transparent;
padding: 0.9rem 0.9rem;
margin:0.5rem 0;
width: 100%;
}
@-webkit-keyframes show {
0%,
49.99% {
opacity: 0;
z-index: 5;
}
50%,
100% {
opacity: 1;
z-index: 6;
}
}
@keyframes show {
0%,
49.99% {
opacity: 0;
z-index: 5;
}
50%,
100% {
opacity: 1;
z-index: 6;
}
}
.slidershow {
position: absolute;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.slidershow--image {
position: absolute;
width: 100%;
height: 100%;
background: no-repeat 50% 50%;
background-size: cover;
-webkit-animation-name: kenburns;
animation-name: kenburns;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-duration: 16s;
animation-duration: 16s;
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
.slidershow--image:nth-child(1) {
-webkit-animation-name: kenburns-1;
animation-name: kenburns-1;
z-index: 3;
}
.slidershow--image:nth-child(2) {
-webkit-animation-name: kenburns-2;
animation-name: kenburns-2;
z-index: 2;
}
.slidershow--image:nth-child(3) {
-webkit-animation-name: kenburns-3;
animation-name: kenburns-3;
z-index: 1;
}
.slidershow--image:nth-child(4) {
-webkit-animation-name: kenburns-4;
animation-name: kenburns-4;
z-index: 0;
}
@-webkit-keyframes keyburns-1 {
0% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
1.5625% {
opacity: 1;
}
23.4375% {
opacity: 1;
}
26.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform:scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
98.4375% {
opacity: 0;
-webkit-transform: scale(1.21176);
transform: scale(1.21176);
}
100% {
opacity: 1;
}
}
@keyframes kenburns-1 {
0% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
1.5625% {
opacity: 1;
}
23.4375% {
opacity: 1;
}
26.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform:scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
98.4375% {
opacity: 0;
-webkit-transform: scale(1.21176);
transform: scale(1.21176);
}
100% {
opacity: 1;
}
}
@-webkit-keyframes kenburns-2 {
23.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
26.5625% {
opacity: 1;
}
48.4375% {
opacity: 1;
}
51.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@keyframes kenburns-2 {
23.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
26.5625% {
opacity: 1;
}
48.4375% {
opacity: 1;
}
51.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@-webkit-keyframes kenburns-3 {
48.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
51.5625% {
opacity: 1;
}
73.4375% {
opacity: 1;
}
76.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@keyframes kenburns-3 {
48.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
51.5625% {
opacity: 1;
}
73.4375% {
opacity: 1;
}
76.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@-webkit-keyframes kenburns-4 {
73.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
76.5625% {
opacity: 1;
}
98.4375% {
opacity: 1;
}
100% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
@keyframes kenburns-4 {
73.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
76.5625% {
opacity: 1;
}
98.4375% {
opacity: 1;
}
100% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
-
forgetPassword.jsp和styleForgetPassword.css、sendMail.js:
对表单排布进行限定,并利用margin属性和长度比例显示实现按键和输入框保持对其状态,此处考虑到表单分开提交无法满足验证表单需要两层数据的需求,因此将选择相应功能的逻辑交给了后端的EmailServlet。sendMail.js将后端传来的校验完成的信息进行响应,并提供更改获取验证码按钮上的倒计时的功能,控制按钮的启用和禁用。
(forgetPassword.jsp中包含的jquery-1.11.3.js文件需要另行下载,本人提供免积分下载的CSDN资源)
forgetPassword.jsp
<%@ page pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML>
<html>
<head>
<base href="<%=basePath%>">
<title>Sign In with Email</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<link rel="stylesheet" href="styleForgetPassword.css">
</head>
<body>
<form class="container" id="form" name="form" AUTOCOMPLETE="OFF">
<form class="form">
<h2 class="title">Sign In</h2>
<table>
<tr height="35px">
<td>
<label for="user_email"></label>
<input type="text" name="user_email" id="user_email" placeholder="Email" class="input1" />
</td>
<td>
<button id="btnGetVcode" class="btn1" style="cursor:pointer">Get Code</button>
</td>
</tr>
<tr height="35px">
<td>
<label for="verification_code"></label>
<input type="text" name="verification_code" id="verification_code" placeholder="Verification Code" class="input2" />
</td>
<td id="message"></td>
</tr>
</table>
<a target="_self">
<button type="button" id="btnVerify" class="btn2" style="cursor:pointer">Sign In</button></a>
</form>
</form>
<div class="slidershow">
<div class="slidershow--image" style="background-image: url('https://images.unsplash.com/photo-1575138312433-d42e9f176f6b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MXwxfDB8MXxhbGx8fHx8fHx8fA&ixlib=rb-1.2.1&q=80&w=1080&utm_source=unsplash_source&utm_medium=referral&utm_campaign=api-credit');"></div>
<div class="slidershow--image" style="background-image: url('https://images.unsplash.com/photo-1668952410266-e86775275752?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=720&ixid=MnwxfDB8MXxyYW5kb218MHx8fHx8fHx8MTY3MDMxMjQ0MQ&ixlib=rb-4.0.3&q=80&w=1080');"></div>
<div class="slidershow--image" style="background-image: url('https://images.unsplash.com/photo-1668016910564-3314f9fbd0bb?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=720&ixid=MnwxfDB8MXxyYW5kb218MHx8fHx8fHx8MTY3MDMxMjgxMA&ixlib=rb-4.0.3&q=80&w=1080');"></div>
<div class="slidershow--image" style="background-image: url('https://images.unsplash.com/photo-1669833526714-0bfa8a3b5cae?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=720&ixid=MnwxfDB8MXxyYW5kb218MHx8fHx8fHx8MTY3MDMxMzM5OA&ixlib=rb-4.0.3&q=80&w=1080')"></div>
</div>
<!-- 引入jQuery -->
<script type="text/javascript" src="jquery-1.11.3.js"></script>
<script type="text/javascript" src="sendEmail.js"></script>
</body>
</html>
styleForgetPassword.css
/*Basic settings of color and font set*/
:root {
--white: #e9e9e9;
--gray: #333;
--blue: #095c91;
--blue-r: #315a7491;
--lightblue: #0393a3;
--button-radius: 0.7rem;
--max-width: 758px;
--max-height: 420px;
font-size: 16px;
font-family: "Microsoft YaHei", tahoma, arial, sans-serif, "Hiragino Sans GB";
}
/*Set body*/
body {
align-items: center;
background-color: var(--white);
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
display: grid;
height: 100vh;
place-items: center;
}
/*Set size and outer fill size*/
.title {
font-weight: 300;
margin: 0 0 1.25rem;
}
/*Set container*/
.container {
background-color: rgba(255, 255, 255, 0.6);
border-radius: var(--button-radius);
box-shadow: 0 0.9rem 1.7rem rgba(0, 0, 0, 0.25), 0 0.7rem 0.7rem rgba(0, 0, 0, 0.22);
display: flex;
flex-direction: column;
height: var(--max-height);
justify-content: center;
max-width: 379px;
overflow: hidden;
padding: 0 3rem;
position: relative;
text-align: center;
width: 100%;
z-index: 5;
}
.btn1 {
background-color: var(--blue);
background-image: linear-gradient(90deg, var(--blue) 0%, var(--lightblue) 74%);
border: 0;
color: var(--white);
cursor: pointer;
font-size: 0.8rem;
font-weight: bold;
letter-spacing: 0.1rem;
padding: 1.2rem 1.7rem;
}
.btn2 {
background-color: var(--blue);
background-image: linear-gradient(90deg, var(--blue) 0%, var(--lightblue) 74%);
border-radius: 20px;
border: 1px solid var(--blue-r);
color: var(--white);
cursor: pointer;
font-size: 0.8rem;
font-weight: bold;
letter-spacing: 0.1rem;
padding: 0.9rem 4rem;
margin: 2rem 0 0 0;
text-transform: uppercase;
transition: transform 80ms ease-in;
}
/*Animation of click (transition)*/
.form > .btn2 {
margin-top: 1.5rem;
}
.btn2:active {
transform: scale(0.95);
}
.btn2:focus {
outline: none;
}
/*Set input1, input2 to align the input box*/
.input1 {
background-color: #fff;
border: 1px solid transparent;
padding: 0.9rem 0.9rem;
margin: 0.5rem 0.6rem;
width: 80%;
}
.input2 {
background-color: #fff;
border: 1px solid transparent;
padding: 0.9rem 0.9rem;
margin: 0.5rem 0.6rem;
width: 140%;
}
/*Picture carousel. Just to look good. I haven't got the specific principles. So here will no notes*/
@-webkit-keyframes show {
0%,
49.99% {
opacity: 0;
z-index: 5;
}
50%,
100% {
opacity: 1;
z-index: 6;
}
}
@keyframes show {
0%,
49.99% {
opacity: 0;
z-index: 5;
}
50%,
100% {
opacity: 1;
z-index: 6;
}
}
.slidershow {
position: absolute;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.slidershow--image {
position: absolute;
width: 100%;
height: 100%;
background: no-repeat 50% 50%;
background-size: cover;
-webkit-animation-name: kenburns;
animation-name: kenburns;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-duration: 16s;
animation-duration: 16s;
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
.slidershow--image:nth-child(1) {
-webkit-animation-name: kenburns-1;
animation-name: kenburns-1;
z-index: 3;
}
.slidershow--image:nth-child(2) {
-webkit-animation-name: kenburns-2;
animation-name: kenburns-2;
z-index: 2;
}
.slidershow--image:nth-child(3) {
-webkit-animation-name: kenburns-3;
animation-name: kenburns-3;
z-index: 1;
}
.slidershow--image:nth-child(4) {
-webkit-animation-name: kenburns-4;
animation-name: kenburns-4;
z-index: 0;
}
@-webkit-keyframes keyburns-1 {
0% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
1.5625% {
opacity: 1;
}
23.4375% {
opacity: 1;
}
26.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform:scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
98.4375% {
opacity: 0;
-webkit-transform: scale(1.21176);
transform: scale(1.21176);
}
100% {
opacity: 1;
}
}
@keyframes kenburns-1 {
0% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
1.5625% {
opacity: 1;
}
23.4375% {
opacity: 1;
}
26.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform:scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
98.4375% {
opacity: 0;
-webkit-transform: scale(1.21176);
transform: scale(1.21176);
}
100% {
opacity: 1;
}
}
@-webkit-keyframes kenburns-2 {
23.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
26.5625% {
opacity: 1;
}
48.4375% {
opacity: 1;
}
51.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@keyframes kenburns-2 {
23.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
26.5625% {
opacity: 1;
}
48.4375% {
opacity: 1;
}
51.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@-webkit-keyframes kenburns-3 {
48.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
51.5625% {
opacity: 1;
}
73.4375% {
opacity: 1;
}
76.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@keyframes kenburns-3 {
48.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
51.5625% {
opacity: 1;
}
73.4375% {
opacity: 1;
}
76.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@-webkit-keyframes kenburns-4 {
73.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
76.5625% {
opacity: 1;
}
98.4375% {
opacity: 1;
}
100% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
@keyframes kenburns-4 {
73.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
76.5625% {
opacity: 1;
}
98.4375% {
opacity: 1;
}
100% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
sendMail.js
const time0 = 60; // Initial time
let time = time0;
let t; // Timing
$(document).ready(function() {
// Getting verification code
$("#btnGetVcode").click(function() {
const btnGet = document.getElementById("btnGetVcode");
btnGet.disabled = true; // to avoid multiple clicks
$.ajax({
url: 'EmailServlet?method=getVCode', // Choosing getCode method
type: 'post',
data: {user_email: $("input[name='user_email']").val()},
dataType: 'text',
success: function(msg) {
if(msg === "-1"){
window.alert("Incorrect Email.");
btnGet.disabled = false; // Disable button to avoid clicks before countdown being awakened
}
else if(msg === "0"){
window.alert("No Such User. Please Sign In First.");
btnGet.disabled = false;
}
else {
useChangeBTN(); // If passing the verification, change the button and awake the countdown
}
},
error:function(msg){
}
});
});
// 验证按钮
$("#btnVerify").click(function() {
document.getElementById("message");
$.ajax({
url: 'EmailServlet?method=verify', // Choosing verify method
type: 'post',
data: {verification_code: $("input[name='verification_code']").val()},
dataType: 'text',
success: function(msg) {
if(msg === "1"){
window.alert("Welcome!")
window.location.assign("mainPage.jsp"); // Jump to main page
}
else{
window.alert("Wrong Verification Code!");
}
},
error:function(msg){
}
});
});
});
// Function "changeBTN" is to start button display countdown and stop the disability of button when countdown ends
function changeBTN(){
if(time > 0){
$("#btnGetVcode").text(" "+time+" s ");
time = time - 1;
}
else{
const btnGet = document.getElementById("btnGetVcode");
btnGet.disabled = false;
$("#btnGetVcode").text("Get Code"); // Show former words
clearInterval(t);
time = time0; // Set back to the initial time
}
}
// Function "changeBTN" is to enable function "changeBTN"
function useChangeBTN(){
$("#btnGetVcode").text(" "+time+" s ");
time = time - 1;
t = setInterval("changeBTN()", 1000); // refresh once time per second
}
-
mainPage.jsp和styleMainPage.css:
样使用submit类型的button进行表单的提交,但并不获取任何内容,只负责启动后端的LogoutServlet从而注销账户。
mainPage.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MAIN PAGE</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<link rel="stylesheet" href="styleMainPage.css">
<script type="text/javascript">
window.onload = function () {
document.getElementById("form");
}
</script>
</head>
<body>
<div class="label">
<form action="LogoutServlet" class="form">
<h1 class="title">MAIN PAGE</h1>
<button type="submit" class="btnWF" id="write_off" name="write_off">Write Off</button>
</form>
</div>
<%--Background carousel chart--%>
<div class="slidershow">
<div class="slidershow--image" style="background-image: url('https://images.unsplash.com/photo-1575138312433-d42e9f176f6b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MXwxfDB8MXxhbGx8fHx8fHx8fA&ixlib=rb-1.2.1&q=80&w=1080&utm_source=unsplash_source&utm_medium=referral&utm_campaign=api-credit');"></div>
<div class="slidershow--image" style="background-image: url('https://images.unsplash.com/photo-1668952410266-e86775275752?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=720&ixid=MnwxfDB8MXxyYW5kb218MHx8fHx8fHx8MTY3MDMxMjQ0MQ&ixlib=rb-4.0.3&q=80&w=1080');"></div>
<div class="slidershow--image" style="background-image: url('https://images.unsplash.com/photo-1668016910564-3314f9fbd0bb?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=720&ixid=MnwxfDB8MXxyYW5kb218MHx8fHx8fHx8MTY3MDMxMjgxMA&ixlib=rb-4.0.3&q=80&w=1080');"></div>
<div class="slidershow--image" style="background-image: url('https://images.unsplash.com/photo-1669833526714-0bfa8a3b5cae?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=720&ixid=MnwxfDB8MXxyYW5kb218MHx8fHx8fHx8MTY3MDMxMzM5OA&ixlib=rb-4.0.3&q=80&w=1080')"></div>
</div>
</body>
</html>
styleMainPage.css
:root {
--white: #e9e9e9;
--gray: #333;
--blue: #095c91;
--blue-r: #315a7491;
--lightblue: #0393a3;
--pink: #ff7f7f;
--button-radius: 0.7rem;
--max-width: 758px;
--max-height: 420px;
font-size: 16px;
font-family: "Microsoft YaHei", tahoma, arial, sans-serif, "Hiragino Sans GB";
}
body {
align-items: center;
background-color: var(--white);
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
display: grid;
height: 100vh;
place-items: center;
}
.label {
background-color: rgba(255, 255, 255, 0);
border-radius: var(--button-radius);
box-shadow: 0 0.9rem 1.7rem rgba(0, 0, 0, 0.25), 0 0.7rem 0.7rem rgba(0, 0, 0, 0.22);
display: flex;
flex-direction: column;
height: var(--max-height);
justify-content: center;
max-width: 379px;
overflow: hidden;
padding: 0 3rem;
position: relative;
text-align: center;
width: 100%;
z-index: 5;
}
.title {
color: var(--white);
font-size: 6rem;
font-weight: 600;
margin: 0 0 1.25rem;
}
.btnWF {
background-color: var(--blue);
background-image: linear-gradient(90deg, var(--blue) 0%, var(--lightblue) 74%);
border-radius: 20px;
border: 1px solid var(--blue-r);
color: var(--pink);
cursor: pointer;
font-size: 0.8rem;
font-weight: bold;
letter-spacing: 0.1rem;
padding: 0.9rem 4rem;
margin: 2rem 0 0 0;
text-transform: uppercase;
transition: transform 80ms ease-in;
}
/*Animation of click (transition)*/
.form > .btnWF {
margin-top: 1.5rem;
}
.btnWF:active {
transform: scale(0.95);
}
.btnWF:focus {
outline: none;
}
@-webkit-keyframes show {
0%,
49.99% {
opacity: 0;
z-index: 5;
}
50%,
100% {
opacity: 1;
z-index: 6;
}
}
@keyframes show {
0%,
49.99% {
opacity: 0;
z-index: 5;
}
50%,
100% {
opacity: 1;
z-index: 6;
}
}
.slidershow {
position: absolute;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.slidershow--image {
position: absolute;
width: 100%;
height: 100%;
background: no-repeat 50% 50%;
background-size: cover;
-webkit-animation-name: kenburns;
animation-name: kenburns;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-duration: 16s;
animation-duration: 16s;
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
.slidershow--image:nth-child(1) {
-webkit-animation-name: kenburns-1;
animation-name: kenburns-1;
z-index: 3;
}
.slidershow--image:nth-child(2) {
-webkit-animation-name: kenburns-2;
animation-name: kenburns-2;
z-index: 2;
}
.slidershow--image:nth-child(3) {
-webkit-animation-name: kenburns-3;
animation-name: kenburns-3;
z-index: 1;
}
.slidershow--image:nth-child(4) {
-webkit-animation-name: kenburns-4;
animation-name: kenburns-4;
z-index: 0;
}
@-webkit-keyframes keyburns-1 {
0% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
1.5625% {
opacity: 1;
}
23.4375% {
opacity: 1;
}
26.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform:scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
98.4375% {
opacity: 0;
-webkit-transform: scale(1.21176);
transform: scale(1.21176);
}
100% {
opacity: 1;
}
}
@keyframes kenburns-1 {
0% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
1.5625% {
opacity: 1;
}
23.4375% {
opacity: 1;
}
26.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform:scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
98.4375% {
opacity: 0;
-webkit-transform: scale(1.21176);
transform: scale(1.21176);
}
100% {
opacity: 1;
}
}
@-webkit-keyframes kenburns-2 {
23.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
26.5625% {
opacity: 1;
}
48.4375% {
opacity: 1;
}
51.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@keyframes kenburns-2 {
23.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
26.5625% {
opacity: 1;
}
48.4375% {
opacity: 1;
}
51.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@-webkit-keyframes kenburns-3 {
48.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
51.5625% {
opacity: 1;
}
73.4375% {
opacity: 1;
}
76.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@keyframes kenburns-3 {
48.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
51.5625% {
opacity: 1;
}
73.4375% {
opacity: 1;
}
76.5625% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@-webkit-keyframes kenburns-4 {
73.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
76.5625% {
opacity: 1;
}
98.4375% {
opacity: 1;
}
100% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
@keyframes kenburns-4 {
73.4375% {
opacity: 1;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
76.5625% {
opacity: 1;
}
98.4375% {
opacity: 1;
}
100% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
(3)后端(Servlet):
-
SignServlet.java:
获取前端输入值后,根据user_password_confirm这一只存在于注册界面中的参数进行简单的功能判定,调用后端DAO中进行查询验证的Login方法或Register方法,进行登录或注册的验证与相关操作。在登陆验证过程中,如果通过验证,将跳转至主页面,同时新建session对象并获取session id,保存已登录的邮箱的信息。
package main.Servlet;
import java.io.IOException;
import java.sql.Connection;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import main.DAO.DAO;
import main.Util.JDBCUtil;
import main.Util.User;
// Servlet of Signing in and signing up
public class SignServlet extends HttpServlet {
private static final long serialVersionUID = 1L; // to ensure version compatibility
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// Information entered by user when signing in: email, password.
String user_email_1 = request.getParameter("user_email_1");
String user_password_1 = request.getParameter("user_password_1");
// Information entered by user when signing up: email, password and confirm password.
String user_email_2 = request.getParameter("user_email_2");
String user_password_2 = request.getParameter("user_password_2");
String user_password_confirm = request.getParameter("user_password_confirm");
response.setContentType("text/html;charset=utf8");
JDBCUtil db = new JDBCUtil();
DAO dao = new DAO();
// The following statements are verifying input information and give related feedbacks
if (user_password_confirm != null) {
// Signing up
String pattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[0-9a-zA-Z]{8,12}$";
boolean re = user_password_2.matches(pattern);
User user = new User(user_email_2, user_password_2);
try {
Connection connection = db.GetConn();
if (!user_password_2.equals(user_password_confirm)) {
response.getWriter().println("<script>alert('Inconsistent passwords.')</script>");
response.getWriter().println("<script>window.location.href='./index.jsp'</script>");
} else if (!re) {
response.getWriter().println("<script>alert('Passwords need more than eight digits including numbers and upper and lower case letters')</script>");
response.getWriter().println("<script>window.location.href='./index.jsp'</script>");
} else {
dao.Register(connection, user);
response.getWriter().println("<script>alert('Sign up successfully.')</script>");
response.getWriter().println("<script>window.location.href='./index.jsp'</script>");
}
} catch (Exception e) { // These statements can verify the existence of email address through integrity check service that mysql has provided
response.getWriter().println("<script>alert('This user already exists.')</script>");
response.getWriter().println("<script>window.location.href='./index.jsp'</script>");
}
} else {
// Signing in
User user = new User(user_email_1, user_password_1);
try {
Connection connection = db.GetConn();
if (dao.Login(connection, user) != null) {
HttpSession session = request.getSession(); // Get session
session.setAttribute("email", user_email_1); // Transferring information to session
response.getWriter().println("<script>alert('Welcome!')</script>");
response.getWriter().println("<script>window.location.href='./mainPage.jsp'</script>");
} else {
response.getWriter().println("<script>alert('Incorrect mailbox or password.')</script>");
response.getWriter().println("<script>window.location.href='./index.jsp'</script>");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
this.doPost(request, response);
}
}
-
EmailServlet.java:
获取前端输入值,并提供由sendMail.js中给出的method参数进行方法的选择(在此处同样设置新建session并存储用户邮箱信息),然后根据不同选择调用不同的方法,其中利用正则表达式验证邮箱格式和利用DAO.java中的Exist方法验证邮箱是否是已注册邮箱,并将VCodeUtil.java生成并传到servlet的验证码和输入的验证码进行比对。两个验证的结果均添加相应标签传至前端JS文件以做出相应的响应。
package main.Servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import main.DAO.DAO;
import main.Util.EmailUtil;
import main.Util.JDBCUtil;
import main.Util.User;
// Servlet of forgetPassword page
// Class "EmailServlet" is to send verification code to user and to check the code
public class EmailServlet extends HttpServlet {
private String user_email;
private String vCode; // Generated verification code
private String vCodeReceive; // Entered verification code
private PrintWriter out; // Output stream
private final EmailUtil emailUtil = EmailUtil.instance;
// Class "EmailServlet"'s construction method
public EmailServlet() {
System.out.println("Monitoring point: Email Servlet");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.setContentType("text/html");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
out = response.getWriter();
user_email = request.getParameter("user_email"); // Parameter "email" from fore-end
vCodeReceive = request.getParameter("verification_code"); // Parameter "vcode" from fore-end
String method = request.getParameter("method"); // Parameter "method" is to choose what method is needed
switch (method) {
case "getVCode": // when "Get Code button" is pressed
try {
MGetVCode();
} catch (Exception e) {
throw new RuntimeException(e);
}
break;
case "verify": // when "Sign In button" is pressed
HttpSession session = request.getSession(); // Get session
session.setAttribute("email", user_email); // Transferring information to session
MVerify();
break;
default:
break;
}
out.flush();
out.close();
}
// Method "MGetVCode" is to confirm email address and send verification code
private void MGetVCode() throws Exception {
DAO dao = new DAO();
User user = new User(user_email, null);
JDBCUtil db = new JDBCUtil();
Connection connection = db.GetConn(); // Configure connection and other things
System.out.println("Monitoring point: Sending Verification Code");
if(!IsEmail(user_email)) { // Verify format of email address
out.print("-1"); // a label to make judgement of the condition of wrong format
return; // Interrupt process
} else {
if (!dao.Exist(connection, user)) { // Verify whether this email address is registered
out.print("0"); // a label to make judgement of the condition of nonexistent email address
return;
}
}
try {
emailUtil.SendEmail(user_email); // Send verification code to target email address
} catch (Exception e) {
e.printStackTrace();
}
vCode = emailUtil.getVCode(); // Get and store the verification code sending just now
out.print("1"); // a label to make judgement of the condition
}
// Method "IsEmail" is to provide a method to confirm the format of email address
private boolean IsEmail(String email) {
if(email.length() == 0) {
return false;
}
Pattern pattern = Pattern.compile("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$"); // Regular expression
return pattern.matcher(email).matches();
}
// Method "MVerify" is to verify whether the verification code is correct
private void MVerify() {
System.out.println("Monitoring point: Verify Verification Code");
if(vCode.equals(vCodeReceive)) {
out.print("1"); // a label to make judgement of the condition
}
else {
out.print("-1"); // a label to make judgement of the condition
}
}
public void destroy() {
super.destroy();
}
@Override
public void init() throws ServletException {
super.init();
}
}
-
LogoutServlet.java:
简单的调用session中存储的信息并调用DAO.java中提供的logout方法实现退出登录并注销账户。
package main.Servlet;
import java.io.IOException;
import java.sql.Connection;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import main.DAO.DAO;
import main.Util.JDBCUtil;
import main.Util.User;
// Servlet of writing off account
public class LogoutServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String user_email_str;
HttpSession session = request.getSession();
Object user_email = session.getAttribute("email"); // Getting parameter from session
user_email_str = user_email.toString();
JDBCUtil db = new JDBCUtil();
DAO dao = new DAO();
Connection connection = db.GetConn();
User user = new User(user_email_str, null);
if (dao.Logout(connection, user)) {
response.getWriter().println("<script>alert('Can not write off.')</script>");
response.getWriter().println("<script>window.location.href='./mainPage.jsp'</script>");
} else {
response.getWriter().println("<script>alert('Write off successfully.')</script>");
response.getWriter().println("<script>window.location.href='./index.jsp'</script>");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
this.doPost(request, response);
}
}
(4)后端(Util)
-
MailUtil.java
注:此处涉及邮件SMTP协议的启动与关闭,可参照此文章(来自Wisdom0110):
使用JAVA实现邮件发送功能http://t.csdn.cn/ONKFk
package main.Util;
import java.util.Date;
import java.util.Properties;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
// Class "EmailUtil" is to configure the method sending email
public class EmailUtil {
private static final String fromEmail = "2562521178@qq.com"; // Sender
private static final String fromEmailPw = "################"; // Sender's password
private static final String myEmailSMTPHost = "smtp.qq.com"; // Mail Server
private static Session session; // Session object
private String vCode; // Getting verification code
public static EmailUtil instance = new EmailUtil();
// Method "getVCode" is to get verification code
public String getVCode() {
return vCode;
}
// Method "EmailUtil" is to configure protocol, server, etc
private EmailUtil() {
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp"); // SMTP protocol
props.setProperty("mail.smtp.host", myEmailSMTPHost); // Recipient's email server
props.setProperty("mail.smtp.auth", "true"); // Request authentication
session = Session.getInstance(props);
}
// Method "CreateMailContent" is to edit message
public MimeMessage CreateMailContent(String toEmail) throws Exception {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(fromEmail, "Verification Code Sending System", "UTF-8")); // Sender's information
message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toEmail)); // Recipient's information
message.setSubject("Verification Code", "UTF-8"); // Subject
vCode = VCodeUtil.VerifyCode(6); // Verification code
message.setContent("Your verification code is " + vCode + ". Please do not show it to others. ", "text/html;charset=UTF-8"); // Main message
message.setSentDate(new Date()); // Date
message.saveChanges(); // Save message
return message; // Return Message
}
// Method "SendEmail" is to send message edited just now
public void SendEmail(String toEmail) throws Exception {
Transport transport = session.getTransport(); // Create connection
transport.connect(fromEmail, fromEmailPw);
MimeMessage message = CreateMailContent(toEmail);
transport.sendMessage(message, message.getAllRecipients()); // Sending email
transport.close(); // Disconnection
}
}
-
JDBCUtil.java
package main.Util;
import java.sql.Connection;
import java.sql.DriverManager;
// Class "EmailUtil" is to configure the connection to database
public class JDBCUtil {
// Method "getConn" is to configure the connection to database
public Connection GetConn() {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (Exception e) {
e.printStackTrace();
}
Connection conn = null;
try {
String dbUsername = "java"; // Username
String dbPassword = "java"; // Password
// Using 103.46.128.49:50691 to form remote connection in order to run this program on other connected device
String dbUrl = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai"; // IP address, port, encoding, etc.
conn = DriverManager.getConnection(dbUrl, dbUsername, dbPassword); // Get connection
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
}
-
VcodeUtil.java
package main.Util;
import java.util.Random;
// Class "VCodeUtil" is to generate verification code
public class VCodeUtil {
public static String VerifyCode(int n) {
StringBuilder strB = new StringBuilder(); // Character splicing
Random rand = new Random();
for(int i = 0; i < n; i++) {
int r1 = rand.nextInt(3);
int r2 = 0;
switch (r1) { // Different type of characters
case 0:
r2 = rand.nextInt(10) + 48; // ASCII code value of numbers
break;
case 1:
r2 = rand.nextInt(26) + 65; // ASCII code value of uppercase letters
break;
case 2:
r2 = rand.nextInt(26) + 97; // ASCII code value of lowercase letters
break;
default:
break;
}
strB.append((char)r2); // Combine the letters into a six digit verification code
}
return strB.toString();
}
}
-
User.java
package main.Util;
// Class "User" is to access or modify data of user
public class User {
private String user_email;
private String user_password;
public User() {}
public User(String user_email, String user_password) {
this.user_email = user_email;
this.user_password = user_password;
}
public String getUser_email() {
return user_email;
}
public String getUser_password() {
return user_password;
}
public void setUser_email(String user_email) {
this.user_email = user_email;
}
public void setUser_password(String user_password) {
this.user_password = user_password;
}
}
(5)后端(DAO)
-
DAO.java:
向servlet提供了使用数据库信息的方法。其中写入了Login,Register,Exist,Logout四个方法,分别用于登录校验,注册写入,检查账户存在性,注销账户。
package main.DAO;
import main.Util.User;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Objects;
// Class "DAO" is to configure the method operating database
public class DAO {
// Method "login" is to provide data for login authentication
public User Login(Connection conn, User user) throws Exception {
User resultUser = null; // Prepare result set "resultUser"
String sql = "select * from user where user_email=? and user_password=?;";
PreparedStatement pstatement = conn.prepareStatement(sql); // Execute SQL statement
pstatement.setString(1, user.getUser_email());
pstatement.setString(2, user.getUser_password()); // Passing parameters to SQL statement
ResultSet rs = pstatement.executeQuery(); // Getting results
if (rs.next()) { // Traversing results
resultUser = new User(); // Store results to result set prepared before
resultUser.setUser_email(rs.getString("user_email"));
resultUser.setUser_password(rs.getString("user_password"));
}
return resultUser;
}
// Method "register" is to store data of user while signing up
public void Register(Connection conn, User user) throws Exception {
String sql = "insert into user(user_email,user_password) values(?,?);";
PreparedStatement pstatement = conn.prepareStatement(sql);
pstatement.setString(1, user.getUser_email());
pstatement.setString(2, user.getUser_password());
pstatement.executeUpdate();
}
// Method "Exist" is to judge whether the entered email address exists while signing up
public boolean Exist(Connection conn, User user) throws Exception {
boolean flag = false;
String sql = "select * from user;";
Statement statement = conn.createStatement();
ResultSet rs = statement.executeQuery(sql);
String input_email = user.getUser_email();
while (rs.next()) { // Traversing results from database to see if entered email address has registered
String user_email = rs.getString("user_email");
if (Objects.equals(user_email, input_email)) {
flag = true;
}
}
return flag;
}
// method "Logout" is to delete relevant user from database
public boolean Logout(Connection conn, User user) {
boolean flag = false;
try {
String sql = "delete from user where user_email=?;";
PreparedStatement pstatement = conn.prepareStatement(sql);
pstatement.setString(1, user.getUser_email());
pstatement.executeUpdate();
} catch (Exception e) {
flag = true;
}
return flag;
}
}
(6)配置文件
-
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>WebProject</display-name>
<!--Setting home page-->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!--Setting SignServlet-->
<servlet>
<servlet-name>SignServlet</servlet-name>
<servlet-class>main.Servlet.SignServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SignServlet</servlet-name>
<url-pattern>/SignServlet</url-pattern>
</servlet-mapping>
<!--Setting MailServlet-->
<servlet>
<servlet-name>EmailServlet</servlet-name>
<servlet-class>main.Servlet.EmailServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>EmailServlet</servlet-name>
<url-pattern>/EmailServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>main.Servlet.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/LogoutServlet</url-pattern>
</servlet-mapping>
</web-app>
7、系统完成形式与参考代码
文件 |
完成形式 |
参考代码(或无参考) |
index.jsp |
改写 |
[1] |
forgetPassword.jsp |
改写 |
[2] |
mainPage.jsp |
自写 |
无参考 |
styleIndex.css |
抄写(改正原代码错误) |
[1] |
styleForgetPassword.css |
仿写、自写 |
[1] |
styleMainPage.css |
自写 |
[1] |
sendEmail.js |
改写 |
[2] |
DAO.java |
自写 |
[3] |
EmailServlet.java |
改写 |
[2] |
SignServlet.java |
自写 |
[3] |
EmailUtil.java |
改写 |
[2] |
JDBCUtil.java |
仿写 |
[3] |
User.java |
自写 |
无参考 |
VCodeUtil.java |
抄写 |
[2] |
[1]利用 css 和 Javascript 实现注册登录界面Ⅰ【每天一个不会秃头的前端案例】_哔哩哔哩_bilibili
[2]第二篇参考代码丢失(该部分代码主要是一个邮箱验证码登录的子系统)文章来源:https://www.toymoban.com/news/detail-472992.html
[3]JavaWeb项目(登录注册页面)全过程详细总结文章来源地址https://www.toymoban.com/news/detail-472992.html
到了这里,关于JavaWeb登录注册系统/界面(邮箱验证码,数据库连接,详细注释,可作结课作业,可用于学习,可接入其他主系统)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!