Article directory
Mission overview
For any project or APP, a login module is indispensable. If the user logs in successfully or fails, he will jump to different result pages. Now that he has received a task assigned by the team leader, he needs to add a login module to the project, which must meet the needs of the real website. The page has form verification, the background connects to the database for true judgment, and jumps to different pages to give users prompts.
specific requirement
Write login interface and perform form verification
Send data from client to server through servlet
Operate the database through java code to determine whether the user name and password are correct
Involving knowledge points
1. SQL language and basic operations
2. JDBC (Java Database Connection)
3. Use of custom tool classes and properties configuration files
5. Servlet working principle and life cycle
6. Servlet request and response
Task process
-
Create a database and save username and password
-
Create a login page that requires users to enter their username and password
-
Create a servlet to receive the user name and password submitted by the user, and then pass the data to the database for verification.
-
According to the verification results, jump to different result pages (successfully jump to success.html, failure
jump to false.html)
Ideas and code implementation
1. Toolkit
Create a utils package, create a new class DBUtils, and create a new configuration file db.properties
properties configuration file
Use ResourceBundle to access local resources and read the values we need from them
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT
username=root
password=123456
DBUtils.java
JDBC tool class encapsulates methods for operating sql, so static methods are recommended.
- Variable definitions
//定义需要的工具类对象(变量定义)
protected static Connection connection = null;
protected static PreparedStatement pps = null;//后续都是用预状态通道来实现
protected static ResultSet rs = null;//结果集
protected static int count = 0;//受影响的行数
//登录的用户名和密码
private static String username;
private static String password;
private static String url;
private static String driverName;
//Druid连接池
private static DruidDataSource druidDataSource = new DruidDataSource();
- Load driver
//加载驱动
static {
//Druid
ResourceBundle bundle = ResourceBundle.getBundle("db");//参数只写属性文件名,不需要写后缀
//加载属性文件
driverName = bundle.getString("driver");
url = bundle.getString("url");
username = bundle.getString("username");
password = bundle.getString("password");
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
druidDataSource.setUrl(url);
druidDataSource.setDriverClassName(driverName);
}
- get link
protected static Connection getConnection() {
try {
connection = druidDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
- Get the pre-state channel and bind parameters
//得到预状态通道
protected static PreparedStatement getPps(String sql) {
try {
getConnection();
pps = connection.prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return pps;
}
//绑定参数,给占位符赋值,list中保存的是给占位符所赋的值
private static void setParams(List list) {
try {
if (list != null && list.size() > 0) {
//集合中有内容
for (int i = 0; i < list.size(); i++) {
pps.setObject(i + 1, list.get(i));//赋值,位置从1开始所以为i+1
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
- addition, deletion, modification
protected static int update(String sql, List list) {
try {
getPps(sql);//得到预状态通道
setParams(list);//绑定参数
count = pps.executeUpdate();//pps.executeUpdate()执行sql语句,返回受影响的行数
} catch (SQLException e) {
e.printStackTrace();
}
return count;//返回受影响的行数
}
- data query
protected static ResultSet query(String sql, List list) {
try {
getPps(sql);//得到预状态通道
setParams(list);//绑定参数
rs = pps.executeQuery();//pps.executeUpdate()执行sql语句,返回结果集
return rs;//返回结果集
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
- Close resource
protected static void closeAll() {
try {
if (rs != null) {
rs.close();
}
if (pps != null) {
pps.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
2. Create database
Create a database demo, create the table user, and save the user name and password
3. Object
Create a pojo package and create a new class User
The data table user corresponding to the User class, thereforeClass attribute name = table field name
User.java
- Define properties and set and get values with setters and getters
private String username;
private String userpassword;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpassword() {
return userpassword;
}
public void setUserpassword(String userpassword) {
this.userpassword = userpassword;
}
- Define no-parameter and full-parameter constructors
public User() {
}
public User(String username, String userpassword) {
this.username = username;
this.userpassword = userpassword;
}
- override toString() method
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", userpassword='" + userpassword + '\'' +
'}';
}
4. Create a login page
Login.html
Ask the user to enter their username and password
- The browser page mainly displays
<body>
<section>
<div class="box">
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="container">
<div class="form">
<h2>用户登录</h2><br />
<form action="test" method="post"><!--使用post发送数据给服务器-->
<div>
<input id="name" class="inputStyle" name="username" type="text" placeholder="用户名" onblur="validateName()"/>
</div>
<span id="nameMsg"></span>
<div>
<input class="inputStyle" name="userpassword" type="password" placeholder="密码"/>
</div>
<div>
<input class="buttomStyle" type="submit" value="登录" />
</div>
</form>
</div>
</div>
</div>
</section>
</body>
- form validation
<script>
function validateName(){
var name = document.getElementById("name").value;
var msg = document.getElementById("nameMsg");
var reg = /^[\u4E00-\u9FA5]{2,4}$/;
var res = reg.test(name);
if(name == null || name == ""){
msg.innerHTML = "用户名不能为空";
msg.style.color = "red";
return false;
}else if(res == false){
msg.innerHTML = "用户名格式错误";
msg.style.color = "red";
return false;
}
return true;
}
</script>
- Use external styles
<link rel="stylesheet" href="MyCSS.css">
MyCSSss.css
- Overall location of the login interface
/**
* 显示水平居中
*/
section {
position: relative;
overflow: hidden;
display: flex; /*垂直居中对齐*/
justify-content: center;
align-items: center;
min-height: 100vh;
/* linear-gradient() 函数用于创建一个表示两种或多种颜色线性渐变的图片 */
background: linear-gradient(to bottom, #f1f4f9, #dff1ff);
}
.box {
position: relative;
}
- background color
/* 背景颜色 */
.color {
/* 绝对定位 */
position: absolute;
/* 使用filter(滤镜) 属性,给图像设置高斯模糊*/
filter: blur(200px);
}
/* :nth-child(n) 选择器匹配父元素中的第 n 个子元素 */
.color:nth-child(1) {
top: -350px;
width: 600px;
height: 600px;
background:#FFC0CB;
}
.color:nth-child(2) {
bottom: -150px;
left: 100px;
width: 500px;
height: 500px;
background: #FFFFE0;
}
.color:nth-child(3) {
bottom: 50px;
right: 100px;
width: 500px;
height: 500px;
background:#DDA0DD;
}
.color:nth-child(4) {
bottom: 50px;
right: 100px;
width: 500px;
height: 500px;
background:#FFFFFF;
}
- Login box style
/* 登录框样式 */
.container {
position: relative;
width: 400px;
min-height: 400px;
background: rgba(255, 255, 255, 0.1);
display: flex;
justify-content: center;
align-items: center;
backdrop-filter: blur(5px);
box-shadow: 0 25px 45px rgba(0, 0, 0, 0.1);
border: 1px solid rgba(255, 255, 255, 0.5);
border-right: 1px solid rgba(255, 255, 255, 0.2);
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}
- Input box style
/* 输入框样式 */
.inputStyle{
width: 100%;
padding: 10px 20px;
margin-top: 20px;
background: rgba(255, 255, 255, 0.2);
outline: none;
border: none;
border-radius: 30px;
border: 1px solid rgba(255, 255, 255, 0.5);
border-right: 1px solid rgba(255, 255, 255, 0.2);
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
font-size: 16px;
letter-spacing: 1px;
color: #000;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
}
- Login button style
/* 登录按钮样式 */
.buttomStyle{
width: 100%;
padding: 10px 20px;
max-width: 100px;
margin-top: 30px;
margin-left: 10px;
margin-bottom: 20px;
border-radius: 30px;
font-size: 16px;
letter-spacing: 1px;
background: #fff;
color: #666;
font-weight: 600;
cursor: pointer;
}
5. Client data is sent to the server
Web.xml
- Add the following content to the Web.xml file
<servlet>
<servlet-name>a1</servlet-name><!--名称-->
<servlet-class>
servlet.UserServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>a1</servlet-name><!--映射的名称-->
<url-pattern>/test</url-pattern><!--<form action="test" method="post">-->
</servlet-mapping>
6. Receive client data
UserServlet .java
Create a servlet package, create a new UserServlet class, inherit HttpServlet, and receive the user name and password entered by the client.
- override doPost method accepts data
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
//取值
String username = req.getParameter("username");
System.out.println("用户输入的用户名:"+username);
String userpassword = req.getParameter("userpassword");
System.out.println("用户输入的密码:"+userpassword);
if(dao.checkLogin(username,userpassword)){
System.out.println("登陆成功");
resp.sendRedirect("/Success.html");
//req.getRequestDispatcher("/Success.html").forward(req,resp);
}else{
System.out.println("登录失败");
resp.sendRedirect("/Fail.html");
//req.getRequestDispatcher("/fail.html").forward(req,resp);
}
}
7. Data processing
Module mainly responsible for data processing
Create a dao package, create a new Dao class, inherit the DBUtils class, and use JDBC to complete the corresponding database operations
Dao.java
public boolean checkLogin(String username,String password){
System.out.println("进入check in");
String sql = "select* from user where username = ? and userpassword = ?";
ArrayList param = new ArrayList();
param.add(username);
param.add(password);
ResultSet query = query(sql, param);
try {
if(!query.next()){
System.out.println("dao:false");
return false;
}else{
User user = new User();
user.setUsername(query.getString("username"));
user.setUserpassword(query.getString("userpassword"));
System.out.println("dao:true");
return true;
}
} catch (SQLException throwables) {
System.out.println(throwables.getMessage());
return false;
}finally {
closeAll();
}
}
8. Login result page
Success.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登陆成功</title>
<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<link rel="stylesheet" href="css/bootstrap.css" />
<link rel="stylesheet" href="MyCSS.css">
</head>
<body>
<section>
<div class="box">
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="container">
<div>
<h2 style="color:#FF69B4">登陆成功</h2>
</div>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="40"
aria-valuemin="0" aria-valuemax="100" style="width: 60%;">
</div>
</div>
</div>
</div>
</section>
</body>
</html>
Fail.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录失败</title>
<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<link rel="stylesheet" href="css/bootstrap.css" />
<link rel="stylesheet" href="MyCSS.css">
</head>
<body>
<section>
<div class="box">
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="container">
<div>
<h2 style="color:#DC143C">用户名or密码错误,登录失败!</h2>
</div>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="40"
aria-valuemin="0" aria-valuemax="100" style="width: 60%;">
</div>
</div>
</div>
</div>
</section>
</body>
</html>
The complete code is as follows
1. Toolkit
properties configuration file
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT
username=root
password=123456
DBUtils.java
public class DBUtils {
//1.定义需要的工具类对象(变量定义)
protected static Connection connection = null;
protected static PreparedStatement pps = null;//后续都是用预状态通道来实现
protected static ResultSet rs = null;//结果集
protected static int count = 0;//受影响的行数
//登录的用户名和密码
private static String username;
private static String password;
private static String url;
private static String driverName;
//Druid
private static DruidDataSource druidDataSource = new DruidDataSource();
//2.加载驱动
static {
//Druid
ResourceBundle bundle = ResourceBundle.getBundle("db");//参数只写属性文件名,不需要写后缀
//加载属性文件
driverName = bundle.getString("driver");
url = bundle.getString("url");
username = bundle.getString("username");
password = bundle.getString("password");
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
druidDataSource.setUrl(url);
druidDataSource.setDriverClassName(driverName);
}
//3.获得连接
protected static Connection getConnection() {
try {
connection = druidDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
//4.得到预状态通道
protected static PreparedStatement getPps(String sql) {
try {
getConnection();//insert into users values(?,?,?,?,)
pps = connection.prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return pps;
}
//5.绑定参数,给占位符赋值,list中保存的是给占位符所赋的值
private static void setParams(List list) {
try {
if (list != null && list.size() > 0) {
//集合中有内容
for (int i = 0; i < list.size(); i++) {
pps.setObject(i + 1, list.get(i));//赋值,位置从1开始所以为i+1
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//6.增删改
protected static int update(String sql, List list) {
try {
getPps(sql);//得到预状态通道
setParams(list);//绑定参数
count = pps.executeUpdate();//pps.executeUpdate()执行sql语句,返回受影响的行数
} catch (SQLException e) {
e.printStackTrace();
}
return count;//返回受影响的行数
}
//7.查询
protected static ResultSet query(String sql, List list) {
try {
getPps(sql);//得到预状态通道
setParams(list);//绑定参数
rs = pps.executeQuery();//pps.executeUpdate()执行sql语句,返回结果集
return rs;//返回结果集
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
//8.关闭资源
protected static void closeAll() {
try {
if (rs != null) {
rs.close();
}
if (pps != null) {
pps.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
2. Object
User.java
public class User {
private String username;
private String userpassword;
public User() {
}
public User(String username, String userpassword) {
this.username = username;
this.userpassword = userpassword;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpassword() {
return userpassword;
}
public void setUserpassword(String userpassword) {
this.userpassword = userpassword;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", userpassword='" + userpassword + '\'' +
'}';
}
}
3. Create a login page
Login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<link rel="stylesheet" href="MyCSS.css">
<script>
function validateName(){
var name = document.getElementById("name").value;
var msg = document.getElementById("nameMsg");
var reg = /^[\u4E00-\u9FA5]{2,4}$/;
var res = reg.test(name);
if(name == null || name == ""){
msg.innerHTML = "用户名不能为空";
msg.style.color = "red";
return false;
}else if(res == false){
msg.innerHTML = "用户名格式错误";
msg.style.color = "red";
return false;
}
return true;
}
</script>
</head>
<body>
<section>
<div class="box">
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="container">
<div class="form">
<h2>用户登录</h2><br />
<form action="test" method="post">
<div>
<input id="name" class="inputStyle" name="username" type="text" placeholder="用户名" onblur="validateName()"/>
</div>
<span id="nameMsg"></span>
<div>
<input class="inputStyle" name="userpassword" type="password" placeholder="密码"/>
</div>
<div>
<input class="buttomStyle" type="submit" value="登录" />
</div>
</form>
</div>
</div>
</div>
</section>
</body>
</html>
MyCss.css
/**
* 显示水平居中
*/
section {
position: relative;
overflow: hidden;
display: flex; /*垂直居中对齐*/
justify-content: center;
align-items: center;
min-height: 100vh;
/* linear-gradient() 函数用于创建一个表示两种或多种颜色线性渐变的图片 */
background: linear-gradient(to bottom, #f1f4f9, #dff1ff);
}
/* 背景颜色 */
.color {
/* 绝对定位 */
position: absolute;
/* 使用filter(滤镜) 属性,给图像设置高斯模糊*/
filter: blur(200px);
}
/* :nth-child(n) 选择器匹配父元素中的第 n 个子元素 */
.color:nth-child(1) {
top: -350px;
width: 600px;
height: 600px;
background:#FFC0CB;
}
.color:nth-child(2) {
bottom: -150px;
left: 100px;
width: 500px;
height: 500px;
background: #FFFFE0;
}
.color:nth-child(3) {
bottom: 50px;
right: 100px;
width: 500px;
height: 500px;
background:#DDA0DD;
}
.color:nth-child(4) {
bottom: 50px;
right: 100px;
width: 500px;
height: 500px;
background:#FFFFFF;
}
.box {
position: relative;
}
/* 登录框样式 */
.container {
position: relative;
width: 400px;
min-height: 400px;
background: rgba(255, 255, 255, 0.1);
display: flex;
justify-content: center;
align-items: center;
backdrop-filter: blur(5px);
box-shadow: 0 25px 45px rgba(0, 0, 0, 0.1);
border: 1px solid rgba(255, 255, 255, 0.5);
border-right: 1px solid rgba(255, 255, 255, 0.2);
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}
/* 输入框样式 */
.inputStyle{
width: 100%;
padding: 10px 20px;
margin-top: 20px;
background: rgba(255, 255, 255, 0.2);
outline: none;
border: none;
border-radius: 30px;
border: 1px solid rgba(255, 255, 255, 0.5);
border-right: 1px solid rgba(255, 255, 255, 0.2);
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
font-size: 16px;
letter-spacing: 1px;
color: #000;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
}
/* 登录按钮样式 */
.buttomStyle{
width: 100%;
padding: 10px 20px;
max-width: 100px;
margin-top: 30px;
margin-left: 10px;
margin-bottom: 20px;
border-radius: 30px;
font-size: 16px;
letter-spacing: 1px;
background: #fff;
color: #666;
font-weight: 600;
cursor: pointer;
}
4. Client data is sent to the server
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">
<servlet>
<servlet-name>a1</servlet-name>
<servlet-class>
com.company.project.t010601.servlet.UserServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>a1</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
</web-app>
5. Receive client data
UserServlet .java
public class UserServlet extends HttpServlet {
Dao dao = new Dao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//HttpSession session = req.getSession();
req.setCharacterEncoding("utf-8");
//取值
String username = req.getParameter("username");
System.out.println("用户输入的用户名:"+username);
String userpassword = req.getParameter("userpassword");
System.out.println("用户输入的密码:"+userpassword);
if(dao.checkLogin(username,userpassword)){
System.out.println("登陆成功");
resp.sendRedirect("/Success.html");
//req.getRequestDispatcher("/Success.html").forward(req,resp);
}else{
System.out.println("登录失败");
resp.sendRedirect("/Fail.html");
//req.getRequestDispatcher("/fail.html").forward(req,resp);
}
}
}
6. Data processing
Dao.java
public class Dao extends DBUtil {
public boolean checkLogin(String username,String password){
System.out.println("进入check in");
String sql = "select* from user where username = ? and userpassword = ?";
ArrayList param = new ArrayList();
param.add(username);
param.add(password);
ResultSet query = query(sql, param);
try {
if(!query.next()){
System.out.println("dao:false");
return false;
}else{
User user = new User();
user.setUsername(query.getString("username"));
user.setUserpassword(query.getString("userpassword"));
System.out.println("dao:true");
return true;
}
} catch (SQLException throwables) {
System.out.println(throwables.getMessage());
return false;
}finally {
closeAll();
}
}
}
7. Login result page
Success.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登陆成功</title>
<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<link rel="stylesheet" href="css/bootstrap.css" />
<link rel="stylesheet" href="MyCSS.css">
</head>
<body>
<section>
<div class="box">
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="container">
<div>
<h2 style="color:#FF69B4">登陆成功</h2>
</div>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="40"
aria-valuemin="0" aria-valuemax="100" style="width: 60%;">
</div>
</div>
</div>
</div>
</section>
</body>
</html>
Fail.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录失败</title>
<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<link rel="stylesheet" href="css/bootstrap.css" />
<link rel="stylesheet" href="MyCSS.css">
</head>
<body>
<section>
<div class="box">
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="container">
<div>
<h2 style="color:#DC143C">用户名or密码错误,登录失败!</h2>
</div>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="40"
aria-valuemin="0" aria-valuemax="100" style="width: 60%;">
</div>
</div>
</div>
</div>
</section>
</body>
</html>