任务 G:用户管理

本文档详述了用户管理任务的技术训练营内容,包括用户注册、登录、用户列表展示、用户详情编辑、冻结账户等功能的实现。技术上,使用Redis保存验证码,涉及Servlet、JSP、DAO等多个组件。开发过程中解决了404错误、验证码显示、SQL语句等问题,完善了用户编辑、冻结逻辑,实现了头像上传和分页展示等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

技术训练营- - 任务 G :用户管理

用户注册、登录,注册时需要填写姓名、性别、手机号、身份证号、年龄、现住址、工作单位等个人信息;

任务内容

功能要求包括:

  1. 用户注册、登录,注册时需要填写姓名、性别、手机号、身份证号、年龄、现住址、工作单位等个人信息;
  2. 可以通过手机号注册,也可以通过验证码注册(验证码由单独的页面显示,注册前就需要生成并,然后访问该页面获得验证码并用于注册);
  3. 在首页可以查看全部用户列表(带分页),可以点击某位用户的名字查看其详情,可以冻结用户帐户,被冻结后的用户无法登录(系统给出提示或返回账户被冻结页面);
  4. 可编辑用户详情,上传用户头像并保存;
  5. 用户还包括积分、余额、卡券等附属资产信息,这些数据要通过单独的页面访问,并且也可以编辑后保存;
  6. admin 用户为管理员,该用户信息不可编辑、不可禁用,也不显示在用户列表中。

技术要求包括:

  1. 通过 Redis 保存用户注册验证码,失效时间为 15 分钟;
  2. 用户注册完毕后,需要登录才能进入首页;
  3. 登录时需要图片验证码,通过 Redis 保存,失效时间为 5 分钟,图片验证码示例:

工作日志

  1. 创建 User 类, 类中包含用户的 姓名、性别、手机号、身份证号、年龄、现住址、工作单位等个人信息的字段。
  2. 创建 UserDAO 类,类中包含各种对数据库的的方法,包括:初始化(测试用)、与数据库连接、添加用户、编辑用户、展示用户列表的方法。
  3. 创建 UserEditServlet 类、UserListPage.jsp 列表页面、UserEditPage.jsp编辑页面以及相应的结果:Edit_Fail.jspEdit_Success.jsp
  4. 遇到了神秘的 404 错误,花了很久时间来解决。
  5. User 类、UserDAO 类中相应方法、添加了 积分、余额、卡券 三个字段。
  6. 创建了 UserDetailEditServlet 类、UserDetailList 详情展示页面、 UserDetailEditPage 详情编辑页面以及相应的结果: EditDetail_Success.jspEditDetail_Fail.jsp ,在UserDAO类中添加详情展示的方法 userDetailEdit、详情编辑的方法 userDetailEdit
  7. 在初始化语句中,添加了 admin 账户,该用户不会在展示页面出现。
  8. User 类、 UserDAO 类中的响应方法、添加了 密码 字段。
  9. 添加密码字段后,出现 sql 语句报错。
  10. 创建 UserRegServlet 类,UserReg.html 注册页面,以及相应的结果页面:Reg_Fail.jspReg_Success.jsp实现了注册功能
  11. 发现用户列表页面不能点击用户名跳转至编辑界面,修复成功,实现了用户基础信息编辑的功能
  12. 更正了编辑用户信息页面的一个显示错误。
  13. 修复了编辑用户信息页面的输入栏没有预设值的问题。
  14. 修复了编辑用户信息页面中身份证预设值为 null 的问题。
  15. 完成了UserDAO里的冻结方法。
  16. 完善了 UserList 中的冻结按钮。
  17. 给 SQL的密码字段添加了默认值。
  18. 修复了性别栏没有勾选选项的问题。
  19. 添加了一个 UserInitServlet 类,并且在主页添加了一个调用这个 Servlet 的按钮。效果为点击之后会初始化数据库,方便测试。
  20. 修改了UserDAO 类中的注册、列表方法,(跟 uid 有关)。
  21. 解决了基本信息编辑页面的一个无法读取到 uid 的错误。
  22. 解决了 UserDAO 类中,编辑用户的方法的 sql 语法问题。
  23. 创建了 UserLoginServlet 类、UserLogin.jsp ,在UserDAO 类中添加了 login 方法。添加了两个相应的登录结果 Login_Success.jspLogin_Fail.jsp
  24. 在主页添加了一个按钮,点击之后跳转到登录界面。
  25. 修复了在登录界面点击登录按钮没有反应的问题。
  26. 在登录结果页面添加了返回登录界面的按钮。
  27. 调整了整个登录逻辑的页面显示问题(例如换行)。
  28. 修复了登录处理逻辑上的一个漏洞(sql 语句问题)。
  29. 给登录结果页面增加了一个显示登录用户用户名的欢迎页面。
  30. 修复了登录结果页面无法获取到用户名的问题,现在登录页面可以正常显示登录用户的用户名了。
  31. 修改了UserDAO中的 userLogin方法,添加冻结判定。
  32. 修复了冻结用户时会报错的问题。
  33. 修复了登录已冻结用户时仍可正常登录的问题。
  34. 修复了用户基本信息页面的跳转到详情页按钮无法正常工作的问题。
  35. 优化了详情展示页的处理逻辑。点击用户详情按钮后会先展示详情列表,点击列表下方的按钮会跳转至详情编辑列表。
  36. 在详情编辑列表里添加了提交按钮。
  37. 在详情编辑列表里添加了用户名,使编辑过程更加直观。
  38. UserDAO 中添加了 userDetailList 方法,用于从数据库中获取用户的详情(积分、余额、卡券)。
  39. 详情编辑页面添加一个按钮,点击后跳转至该用户的详情编辑页面。
  40. 修复了详情编辑编辑页面无法获取到用户信息的问题。
  41. 修复了详情页面的个人信息错位的问题。
  42. 修复了详情编辑页面提交按钮跳转地址有误的问题。
  43. 修复了详情编辑页面无法正确获取到用户名的问题。
  44. 给详情编辑页面的 uid 和用户名添加了只读属性。
  45. 修改了详情编辑的结果页面中,返回按钮的跳转地址。至此,详情编辑功能成功实现
  46. pom.xml 文件中添加了 commons-fileupload 依赖,用于上传图像。
  47. 更新了 servlet 的依赖(原来的 servlet 版本不对)。
  48. 在项目模块中添加了 jsmart 的配置。
  49. 修改项目模块中的 jsmart 配置文件,并且在 tomcat 的 lib 目录下 穆现在上传图片时不会再出现 classnotfound 的错误了。
  50. 找到了上传后图片的储存位置。
  51. 调整了代码,现在图片上传界面不会再有一个用户uid的输入框,已经将它设置为隐藏。虽然已经将它设为不可编辑,但是没必要显示出来。
  52. 添加了 code.jsp 文件,用于展示验证码。
  53. 修复了无法正常显示验证码的问题,原因为某些函数未定义。
  54. code.jsp 添加了refresh 函数,用于刷新验证码。
  55. code.jsp 中添加了判断输入的账号密码是否为空的函数。
  56. 删除了 code.jsp 的一行代码,解决了一个验证码显示的 bug ,但还是无法正常显示验证码。
  57. 修改了 code.jsp 中的一个方法,解决了验证码显示的 bug ,现在已经可以正常显示验证码了。
  58. UserReg.html 删掉了,用 UserReg.jsp 代替,跟其他页面统一。
  59. UserReg.jsp 中添加了关于验证码的判定。
  60. 修复了验证码错误时不会弹窗报错的漏洞。
  61. 修复验证码错误弹窗时无法正常显示中文的问题。

项目代码

DAO

UserDAO

提供数据库的相关操作方法

package com.xxm;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: xxm
 * @Date: 2021/12/1 19:49
 * UserDAO 类,类中包含各种对数据库操作的方法
 */
public class UserDAO {
   


    /**
     * 方法 0:initTable
     * 方法用作测试,完成前记得删掉!
     * 作用为:如果表 userTable 存在,则将其删掉,并重新创建
     */
    public void initTable() {
   

        //连接数据库、执行 sql 语句
        try {
   
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
   
            e.printStackTrace();
        }

        //初始化的 sql 语句,如果表存在则 DROP ,不存在则创建
        String sql1 = "DROP TABLE IF EXISTS userTable;";

        //创建表的 sql 语句
        String sql2 =
                "CREATE TABLE userTable ( \n" +
                        "uid INT(32) NOT NULL AUTO_INCREMENT,\n" +
                        "username VARCHAR(32) NOT NULL,\n" +
                        "password VARCHAR(32) NOT NULL DEFAULT '123456',\n" +
                        "gender CHAR(4) NOT NULL,\n" +
                        "id CHAR(18) NOT NULL,\n" +
                        "phone CHAR(11) NOT NULL,\n" +
                        "age INT(4) NOT NULL,\n" +
                        "address VARCHAR(32) NOT NULL,\n" +
                        "company VARCHAR(32) NOT NULL,\n" +
                        "freeze BOOLEAN,\n" +
                        "points INT(16),\n" +
                        "balance INT(32),\n" +
                        "coupon VARCHAR(32),\n" +
                        "PRIMARY KEY(uid)\n)" +
                        ";";

        //插入几个初始数据的 sql 语句
        String sql3 = "INSERT INTO userTable(uid,username,gender,id,phone,age,address,company)\n" +
                "VALUES\n" +
                "(1,'admin','管理员','123456199645451088','13512345678',0,'管理','管理'),\n" +
                "(2,'张飞','男','123456199645451088','13512345678',34,'燕','蜀'),\n" +
                "(3,'刘备','男','123456199254510882','13512325478',36,'成都','蜀'),\n" +
                "(4,'张辽','男','123436199254854828','18823254738',35,'逍遥津','魏'),\n" +
                "(5,'貂蝉','女','123456788932135545','13512342234',24,'洛阳','东汉')\n" +
                ";\n";

        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/study?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai", "root", "root");
             PreparedStatement pstmt = conn.prepareStatement(sql1)) {
   
            pstmt.execute(sql1);
            pstmt.execute(sql2);
            pstmt.execute(sql3);
        } catch (SQLException e) {
   
            e.printStackTrace();
        }
    }


    /**
     * 方法 1:
     * getConnection 方法,作用为与数据库取得连接。可以起到简化代码的作用
     * 与数据库连接的方法,返回 Connection 对象
     */
    public Connection getConnection() throws SQLException {
   
        try {
   
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
   
            e.printStackTrace();
        }
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/study?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai", "root", "root");
    }


    /**
     * 方法 2:
     * addUser 方法,其作用为将 User 对象的数据(姓名、性别、手机号、身份证号、年龄、现住址、工作单位)保存至数据库
     * 在数据前面还加了一个 uid ,作为用户的标识符。
     * 根据添加结果,返回一个布尔值,servlet 再根据这个布尔值决定跳转至相应的页面。
     */
    public boolean addUser(User user) throws Exception {
   
        //定义 sql 语句
        String sql = "INSERT INTO userTable (uid,username,gender,phone,id,age,address,company) VALUES (0,?,?,?,?,?,?,?)";

        //连接数据库、执行 sql 语句
        Class.forName("com.mysql.cj.jdbc.Driver");

        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
   
            pstmt.setString(1, user.getUsername());
            pstmt.setString(2, user.getGender());
            pstmt.setString(3, user.getPhone());
            pstmt.setString(4, user.getId());
            pstmt.setInt(5, user.getAge());
            pstmt.setString(6, user.getAddress());
            pstmt.setString(7, user.getCompany());

            int num = pstmt.executeUpdate();
            if (num != 0) {
   
                System.out.println("注册成功");
                return true;
            } else {
   
                return false;
            }
        } catch (SQLException e) {
   
            System.out.println("注册失败,账号已存在");
            return false;
        }
    }


    /**
     * 方法 3:
     * userEdit 方法,作用为,编辑用户信息
     * uid 是要编辑的用户的 uid,
     * 其他传入参数是用户输入的信息。
     */
    public int editUser(int uid, String username, String gender, String phone, String id, int age, String address, String company) {
   
        //定义 sql 语句,用占位符标记,方便接收要修改的数据
        int number = 0;
        String sql = "UPDATE userTable SET username = ?, gender = ?, phone = ?, id = ?, age = ?, address = ?, company = ? WHERE uid = ?";

        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
   

            pstmt.setString(1, username);
            pstmt.setString(2, gender);
            pstmt.setString(3, phone);
            pstmt.setString(4, id);
            pstmt.setInt(5, age);
            pstmt.setString(6, address);
            pstmt.setString(7, company);
            pstmt.setInt(8, uid);

            number = pstmt.executeUpdate();

        } catch (Exception e) {
   
            e.printStackTrace();
        }
        return number;
    }


    /**
     * 方法 4:
     * userList 方法,作用为:获取一个 List,里面有数据库里的所有用户的数据的所有的 User 类对象的基本信息。
     */
    public List<User> userList() {
   
        List<User> users = new ArrayList<>();

        //定义 sql 语句, uid 为 1 的用户是管理员用户 admin,因此将其排除在展示列表外
        String sql = "SELECT username,gender,phone,id,age,address,company,uid FROM userTable WHERE uid != 1";

        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
   
            ResultSet rs = pstmt.executeQuery();

            while (rs.next()) {
   
                User user = new User();
                user.setUsername(rs.getString(1));
                user.setGender(rs.getString(2));
                user.setPhone(rs.getString(3));
                user.setId(rs.getString(4));
                user.setAge(rs.getInt(5));
                user.setAddress(rs.getString(6));
                user.setCompany(rs
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值