Servlet 3.0 + JSP 用户管理 CRUD 实战:5个核心类与3个JSP页面构建完整流程 Servlet 3.0 JSP 用户管理 CRUD 实战从零构建企业级开发思维在Java Web开发领域掌握Servlet和JSP技术栈是每位开发者的必修课。本文将带您从实战角度出发通过一个完整的用户管理模块开发过程深入理解MVC架构的精髓。不同于简单的代码堆砌我们将重点关注模块化设计、数据流向控制和可维护性实践。1. 项目架构设计与环境准备1.1 技术选型与项目结构现代Java Web开发虽然涌现了Spring Boot等框架但理解原生Servlet/JSP的工作机制仍是核心基础。我们的技术栈选择Servlet 3.0支持注解配置简化web.xml管理JSP 2.2结合EL表达式和JSTL标签库MySQL 5.7关系型数据库标准选择Maven项目依赖管理工具标准项目目录结构应遵循Maven约定src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── example/ │ │ ├── model/ # 数据模型 │ │ ├── dao/ # 数据访问层 │ │ ├── service/ # 业务逻辑层 │ │ └── web/ # 控制器层 │ ├── resources/ # 配置文件 │ └── webapp/ │ ├── WEB-INF/ │ │ └── views/ # JSP视图文件 │ └── static/ # 静态资源1.2 数据库设计与初始化用户表设计应考虑基础字段和扩展性CREATE TABLE users ( id int(11) NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL, password varchar(100) NOT NULL, email varchar(100) DEFAULT NULL, phone varchar(20) DEFAULT NULL, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, status tinyint(1) DEFAULT 1, PRIMARY KEY (id), UNIQUE KEY idx_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;提示密码字段应存储加密后的值推荐使用BCrypt等强哈希算法2. 核心组件实现2.1 领域模型构建采用Java Bean规范定义用户实体package com.example.model; import java.time.LocalDateTime; public class User { private Integer id; private String username; private String password; private String email; private String phone; private LocalDateTime createTime; private LocalDateTime updateTime; private Boolean status; // 省略getter/setter和构造方法 }2.2 数据访问层实现DAO层采用JDBC模板模式避免重复代码public class UserDao { private final DataSource dataSource; public UserDao(DataSource dataSource) { this.dataSource dataSource; } public User findById(int id) throws SQLException { String sql SELECT * FROM users WHERE id ?; try (Connection conn dataSource.getConnection(); PreparedStatement stmt conn.prepareStatement(sql)) { stmt.setInt(1, id); ResultSet rs stmt.executeQuery(); if (rs.next()) { return mapUser(rs); } return null; } } private User mapUser(ResultSet rs) throws SQLException { User user new User(); user.setId(rs.getInt(id)); user.setUsername(rs.getString(username)); // 其他字段映射... return user; } }2.3 服务层设计服务层处理业务逻辑和事务管理public class UserService { private final UserDao userDao; public UserService(UserDao userDao) { this.userDao userDao; } public User getUserById(int id) throws BusinessException { try { User user userDao.findById(id); if (user null) { throw new BusinessException(用户不存在); } return user; } catch (SQLException e) { throw new BusinessException(数据库查询失败, e); } } }3. 控制器与视图开发3.1 Servlet控制器实现使用Servlet 3.0注解简化配置WebServlet(/users/*) public class UserServlet extends HttpServlet { private UserService userService; Override public void init() throws ServletException { DataSource dataSource (DataSource) getServletContext() .getAttribute(dataSource); userService new UserService(new UserDao(dataSource)); } Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String pathInfo req.getPathInfo(); if (pathInfo null || pathInfo.equals(/)) { listUsers(req, resp); } else if (pathInfo.equals(/new)) { showCreateForm(req, resp); } else { String[] parts pathInfo.split(/); if (parts.length 2) { showUser(Integer.parseInt(parts[1]), req, resp); } } } private void listUsers(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取用户列表逻辑 req.getRequestDispatcher(/WEB-INF/views/users/list.jsp) .forward(req, resp); } }3.2 JSP视图开发采用JSTL和EL表达式简化页面逻辑% page contentTypetext/html;charsetUTF-8 % % taglib prefixc urihttp://java.sun.com/jsp/jstl/core % !DOCTYPE html html head title用户列表/title /head body h2用户管理/h2 table thead tr thID/th th用户名/th th邮箱/th th操作/th /tr /thead tbody c:forEach items${users} varuser tr td${user.id}/td td${user.username}/td td${user.email}/td td a hrefc:url value/users/${user.id}/查看/a /td /tr /c:forEach /tbody /table /body /html4. 完整CRUD流程实现4.1 创建用户流程表单提交到Servlet的POST处理WebServlet(/users) public class UserServlet extends HttpServlet { // ...其他方法 Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { User user new User(); user.setUsername(req.getParameter(username)); user.setPassword(encrypt(req.getParameter(password))); // 其他字段处理... try { userService.createUser(user); resp.sendRedirect(req.getContextPath() /users); } catch (BusinessException e) { req.setAttribute(error, e.getMessage()); req.getRequestDispatcher(/WEB-INF/views/users/new.jsp) .forward(req, resp); } } }4.2 更新与删除实现采用RESTful风格设计URLWebServlet(/users/*) public class UserServlet extends HttpServlet { // ...其他方法 Override protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 解析ID String[] parts req.getPathInfo().split(/); int userId Integer.parseInt(parts[1]); // 更新逻辑... } Override protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 解析ID并删除 String[] parts req.getPathInfo().split(/); int userId Integer.parseInt(parts[1]); userService.deleteUser(userId); resp.setStatus(HttpServletResponse.SC_NO_CONTENT); } }5. 高级特性与优化5.1 分页查询实现服务层添加分页支持public class UserService { public PageUser listUsers(int page, int size) { // 计算偏移量 int offset (page - 1) * size; ListUser users userDao.findByPage(offset, size); int total userDao.count(); return new Page(users, page, size, total); } }5.2 表单验证与错误处理前端结合后端验证c:if test${not empty errors} div classalert alert-danger ul c:forEach items${errors} varerror li${error}/li /c:forEach /ul /div /c:if5.3 日志与异常处理配置全局异常处理器WebServlet(/errorHandler) public class ErrorHandlerServlet extends HttpServlet { Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Throwable throwable (Throwable) req.getAttribute(javax.servlet.error.exception); logger.error(请求处理异常, throwable); // 根据异常类型返回不同错误页面 if (throwable instanceof BusinessException) { req.getRequestDispatcher(/WEB-INF/views/error/business.jsp) .forward(req, resp); } else { req.getRequestDispatcher(/WEB-INF/views/error/system.jsp) .forward(req, resp); } } }6. 项目部署与测试6.1 Tomcat配置优化server.xml连接池配置Context Resource namejdbc/UserDB authContainer typejavax.sql.DataSource maxTotal100 maxIdle30 maxWaitMillis10000 usernamedbuser passworddbpass driverClassNamecom.mysql.jdbc.Driver urljdbc:mysql://localhost:3306/userdb/ /Context6.2 集成测试策略使用HttpClient进行端到端测试public class UserSystemTest { Test public void testCreateUser() throws Exception { CloseableHttpClient client HttpClients.createDefault(); HttpPost post new HttpPost(http://localhost:8080/users); ListNameValuePair params new ArrayList(); params.add(new BasicNameValuePair(username, testuser)); // 其他参数... post.setEntity(new UrlEncodedFormEntity(params)); try (CloseableHttpResponse response client.execute(post)) { assertEquals(302, response.getStatusLine().getStatusCode()); // 验证重定向位置 } } }通过这个完整的开发流程您不仅掌握了Servlet/JSP的技术实现更重要的是理解了企业级Web应用的分层架构和最佳实践。这种模块化、分层的设计思想正是现代Java Web框架如Spring MVC的基础。