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

发布时间:2026/7/15 13:49:03

JSP实战:从零构建用户管理模块
1. 环境准备与项目搭建在开始构建用户管理模块前我们需要准备好开发环境。这里推荐使用IntelliJ IDEA作为开发工具配合Tomcat 9作为Web服务器MySQL 5.7作为数据库。如果你还没有安装这些软件可以到官网下载最新版本。首先创建一个新的Maven Web项目在pom.xml中添加必要的依赖dependencies !-- Servlet API -- dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version4.0.1/version scopeprovided/scope /dependency !-- JSTL -- dependency groupIdjavax.servlet.jsp.jstl/groupId artifactIdjstl-api/artifactId version1.2/version /dependency !-- MySQL Connector -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.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) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;为了简化数据库操作我们创建一个DBUtil工具类public class DBUtil { private static final String URL jdbc:mysql://localhost:3306/user_management?useSSLfalse; 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 ListUser getAllUsers() throws SQLException { ListUser 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(); ListUser 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 contentTypetext/html;charsetUTF-8 languagejava % % taglib prefixc urihttp://java.sun.com/jsp/jstl/core % html head title用户列表/title link relstylesheet href${pageContext.request.contextPath}/css/style.css /head body h1用户列表/h1 table tr thID/th th用户名/th th邮箱/th th电话/th th创建时间/th th操作/th /tr c:forEach items${users} varuser tr td${user.id}/td td${user.username}/td td${user.email}/td td${user.phone}/td td${user.createTime}/td td a hrefuser_detail?id${user.id}查看/a a hrefedit_user?id${user.id}编辑/a a hrefdelete_user?id${user.id} onclickreturn confirm(确定删除该用户吗)删除/a /td /tr /c:forEach /table a hrefadd_user添加用户/a /body /html5. 用户详情查看功能创建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 contentTypetext/html;charsetUTF-8 languagejava % html head title用户详情/title link relstylesheet href${pageContext.request.contextPath}/css/style.css /head body h1用户详情/h1 table tr tdID:/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 hrefusers返回列表/a /body /html6. 添加用户功能创建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 contentTypetext/html;charsetUTF-8 languagejava % html head title添加用户/title link relstylesheet href${pageContext.request.contextPath}/css/style.css /head body h1添加用户/h1 form actionadd_user methodpost table tr td用户名:/td tdinput typetext nameusername required/td /tr tr td密码:/td tdinput typepassword namepassword required/td /tr tr td邮箱:/td tdinput typeemail nameemail required/td /tr tr td电话:/td tdinput typetext namephone/td /tr tr td colspan2 input typesubmit value添加 a hrefusers取消/a /td /tr /table /form c:if test${not empty error} div classerror${error}/div /c:if /body /html7. 删除用户功能创建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 contentTypetext/html;charsetUTF-8 languagejava % html head title编辑用户/title link relstylesheet href${pageContext.request.contextPath}/css/style.css /head body h1编辑用户/h1 form actionedit_user methodpost input typehidden nameid value${user.id} table tr td用户名:/td tdinput typetext nameusername value${user.username} required/td /tr tr td邮箱:/td tdinput typeemail nameemail value${user.email} required/td /tr tr td电话:/td tdinput typetext namephone value${user.phone}/td /tr tr td colspan2 input typesubmit value保存 a hrefuser_detail?id${user.id}取消/a /td /tr /table /form c:if test${not empty error} div classerror${error}/div /c:if /body /html9. 功能测试与优化完成所有功能开发后我们需要进行全面的测试。测试应该包括用户列表展示是否正常用户详情查看是否正确显示添加用户功能是否正常工作编辑用户信息是否成功保存删除用户功能是否正常表单验证是否有效错误处理是否合理在测试过程中我发现几个需要优化的地方密码应该加密存储不能明文保存需要添加分页功能防止用户数据过多时页面加载缓慢应该添加权限控制防止未授权访问需要增加表单验证防止无效数据提交以密码加密为例我们可以使用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. 项目部署与上线完成开发和测试后我们需要将项目部署到生产环境。部署步骤包括打包项目使用Maven的package命令生成WAR文件配置数据库在生产环境创建数据库并导入初始数据部署到Tomcat将WAR文件复制到Tomcat的webapps目录启动Tomcat运行startup.sh或startup.bat验证部署访问应用确保所有功能正常如果需要更专业的部署可以考虑使用Nginx作为反向代理配置HTTPS加密设置数据库连接池配置日志系统实现自动化部署在实际项目中我通常会使用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

相关新闻

Apache POI 实战指南:从基础读写到企业级报表生成

Apache POI 实战指南:从基础读写到企业级报表生成

2026/7/6 11:45:01

1. Apache POI入门:为什么选择这个Java办公文档神器第一次接触Apache POI是在2013年做银行报表系统时,当时需要处理每天上万笔交易记录的Excel导出。试过JXL等工具后,发现POI是唯一能稳定处理复杂格式和大数据量的解决方案。现在每次看到项目…

Unity VFX Graph 2022.3 火花特效:3步实现粒子受目标点动态吸引

Unity VFX Graph 2022.3 火花特效:3步实现粒子受目标点动态吸引

2026/7/12 19:41:43

Unity VFX Graph 2022.3 火花特效:3步实现粒子受目标点动态吸引在游戏开发中,粒子特效的动态交互能力往往决定了视觉体验的上限。想象一下:当玩家释放技能时,火花粒子不是简单地随机飘散,而是如同被磁铁吸引般飞向目标…

网易后端面试深度解析:从八股文到系统设计,如何通过大厂技术考核

网易后端面试深度解析:从八股文到系统设计,如何通过大厂技术考核

2026/7/9 0:21:43

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 “211本科面网易后端,4轮面试被拷问到怀疑人生,最后……” 看到这个标题,你是不是以为又是一个“…

C++实现HDLC协议栈:从原理到嵌入式工业通信实战

C++实现HDLC协议栈:从原理到嵌入式工业通信实战

2026/7/16 5:49:45

1. 项目概述:为什么要在C里折腾HDLC?如果你在嵌入式、工业通信或者一些老牌通信设备公司的代码里翻过,大概率会碰到HDLC(高级数据链路控制)协议。乍一看,这协议名字里带个“高级”,但其实是上个…

PCB设计工程师核心技能与学习路径:从入门到进阶

PCB设计工程师核心技能与学习路径:从入门到进阶

2026/7/16 5:49:45

这次我们来聊聊PCB设计工程师这个岗位到底需要掌握哪些技能,哪些内容可以暂时放一放。对于刚入行的工程师来说,最头疼的就是不知道学习重点在哪里,担心学了一堆用不上的东西,反而错过了核心技能。PCB设计工程师主要负责电路板的设…

【AI总结】2026年6月 主流国内外大模型总结

【AI总结】2026年6月 主流国内外大模型总结

2026/7/16 5:49:45

目录 引言一、 国际主流模型 1. OpenAI GPT 系列2. Anthropic Claude 系列3. Google Gemini 系列4. Meta Llama 系列5. xAI Grok 系列6. 其他值得关注的国际模型 二、 国内主流模型 1. 百度 文心大模型2. 阿里 通义千问3. 腾讯 混元大模型4. 字节跳动 豆包大模型 / 扣子5. 智谱…

Java循环控制进阶:while与do..while的实战抉择与break/continue的精准调控

Java循环控制进阶:while与do..while的实战抉择与break/continue的精准调控

2026/7/16 5:49:45

1. 为什么需要while和do..while循环?在日常编程中,我们经常遇到需要重复执行某段代码的场景。比如读取用户输入直到输入合法、处理文件中的每一行数据、或者游戏中的主循环。这时候,循环结构就派上用场了。Java提供了三种主要的循环结构&…

【2014-01-27】cocos2dx学习笔记:CCNode回调流程

【2014-01-27】cocos2dx学习笔记:CCNode回调流程

2026/7/16 5:49:45

[历史归档] 本文原发布于 cstriker1407.info 个人博客,内容为历史存档,仅供参考。 发布时间: 2014-01-27 | 标题:cocos2dx学习笔记:CCNode回调流程 | 分类: 编程 / C &&…

OpenAI技术面试全攻略:算法、系统设计与项目经验解析

OpenAI技术面试全攻略:算法、系统设计与项目经验解析

2026/7/16 5:39:44

最近在技术圈里,OpenAI 的面试体验又成了热门话题。不少开发者分享了自己参与面试的经历,普遍反馈流程专业、题目有深度,特别是对算法基础和系统设计能力的考察很到位。这让很多正在准备面试或对 AI 领域感兴趣的同学跃跃欲试。不过也有网友调…

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

2026/7/16 0:35:09

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator XUnity.AutoTranslator作为Unity游戏社区中最成熟的文本翻译解决方…

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

2026/7/13 20:43:19

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持 【免费下载链接】raspberrypi-kernel It provides openEuler kernel source for Raspberry Pi 项目地址: https://gitcode.com/openeuler/raspberrypi-kernel 前往项目官网免费下载&…

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

2026/7/15 0:26:43

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧 【免费下载链接】integration-test The repo contains test suits for system integration test 项目地址: https://gitcode.com/openeuler/integration-test 前往项目官网免费下载:…

Python实现跨境电商商品图批量翻译教程

Python实现跨境电商商品图批量翻译教程

2026/7/16 0:09:31

一、问题引入做跨境电商的卖家朋友,你是否遇到过这样的困扰?每次上架新品到亚马逊、Shopee或Lazada等平台,都需要处理大量商品图片的多语言版本。比如上架200款衣服,每款需要翻译成英语、日语、韩语等5种语言,这意味着…

跨境电商多语言商品图翻译方案实现

跨境电商多语言商品图翻译方案实现

2026/7/16 0:09:31

一、问题引入对于做跨境电商的卖家来说,多语言商品图的制作一直是令人头疼的环节。当你准备在亚马逊、Shopee、Lazada等多个平台同步上架新品时,首先遇到的就是图片翻译问题。以一位做家居用品的卖家为例,他需要将200张商品图片中的英文文案全…

Windows系统文件d3dx9_36.dll丢失找不到问题解决

Windows系统文件d3dx9_36.dll丢失找不到问题解决

2026/7/16 0:09:31

在使用电脑系统时经常会出现丢失找不到某些文件的情况,由于很多常用软件都是采用 Microsoft Visual Studio 编写的,所以这类软件的运行需要依赖微软Visual C运行库,比如像 QQ、迅雷、Adobe 软件等等,如果没有安装VC运行库或者安装…