当前位置: 首页 > news >正文

JSP实战:从零构建用户管理模块

1. 环境准备与项目搭建

在开始构建用户管理模块前,我们需要准备好开发环境。这里推荐使用IntelliJ IDEA作为开发工具,配合Tomcat 9+作为Web服务器,MySQL 5.7+作为数据库。如果你还没有安装这些软件,可以到官网下载最新版本。

首先创建一个新的Maven Web项目,在pom.xml中添加必要的依赖:

<dependencies> <!-- Servlet API --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <!-- JSTL --> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency> <!-- MySQL Connector --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.25</version> </dependency> </dependencies>

接下来创建项目的基本目录结构:

src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── example/ │ │ ├── bean/ # 实体类 │ │ ├── dao/ # 数据访问层 │ │ └── servlet/ # Servlet控制器 │ ├── resources/ # 配置文件 │ └── webapp/ │ ├── WEB-INF/ │ │ └── web.xml # Web应用配置 │ ├── css/ # 样式表 │ ├── js/ # JavaScript │ └── jsp/ # JSP页面

2. 数据库设计与实现

用户管理模块的核心是数据库设计。我们创建一个简单的用户表,包含基本字段:

CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `password` varchar(100) NOT NULL, `email` varchar(100) NOT NULL, `phone` varchar(20) DEFAULT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP, `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `username_UNIQUE` (`username`), UNIQUE KEY `email_UNIQUE` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

为了简化数据库操作,我们创建一个DBUtil工具类:

public class DBUtil { private static final String URL = "jdbc:mysql://localhost:3306/user_management?useSSL=false"; private static final String USER = "root"; private static final String PASSWORD = "123456"; public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } public static void close(Connection conn, Statement stmt, ResultSet rs) { try { if (rs != null) rs.close(); if (stmt != null) stmt.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }

3. 用户实体与DAO层实现

创建User实体类,对应数据库中的users表:

public class User { private Integer id; private String username; private String password; private String email; private String phone; private Date createTime; private Date updateTime; // 省略getter和setter方法 }

接着实现UserDAO类,封装对用户表的CRUD操作:

public class UserDAO { public List<User> getAllUsers() throws SQLException { List<User> users = new ArrayList<>(); Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = DBUtil.getConnection(); String sql = "SELECT * FROM users"; stmt = conn.prepareStatement(sql); rs = stmt.executeQuery(); while (rs.next()) { User user = new User(); user.setId(rs.getInt("id")); user.setUsername(rs.getString("username")); user.setEmail(rs.getString("email")); user.setPhone(rs.getString("phone")); user.setCreateTime(rs.getTimestamp("create_time")); user.setUpdateTime(rs.getTimestamp("update_time")); users.add(user); } } finally { DBUtil.close(conn, stmt, rs); } return users; } public User getUserById(int id) throws SQLException { // 类似getAllUsers的实现 } public boolean addUser(User user) throws SQLException { // 实现添加用户逻辑 } public boolean updateUser(User user) throws SQLException { // 实现更新用户逻辑 } public boolean deleteUser(int id) throws SQLException { // 实现删除用户逻辑 } }

4. 用户列表展示功能

创建AllUsersServlet处理用户列表请求:

@WebServlet("/users") public class AllUsersServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { UserDAO userDAO = new UserDAO(); List<User> users = userDAO.getAllUsers(); request.setAttribute("users", users); request.getRequestDispatcher("/jsp/user_list.jsp").forward(request, response); } catch (SQLException e) { throw new ServletException("Database error", e); } } }

对应的JSP页面(user_list.jsp):

<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>用户列表</title> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> </head> <body> <h1>用户列表</h1> <table> <tr> <th>ID</th> <th>用户名</th> <th>邮箱</th> <th>电话</th> <th>创建时间</th> <th>操作</th> </tr> <c:forEach items="${users}" var="user"> <tr> <td>${user.id}</td> <td>${user.username}</td> <td>${user.email}</td> <td>${user.phone}</td> <td>${user.createTime}</td> <td> <a href="user_detail?id=${user.id}">查看</a> <a href="edit_user?id=${user.id}">编辑</a> <a href="delete_user?id=${user.id}" onclick="return confirm('确定删除该用户吗?')">删除</a> </td> </tr> </c:forEach> </table> <a href="add_user">添加用户</a> </body> </html>

5. 用户详情查看功能

创建ShowUserServlet处理用户详情请求:

@WebServlet("/user_detail") public class ShowUserServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String idStr = request.getParameter("id"); if (idStr == null || idStr.isEmpty()) { response.sendRedirect("users"); return; } try { int id = Integer.parseInt(idStr); UserDAO userDAO = new UserDAO(); User user = userDAO.getUserById(id); if (user == null) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } request.setAttribute("user", user); request.getRequestDispatcher("/jsp/user_detail.jsp").forward(request, response); } catch (NumberFormatException e) { response.sendError(HttpServletResponse.SC_BAD_REQUEST); } catch (SQLException e) { throw new ServletException("Database error", e); } } }

对应的JSP页面(user_detail.jsp):

<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>用户详情</title> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> </head> <body> <h1>用户详情</h1> <table> <tr> <td>ID:</td> <td>${user.id}</td> </tr> <tr> <td>用户名:</td> <td>${user.username}</td> </tr> <tr> <td>邮箱:</td> <td>${user.email}</td> </tr> <tr> <td>电话:</td> <td>${user.phone}</td> </tr> <tr> <td>创建时间:</td> <td>${user.createTime}</td> </tr> <tr> <td>更新时间:</td> <td>${user.updateTime}</td> </tr> </table> <a href="users">返回列表</a> </body> </html>

6. 添加用户功能

创建AddUserServlet处理添加用户请求:

@WebServlet("/add_user") public class AddUserServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 显示添加用户表单 request.getRequestDispatcher("/jsp/add_user.jsp").forward(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 处理表单提交 String username = request.getParameter("username"); String password = request.getParameter("password"); String email = request.getParameter("email"); String phone = request.getParameter("phone"); User user = new User(); user.setUsername(username); user.setPassword(password); user.setEmail(email); user.setPhone(phone); try { UserDAO userDAO = new UserDAO(); boolean success = userDAO.addUser(user); if (success) { response.sendRedirect("users"); } else { request.setAttribute("error", "添加用户失败"); request.getRequestDispatcher("/jsp/add_user.jsp").forward(request, response); } } catch (SQLException e) { throw new ServletException("Database error", e); } } }

添加用户表单页面(add_user.jsp):

<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>添加用户</title> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> </head> <body> <h1>添加用户</h1> <form action="add_user" method="post"> <table> <tr> <td>用户名:</td> <td><input type="text" name="username" required></td> </tr> <tr> <td>密码:</td> <td><input type="password" name="password" required></td> </tr> <tr> <td>邮箱:</td> <td><input type="email" name="email" required></td> </tr> <tr> <td>电话:</td> <td><input type="text" name="phone"></td> </tr> <tr> <td colspan="2"> <input type="submit" value="添加"> <a href="users">取消</a> </td> </tr> </table> </form> <c:if test="${not empty error}"> <div class="error">${error}</div> </c:if> </body> </html>

7. 删除用户功能

创建DeleteUserServlet处理删除用户请求:

@WebServlet("/delete_user") public class DeleteUserServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String idStr = request.getParameter("id"); if (idStr == null || idStr.isEmpty()) { response.sendRedirect("users"); return; } try { int id = Integer.parseInt(idStr); UserDAO userDAO = new UserDAO(); boolean success = userDAO.deleteUser(id); if (success) { response.sendRedirect("users"); } else { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } catch (NumberFormatException e) { response.sendError(HttpServletResponse.SC_BAD_REQUEST); } catch (SQLException e) { throw new ServletException("Database error", e); } } }

8. 用户编辑功能

创建EditUserServlet处理编辑用户请求:

@WebServlet("/edit_user") public class EditUserServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String idStr = request.getParameter("id"); if (idStr == null || idStr.isEmpty()) { response.sendRedirect("users"); return; } try { int id = Integer.parseInt(idStr); UserDAO userDAO = new UserDAO(); User user = userDAO.getUserById(id); if (user == null) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } request.setAttribute("user", user); request.getRequestDispatcher("/jsp/edit_user.jsp").forward(request, response); } catch (NumberFormatException e) { response.sendError(HttpServletResponse.SC_BAD_REQUEST); } catch (SQLException e) { throw new ServletException("Database error", e); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String idStr = request.getParameter("id"); String username = request.getParameter("username"); String email = request.getParameter("email"); String phone = request.getParameter("phone"); try { int id = Integer.parseInt(idStr); User user = new User(); user.setId(id); user.setUsername(username); user.setEmail(email); user.setPhone(phone); UserDAO userDAO = new UserDAO(); boolean success = userDAO.updateUser(user); if (success) { response.sendRedirect("user_detail?id=" + id); } else { request.setAttribute("error", "更新用户失败"); request.getRequestDispatcher("/jsp/edit_user.jsp").forward(request, response); } } catch (NumberFormatException e) { response.sendError(HttpServletResponse.SC_BAD_REQUEST); } catch (SQLException e) { throw new ServletException("Database error", e); } } }

编辑用户表单页面(edit_user.jsp):

<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>编辑用户</title> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> </head> <body> <h1>编辑用户</h1> <form action="edit_user" method="post"> <input type="hidden" name="id" value="${user.id}"> <table> <tr> <td>用户名:</td> <td><input type="text" name="username" value="${user.username}" required></td> </tr> <tr> <td>邮箱:</td> <td><input type="email" name="email" value="${user.email}" required></td> </tr> <tr> <td>电话:</td> <td><input type="text" name="phone" value="${user.phone}"></td> </tr> <tr> <td colspan="2"> <input type="submit" value="保存"> <a href="user_detail?id=${user.id}">取消</a> </td> </tr> </table> </form> <c:if test="${not empty error}"> <div class="error">${error}</div> </c:if> </body> </html>

9. 功能测试与优化

完成所有功能开发后,我们需要进行全面的测试。测试应该包括:

  1. 用户列表展示是否正常
  2. 用户详情查看是否正确显示
  3. 添加用户功能是否正常工作
  4. 编辑用户信息是否成功保存
  5. 删除用户功能是否正常
  6. 表单验证是否有效
  7. 错误处理是否合理

在测试过程中,我发现几个需要优化的地方:

  1. 密码应该加密存储,不能明文保存
  2. 需要添加分页功能,防止用户数据过多时页面加载缓慢
  3. 应该添加权限控制,防止未授权访问
  4. 需要增加表单验证,防止无效数据提交

以密码加密为例,我们可以使用BCrypt进行加密:

import org.mindrot.jbcrypt.BCrypt; public class PasswordUtil { public static String hashPassword(String plainPassword) { return BCrypt.hashpw(plainPassword, BCrypt.gensalt()); } public static boolean checkPassword(String plainPassword, String hashedPassword) { return BCrypt.checkpw(plainPassword, hashedPassword); } }

然后在UserDAO中修改添加用户的方法:

public boolean addUser(User user) throws SQLException { Connection conn = null; PreparedStatement stmt = null; try { conn = DBUtil.getConnection(); String sql = "INSERT INTO users(username, password, email, phone) VALUES(?, ?, ?, ?)"; stmt = conn.prepareStatement(sql); stmt.setString(1, user.getUsername()); stmt.setString(2, PasswordUtil.hashPassword(user.getPassword())); stmt.setString(3, user.getEmail()); stmt.setString(4, user.getPhone()); return stmt.executeUpdate() > 0; } finally { DBUtil.close(conn, stmt, null); } }

10. 项目部署与上线

完成开发和测试后,我们需要将项目部署到生产环境。部署步骤包括:

  1. 打包项目:使用Maven的package命令生成WAR文件
  2. 配置数据库:在生产环境创建数据库并导入初始数据
  3. 部署到Tomcat:将WAR文件复制到Tomcat的webapps目录
  4. 启动Tomcat:运行startup.sh或startup.bat
  5. 验证部署:访问应用确保所有功能正常

如果需要更专业的部署,可以考虑:

  1. 使用Nginx作为反向代理
  2. 配置HTTPS加密
  3. 设置数据库连接池
  4. 配置日志系统
  5. 实现自动化部署

在实际项目中,我通常会使用Docker容器化部署,这样可以保证环境一致性,简化部署流程。一个简单的Dockerfile示例如下:

FROM tomcat:9.0 COPY target/user-management.war /usr/local/tomcat/webapps/ CMD ["catalina.sh", "run"]

然后构建并运行容器:

docker build -t user-management . docker run -d -p 8080:8080 --name user-management-app user-management
http://www.cnnetsun.cn/news/3183091.html

相关文章:

  • C# .NET 6 WebAPI 对接微信小程序:3类接口设计与JWT鉴权实战
  • Java 事件驱动编程实战:基于 ActionListener 实现游戏逻辑的 2 种状态管理
  • Java+Vue+SpringBoot+MySQL员工绩效系统毕业设计部署与核心模块解析
  • Java+Vue+SpringBoot+MySQL课程作业管理系统:毕业设计实战部署与二次开发指南
  • 古风模特ai图片生成与多平台场景应用案例解析
  • 从DOSBox到86Box:五种虚拟化技术如何解决老软件兼容性问题
  • Balena Etcher终极指南:三步轻松制作系统启动盘,告别命令行复杂操作
  • STBP-tdBN 算法实战:ResNet-50 SNN 在 CIFAR-10 上实现 93.15% 准确率(6 时间步)
  • 01.02.01.DeepSeek:环境搭建篇(数据库 PostgreSQL)
  • 高精度计时系统:CS2200-CP与STM32F415ZG的硬件设计与应用
  • Plone主题开发底层逻辑:ZCA、TAL与Viewlet分层模型解析
  • Maya动画管理终极指南:Studio Library如何提升你的工作效率300%
  • SQL触发器:数据一致性的最后一道闸门
  • Excel slicer高级筛选实战:跨表联动与数据模型原理
  • Zenko:面向多云对象存储的数据编排层与策略驱动实践
  • Python工程选型的四大核心理由:效率、集成、交付与调试
  • DeepSeek服务波动根因解析:从503/504错误到云原生AI弹性瓶颈
  • Django技术向善:用开源框架驱动社会价值落地
  • PIC32与DS28EC20在嵌入式EEPROM存储中的优化实践
  • Snowflake四层架构实战:从账户初始化到可运行数据库
  • ASM330LHH与STM32F439ZG在运动跟踪技术中的应用
  • Django项目Kubernetes+GitOps自动化部署实战
  • 日常 Kubernetes:从命令行到工作流的工程化实践
  • KannalaBrandt8 模型 OpenCV 4.8 标定实战:5步完成鱼眼相机参数精确求解
  • Excel冻结多行:解决表头丢失的信息锚定问题
  • Windows Cleaner:如何通过3个核心功能解决C盘空间不足问题
  • Plone可扩展性实战:ZEO集群与ZODB优化指南
  • AI大模型职业指南:从核心岗位到实战技能,助你成功转型
  • COCO 2017 数据集格式实战:5分钟代码解析 JSON 5大核心字段
  • AWS VPC从零搭建:CLI与控制台双轨验证实战