基于JavaScript的实现网站用户登录功能 实验

1、 实验目的

掌握JDBC常用接口的使用,包括Driver接口、DriverManager类、Statement接口、PreparedStatement接口和ResultSet接口。掌握并实现JDBC程序的全过程。学习和掌握使用JDBC连接数据库,并完成对数据的增删改查。学习和掌握使用JDBC查询数据库对用户的用户名和密码进行检验,实现用户登录功能。

2、 实验所用方法

上机实践

3、 实验步骤及截图

创建一个数据库表,使用下面sql语句在MySQLworkbench插入数据。创建的名称为jdbc的数据库,然后在该数据库中创建一个tb_user表,并在tb_user表插入一条用户数据:

sql 复制代码
CREATE TABLE tb_user (
    id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,-- id主键    
    username VARCHAR(40) NOT NULL,-- 账户名称,设置不为空
    PASSWORD VARCHAR(40) NOT NULL,-- 密码,设置不为空
    NAME VARCHAR(40) DEFAULT NULL,-- 用户真实姓名,默认为空
    gender VARCHAR(20) DEFAULT NULL,-- 用户性别,默认为空
    phonenumber    VARCHAR(30) DEFAULT NULL, -- 用户手机号码,默认为空
    identitycode VARCHAR(30) DEFAULT NULL-- 用户身份证号码,默认为空
);

INSERT INTO tb_user VALUES(1,'张三','123','张三','male','13888888888','110202107075023');

在web目录下创建一个名称为login的JSP文件,在该文件中添加用于用户登录时输入用户信息的表单元素:

javascript 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录页面</title>
</head>
<style>
    * {
        margin: 0;
        padding: 0;
    }
    form {
        display: block;
        height: auto;
        width: 450px;
        margin: 100px auto;
    }
    form table tr {
        height: 40px;
    }
    form table tr td {
        height: 40px;
        width: 280px;
        line-height: 40px;
    }
    form table tr td input {
        height: 32px;
        border: 1px solid #BABABA;
        border-radius: 6px;
    }
    .alignRight {
        text-align: right;
        line-height: 40px;
        font-size: 16px;
        font-family: "Monaco";
        width: 200px;
    }
    .submit {
        display: block;
        height: 40px;
        width: 250px;
        color: white;
        font-weight: bold;
        font-size: 18px;
        background-color: #98ECAC;
        border-radius: 8px;
        margin: 15px auto;
    }
</style>
<body>
<form action="LoginServlet" method="post">
    <table>
        <tr>
            <td class="alignRight">
                Username:
            </td>
            <td>
                <input type="text" name="username" />
            </td>
        </tr>
        <tr>
            <td class="alignRight">
                Password:
            </td>
            <td>
                <input type="password" name="password" />
            </td>
        </tr>
    </table>
    <input type="submit" value="登 录" class="submit" />
</form>
</body>
</html>

由于每次操作数据库时,都需要加载数据库驱动、建立数据库连接以及关闭数据库连接,为了避免代码的重复书写,下面建立一个专门用于操作数据库的工具类。在src目录的cn.itcast包下创建一个GetConnection工具类:

javascript 复制代码
package cn.itcast;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class GetConnection {
    Connection conn = null;
    public Connection getConnection() throws ClassNotFoundException {
        String driver="com.mysql.cj.jdbc.Driver";                //驱动路径
        String url= "jdbc:mysql://localhost:3306/jdbc?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8";      //数据库地址
        String user="root";                                //访问数据库的用户名
        String password="root";                            //用户自己的密码
        Class.forName(driver);
        try {
            conn = DriverManager.getConnection(url,user,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //返回Connection对象
        return conn;
    }
}

在项目src目录的cn.itcast包下创建LoginServlet类,用于封装用户的登录信息并对用户信息进行校验:

javascript 复制代码
package cn.itcast;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
@WebServlet(name = "LoginServlet",urlPatterns = "/LoginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse
            response)throws ServletException, IOException {
        //设置请求编码、响应方式和编码方式
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        PreparedStatement ptst = null;
        //获取登录页面提交的数据
        String loginName = request.getParameter("username");
        String loginPassword = request.getParameter("password");
        //sql语句
        String selectUsername = "select username from tb_user";
        String selectPassword = "select password from tb_user where username = ?";
        try {
            //获取与数据库的链接
            conn = new GetConnection().getConnection();
            //遍历tb_user表,将数据库中所有username存入集合中
            st = conn.createStatement();
            rs = st.executeQuery(selectUsername);
            List<String> usernameList = new ArrayList<String>();
            while (rs.next()) {
                usernameList.add(rs.getString(1));
            }
            //关闭连接
            if (rs != null) {
                rs.close();
            }
            if (st != null) {
                st.close();
            }
            //判断集合中是否存在所要登录的username
            if (usernameList.contains(loginName)) {
                //查找username对应的password
                List<String> passwordList = new ArrayList<String>();
                ptst = (PreparedStatement)
                        conn.prepareStatement(selectPassword);
                //设置ptst参数
                ptst.setString(1, loginName);
                rs = ptst.executeQuery();
                while (rs.next()) {
                    passwordList.add(rs.getString(1));
                }
                //判断数据库与登录页面提交的password是否一致
                if (passwordList.get(0).equals(loginPassword)) {
                    out.println("欢迎登录。");
                } else {
                    out.println("密码错误,请重新输入。");
                }
                if (rs != null) {
                    rs.close();
                }
                if (ptst != null) {
                    ptst.close();
                }
            } else {
                out.println("用户名不存在");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //关闭链接
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        out.flush();
        out.close();
    }
}

登录网页:

4、 实验过程中出现的问题

login.jsp页面后跳转LoginServlet验证,jsp里的action路径写错了会报404的错。

5、 实验心得

通过本次实验深刻体会到JDBC在Java应用程序与数据库交互中的重要作用。

掌握了JDBC的核心接口和类后,我能够更加高效地编写数据库操作代码。也更加巩固了课堂知识:Driver接口是JDBC驱动程序的接口,每个JDBC驱动程序都必须实现该接口。尽管我们一般不会直接使用Driver接口,但了解其存在对于理解JDBC架构很重要。而DriverManager类管理一组JDBC驱动程序的基本服务。它用于建立与数据库的连接,通常通过调用DriverManager.getConnection()方法实现。Statement接口用于执行静态SQL语句并返回它所生成结果的对象。通过调用createStatement()方法从Connection对象获取。PreparedStatement接口是Statement的子接口,代表预编译的SQL语句。它主要用于执行带有参数的SQL语句,以提高安全性和性能。ResultSet接口表示数据库结果集的数据表,通过它可以前向遍历查询结果。特别是在实现用户登录功能时,深刻理解了PreparedStatement的重要性,它不仅提高了代码的安全性,还简化了SQL语句的编写过程。

在实验的过程中我也意识到了资源管理的重要性。在JDBC编程中,正确地关闭资源(如ResultSet、Statement和Connection)是防止资源泄漏的关键。通过养成在finally块中关闭资源的习惯,这样做能够确保即使在发生异常的情况下,资源也能被正确释放。

相关推荐
樱桃园园长5 分钟前
【Three.js 实战】手势控制 3D 奢华圣诞树 —— 从粒子系统到交互实现
javascript·3d·交互
二狗哈11 分钟前
Cesium快速入门30:CMZL动画
javascript·3d·webgl·cesium·地图可视化
@小白向前冲12 分钟前
数据库创表(方便自己查看)
数据库·mysql
散一世繁华,颠半世琉璃14 分钟前
高并发下的 Redis 优化:如何利用HeavyKeeper快速定位热 key
数据库·redis·缓存
咸鱼加辣23 分钟前
【前端的crud】DOM 就是前端里的“数据库”
前端·数据库
Lin_Miao_0927 分钟前
基于 DataX + DataX-Web 生成报表数据
java·数据库
一位代码28 分钟前
mysql | 复制表结构和数据
数据库·mysql
IndulgeCui28 分钟前
记一次mysql迁移至OceanBase操作记录
数据库·mysql·oceanbase
悟能不能悟33 分钟前
mybatis sql where a=#{a},如果a为null,会返回什么
数据库·sql·mybatis
l1t37 分钟前
豆包解读论文:将具有分支和循环控制流的命令式程序转换为标准SQL1999的公共表表达式
开发语言·数据库·人工智能·python·sql·postgresql·duckdb