【JavaWeb】Html、Servlet、JDBC实现页面登录
程序员文章站
2022-05-08 16:08:13
...
任务概述
任意一个项目或 APP,必不可少的就是登录模块,用户登录成功或失败,跳转到不同结果页面,现在接到组长分配的任务,需要给项目添加一个登录模块,要求贴切真实网站需求,页面有表单验证,后台连接数据库真实判断,跳转到不同页面给用户提示
具体需求
编写登录界面并进行表单验证
通过servlet将数据从客服端发送到服务器
通过java代码操作数据库,判断用户名和密码是否正确
涉及知识点
任务过程
-
创建数据库,保存用户名和密码
-
创建登录页面,要求用户输入用户名和密码
-
创建 servlet接收用户提交的用户名和密码,接收后将数据传递到数据库进行验证
-
根据验证结果,跳转到不同的结果页面(成功跳转到 success.html、失败
跳转到 false.html)
思路及代码实现
一、 工具包
创建一个utils包,新建类DBUtils,新建配置文件db.properties
properties配置文件
使用ResourceBundle访问本地资源,从里面读取我们需要的值
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工具类,封装了操作sql的方法,因此方法都推荐静态static
- 变量定义
//定义需要的工具类对象(变量定义)
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();
- 加载驱动
//加载驱动
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);
}
- 获得链接
protected static Connection getConnection() {
try {
connection = druidDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
- 得到预状态通道并绑定参数
//得到预状态通道
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();
}
}
- 增删改
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;//返回受影响的行数
}
- 数据查询
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;
}
- 关闭资源
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();
}
}
二、 创建数据库
创建数据库demo,建立表user,保存用户名和密码
三、 对象
创建一个pojo包,新建类User
User类对应的数据表user,因此类属性名 = 表字段名
User.java
- 定义属性并用setter和getter设置和获取值
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;
}
- 定义无参和全参构造方法
public User() {
}
public User(String username, String userpassword) {
this.username = username;
this.userpassword = userpassword;
}
- override toString()方法
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", userpassword='" + userpassword + '\'' +
'}';
}
四、 创建登录页面
Login.html
要求用户输入用户名和密码
- 浏览器页面主要显示
<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>
- 表单验证
<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>
- 使用外部样式
<link rel="stylesheet" href="MyCSS.css">
MyCSSss.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);
}
.box {
position: relative;
}
- 背景颜色
/* 背景颜色 */
.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;
}
- 登录框样式
/* 登录框样式 */
.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;
}
五、客户端数据发送给服务器
Web.xml
- 在Web.xml文件中添加如下内容
<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>
六、 接收客户端数据
UserServlet .java
创建一个servlet包,新建 UserServlet类,继承HttpServlet,接收客户端输入的用户名和密码
- override doPost方法接受数据
@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);
}
}
七、 数据处理
主要负责数据处理的模块
创建一个dao包,新建 Dao类,继承DBUtils类,使用 JDBC 完成相应数据库操作
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();
}
}
八、 登录结果页面
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>
完整代码如下
一、 工具包
properties配置文件
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();
}
}
}
二、 对象
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 + '\'' +
'}';
}
}
三、 创建登录页面
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;
}
四、客户端数据发送给服务器
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>
五、 接收客户端数据
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);
}
}
}
六、 数据处理
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();
}
}
}
七、 登录结果页面
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>
下一篇: 中文*实现简繁转换_其他工具_软件教程
推荐阅读
-
JavaWeb商城项目(Day05)Web层(登录页面的html+Servlet程序)
-
jsp+java servlet实现简单用户登录和注册页面(连接数据库,登录页面包含验证码,两周内免登陆等功能)
-
JavaWeb Servlet实现网页登录功能
-
JDBC数据库访问与Servlet实现简单登录界面
-
HTML+jQuery实现简单的登录页面
-
JavaWeb01_HTML+CSS实现注册页面
-
jQuery Ajax 实现在html页面实时显示用户登录状态
-
【JavaWeb】Html、Servlet、JDBC实现页面登录
-
【JavaWeb】用Servlet实现用户登录/注册
-
【javaweb:servlet】采用重定向实现页面跳转