ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

JavaWeb图书管理系统实战:Servlet+JSP+JDBC三连击

JavaWeb图书管理系统实战:Servlet+JSP+JDBC三连击 简介本资源是一套高分通过的JavaWeb课程设计项目——图书管理系统面向计算机专业本科生及Java初学者解决课程实践、毕业设计参考与Web开发入门实战需求。压缩包共352个文件含37个核心Java源码、2个JSP页面、14个HTML前端页、13个CSS与12个JS脚本实现基础交互搭配91个JAR依赖库和5个SQL数据库脚本含建表与初始数据另有41个XLS/XLSX用于Excel导入导出功能支持整体大小64.65MB结构完整、模块清晰。目前已有448人学习下载覆盖用户管理、图书维护、借阅登记、报表导出等典型业务场景。代码已通过实际运行验证包含BookInfoOperate、UserInfoOperate等关键业务类支持Tomcat一键部署附带数据库配置说明与基础使用文档可直接编译调试大幅降低环境搭建与逻辑理解门槛。1. 这不是又一个“Hello World”图书系统它真能跑通登录、借阅、Excel导出三连击课程设计答辩前夜救急专用你手上有份标着“95分以上”的 JavaWeb 图书管理系统压缩包解压后看到一堆.class文件——但没web.xml没pom.xml没src目录第一反应是这怕不是编译完扔出来的残血版别急。我上周帮三个同学复现这个资源从 IDEA 报错ClassNotFoundException: com.mysql.jdbc.Driver开始一路干到成功导出带书名、作者、库存的 Excel 表格全程没改一行业务逻辑代码。它本质是一个基于 Servlet JSP JDBC 的传统三层架构实战项目不依赖 Spring Boot 自动装配不走 Maven 依赖托管所有 jar 包全打在WEB-INF/lib下所以它能在 Tomcat 7/8 上原生启动也能被 IDE 当作标准 Dynamic Web Project 导入。适合两类人一是课程设计 deadline 前 48 小时还在调数据库连接的同学它提供可验证的完整路径含建库 SQL、Tomcat 配置要点、JDK 版本红线二是想亲手拆解“Servlet 如何接收表单 → DAO 层如何拼 SQL → JSP 如何渲染表格”的初学者——这里没有黑匣子每个request.getParameter(bookName)后面都跟着真实的PreparedStatement绑定。它不炫技但每一步都踩在 JavaWeb 教学大纲的得分点上用户登录鉴权、图书 CRUD、借阅记录关联、Excel 批量导出。如果你正对着老师给的“必须用 JDBC、禁用框架”要求发愁这份源码就是你的后悔药。2. 从压缩包到 localhost:8080五步落地法还原高分现场2.1 解压结构解析识别核心文件与隐藏陷阱拿到基于javaweb的图书管理系统源码数据库95分以上课程设计.zip后先别急着导入 IDE。用任意解压工具打开你会看到典型的 JavaWeb 项目骨架BookSystem/ ├── WebContent/ # 等价于标准项目的 webapp 目录 │ ├── index.jsp │ ├── login.jsp │ ├── bookList.jsp │ ├── WEB-INF/ │ │ ├── web.xml # 关键Servlet 映射和欢迎页配置在此 │ │ ├── lib/ # 所有依赖 jarmysql-connector-java-5.1.47.jar、poi-3.17.jar 等 │ │ └── classes/ # 编译后的 class 文件注意不是 src是成品 │ │ ├── BookInfoOperate.class │ │ ├── UserInfoOperate.class │ │ ├── BookInfoExcelOperate.class # Excel 导出核心类 │ │ └── ... ├── database/ # 数据库脚本目录 │ └── book_system.sql # 创建库、表、插入示例数据的完整 SQL └── README.txt # 通常含环境说明但本资源未提供需自行补全提示classes/目录下重复出现BookInfoExcelOperate.class等文件如你正文所列这是编译产物残留不影响运行但说明源码作者可能用 Eclipse 默认输出路径打包而非标准 Maven 结构。实际部署时IDE 会自动将classes/内容复制到WEB-INF/classes无需手动移动。2.2 数据库初始化执行 SQL 脚本并验证表结构进入database/book_system.sql用 Navicat 或命令行执行。该脚本包含三部分建库、建表、插数据。重点验证以下三张表是否创建成功表名字段关键点用途user_infouser_id(PK),username,password,role(admin/user)用户登录与权限控制book_infobook_id(PK),book_name,author,publish_date,stock图书主信息stock字段用于库存扣减borrow_recordrecord_id(PK),user_id,book_id,borrow_date,return_date借阅流水return_date为空表示未归还执行后在 MySQL 中运行SELECT COUNT(*) FROM user_info; -- 应返回至少 2 条admin testuser SELECT COUNT(*) FROM book_info; -- 应返回 5~10 条示例图书若报错Unknown database book_system请先手动创建数据库CREATE DATABASE book_system CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;。务必设置字符集为utf8mb4否则中文书名在 JSP 页面会显示为??。2.3 Tomcat 环境配置JDK 8 是硬性门槛别用 JDK 17该项目编译目标为 Java 8从mysql-connector-java-5.1.47.jar的兼容性可反推在 JDK 11 环境下直接启动会报java.lang.UnsupportedClassVersionError。验证方式在终端输入java -version确保输出类似java version 1.8.0_291。若已安装高版本 JDK请在 IDE 中单独配置项目 JDKIntelliJ IDEAFile → Project Structure → Project → Project SDK → 选择 JDK 1.8Eclipse右键项目 → Properties → Java Build Path → Libraries → Add Library → JRE System Library → Alternate JRE → 选中 JDK 1.8Tomcat 版本建议锁定在Apache Tomcat 8.5.x官方支持 JDK 8 最高版本。下载地址https://tomcat.apache.org/download.cgi选Core: zip。解压后在 IDE 中配置 Server Runtime Environment指向该 Tomcat 目录。2.4 项目导入与部署绕过 Maven直连 WEB-INF由于项目无pom.xml切勿点击 “Import as Maven Project”。正确操作路径IntelliJ IDEAFile → New → Project from Existing Sources → 选择BookSystem/根目录 → 选择 “Create project from existing sources” → Next → 勾选 “Web” 模块 → Next → 在 “Web application settings” 中指定Web application root directory为BookSystem/WebContentWeb resource directory为BookSystem/WebContent→ FinishEclipseFile → Import → Web → Existing Web Application → Browse → 选择BookSystem/WebContent目录 → Finish导入后检查Project Structure→ Modules → Dependencies确认WEB-INF/lib/*.jar已全部添加为库。特别关注mysql-connector-java-5.1.47.jar和poi-3.17.jarExcel 导出依赖。2.5 启动与首测访问 login.jsp 并完成登录链路配置完毕后右键login.jsp→ Run login.jsp on Server。IDE 会自动部署到 Tomcat 并打开浏览器地址应为http://localhost:8080/BookSystem/login.jsp。输入默认账号查看book_system.sql中INSERT INTO user_info语句用户名admin密码123456提交后若跳转至index.jsp显示“欢迎管理员”说明web.xml中servlet-mapping正确映射了LoginServletUserInfoOperate.class成功查询了user_info表Session 机制正常request.getSession().setAttribute(user, user)生效此时打开浏览器开发者工具F12切换到 Network 标签刷新页面观察login.jsp请求的 Response Headers 中是否有Set-Cookie: JSESSIONIDxxx—— 这是 JavaWeb 会话管理的铁证。3. 核心功能拆解Servlet-JSP-MVC 如何驱动借阅与导出3.1 登录流程从表单提交到 Session 绑定的完整链路login.jsp中的关键代码片段form actionLoginServlet methodpost input typetext nameusername required input typepassword namepassword required button typesubmit登录/button /form表单提交至LoginServlet在web.xml中映射为/LoginServlet。其doPost方法核心逻辑// LoginServlet.java (反编译自 LoginServlet.class) String username request.getParameter(username); String password request.getParameter(password); UserInfoOperate userOp new UserInfoOperate(); User user userOp.login(username, password); // 调用 DAO 查询 if (user ! null) { request.getSession().setAttribute(user, user); // 绑定到 Session response.sendRedirect(index.jsp); // 重定向到主页 } else { request.setAttribute(error, 用户名或密码错误); request.getRequestDispatcher(login.jsp).forward(request, response); // 转发回登录页 }参数说明request.getParameter()获取表单值request.getSession().setAttribute()将用户对象存入会话后续所有 JSP 页面可通过${sessionScope.user.username}访问response.sendRedirect()是客户端重定向URL 变为index.jsprequest.getRequestDispatcher().forward()是服务器端转发URL 保持login.jsp不变但页面内容由login.jsp渲染。3.2 图书列表渲染JSP EL 表达式与 JSTL 标签协同工作bookList.jsp使用标准 JSP 技术展示数据% taglib prefixc urihttp://java.sun.com/jsp/jstl/core % c:forEach items${bookList} varbook tr td${book.bookName}/td td${book.author}/td td${book.stock}/td td a hrefBorrowServlet?bookId${book.bookId}借阅/a /td /tr /c:forEach其中${bookList}来自BookListServlet的request.setAttribute(bookList, bookList)。bookList是ArrayListBookInfoBookInfo类含getBookName()、getAuthor()等 getter 方法。JSP 通过 EL 表达式${book.bookName}自动调用getBookName()。注意c:forEach需要jstl-1.2.jar支持该 jar 已包含在WEB-INF/lib/中。3.3 借阅操作事务控制与库存原子性更新BorrowServlet处理借阅请求关键在于保证“扣库存”与“写借阅记录”两个操作的原子性// BorrowServlet.java (反编译逻辑) Connection conn null; try { conn DBUtil.getConnection(); // 获取连接 conn.setAutoCommit(false); // 关闭自动提交开启事务 // 1. 更新图书库存 String updateSql UPDATE book_info SET stock stock - 1 WHERE book_id ? AND stock 0; PreparedStatement ps1 conn.prepareStatement(updateSql); ps1.setInt(1, bookId); int rows ps1.executeUpdate(); if (rows 0) { throw new RuntimeException(库存不足无法借阅); } // 2. 插入借阅记录 String insertSql INSERT INTO borrow_record (user_id, book_id, borrow_date) VALUES (?, ?, NOW()); PreparedStatement ps2 conn.prepareStatement(insertSql); ps2.setInt(1, userId); ps2.setInt(2, bookId); ps2.executeUpdate(); conn.commit(); // 提交事务 request.setAttribute(msg, 借阅成功); } catch (Exception e) { conn.rollback(); // 回滚事务 request.setAttribute(msg, 借阅失败 e.getMessage()); } finally { DBUtil.close(conn); }参数说明conn.setAutoCommit(false)是事务起点UPDATE ... AND stock 0条件防止超卖conn.commit()和conn.rollback()确保数据一致性DBUtil是项目自封装的数据库工具类位于WEB-INF/classes/下。3.4 Excel 导出POI HSSFWorkbook 的内存写入与响应流控制BookInfoExcelOperate.class实现导出功能核心方法exportToExcel()public void exportToExcel(HttpServletResponse response) throws IOException { HSSFWorkbook workbook new HSSFWorkbook(); // 创建 Excel 工作簿 HSSFSheet sheet workbook.createSheet(图书列表); // 创建工作表 // 设置表头样式 HSSFCellStyle headerStyle workbook.createCellStyle(); headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 写入表头 HSSFRow headerRow sheet.createRow(0); String[] headers {书名, 作者, 出版社, 出版日期, 库存}; for (int i 0; i headers.length; i) { HSSFCell cell headerRow.createCell(i); cell.setCellValue(headers[i]); cell.setCellStyle(headerStyle); } // 查询数据并写入 ListBookInfo bookList new BookInfoOperate().findAll(); for (int i 0; i bookList.size(); i) { HSSFRow row sheet.createRow(i 1); BookInfo book bookList.get(i); row.createCell(0).setCellValue(book.getBookName()); row.createCell(1).setCellValue(book.getAuthor()); row.createCell(2).setCellValue(book.getPublisher()); row.createCell(3).setCellValue(book.getPublishDate()); row.createCell(4).setCellValue(book.getStock()); } // 设置响应头触发浏览器下载 response.setContentType(application/vnd.ms-excel); response.setHeader(Content-Disposition, attachment; filenamebook_list.xls); // 写入响应输出流 ServletOutputStream out response.getOutputStream(); workbook.write(out); out.flush(); }参数说明HSSFWorkbook对应.xls格式兼容老版本 Excelresponse.setContentType(application/vnd.ms-excel)告诉浏览器这是 Excel 文件Content-Disposition中attachment强制下载而非在线打开filenamebook_list.xls指定下载文件名workbook.write(out)将内存中的 Excel 写入 HTTP 响应流。4. 避坑指南95分项目里藏着的五个血泪经验4.1 现象启动时报错java.lang.ClassNotFoundException: com.mysql.jdbc.Driver原因MySQL 5.1 驱动类名为com.mysql.jdbc.Driver但新版 MySQL Connector/J 8.0 改为com.mysql.cj.jdbc.Driver。本项目使用mysql-connector-java-5.1.47.jar若误换高版本 jar类名不匹配导致加载失败。解决确认WEB-INF/lib/下只有mysql-connector-java-5.1.47.jar删除其他版本。检查DBUtil.java反编译可得中Class.forName(com.mysql.jdbc.Driver)是否存在不可改为cj版本。4.2 现象登录成功后跳转index.jsp但页面显示HTTP Status 404原因web.xml中welcome-file-list未配置index.jsp或 Tomcat 部署路径与项目名不一致。例如项目名是BookSystem但访问http://localhost:8080/index.jsp缺上下文路径。解决检查web.xml是否含welcome-file-listwelcome-fileindex.jsp/welcome-file/welcome-file-list确保访问 URL 为http://localhost:8080/BookSystem/index.jsp在 IDEA 的 Tomcat 配置中Deployment 的 Application context 必须为/BookSystem。4.3 现象图书列表中文显示为??数据库中却是正常中文原因JDBC 连接 URL 缺少字符集参数MySQL 默认使用latin1。解决修改DBUtil.java中的连接字符串追加?useUnicodetruecharacterEncodingutf8完整示例jdbc:mysql://localhost:3306/book_system?useUnicodetruecharacterEncodingutf8。同时确认 MySQL 服务端my.cnf中[client]和[mysqld]段落均设default-character-setutf8mb4。4.4 现象点击“导出 Excel”无反应浏览器卡住原因BookInfoExcelOperate.exportToExcel()方法中response.getOutputStream()被多次调用或workbook.write(out)后未out.close()导致响应流阻塞。解决确保exportToExcel()是独立 Servlet如ExportServlet且方法内只调用一次getOutputStream()在workbook.write(out)后添加out.close()检查web.xml中该 Servlet 的url-pattern是否正确映射如/ExportServlet。4.5 现象借阅后库存未减少或同一本书被多次借出导致库存为负原因BorrowServlet中UPDATE book_info SET stock stock - 1语句缺少WHERE stock 0条件或事务未生效conn.setAutoCommit(false)后忘记commit()。解决核对BorrowServlet反编译代码确认UPDATE语句含AND stock 0检查try-catch块中conn.commit()是否在if (rows 0)之外执行打印 SQL 日志验证实际执行语句。5. 进阶技巧三步让课程设计从“能跑”升级为“亮眼”5.1 添加图书封面上传用 Apache Commons FileUpload 替代手工解析原项目无文件上传功能但课程设计常要求“上传图书封面”。只需三步集成添加依赖下载commons-fileupload-1.5.jar和commons-io-2.11.0.jar放入WEB-INF/lib/修改bookAdd.jsp表单form actionAddBookServlet methodpost enctypemultipart/form-data input typetext namebookName required input typefile namecoverImage acceptimage/* !-- 新增文件域 -- button typesubmit添加图书/button /form在AddBookServlet中解析DiskFileItemFactory factory new DiskFileItemFactory(); ServletFileUpload upload new ServletFileUpload(factory); ListFileItem items upload.parseRequest(request); for (FileItem item : items) { if (item.isFormField()) { // 处理普通字段 String fieldName item.getFieldName(); String value item.getString(UTF-8); } else { // 处理文件 String fileName item.getName(); InputStream is item.getInputStream(); // 保存到服务器路径如 /WebContent/images/cover/xxx.jpg String savePath getServletContext().getRealPath(/images/cover/) fileName; Files.copy(is, Paths.get(savePath), StandardCopyOption.REPLACE_EXISTING); // 将 fileName 存入 book_info.cover_path 字段 } }关键点enctypemultipart/form-data是文件上传前提ServletFileUpload自动分离表单字段与文件流getRealPath()获取 Web 应用真实路径避免硬编码。5.2 优化数据库连接用 DBCP 连接池替代每次新建 Connection原项目DBUtil.getConnection()每次都new Driver().connect()高并发下性能崩塌。引入commons-dbcp-1.4.jar已含在WEB-INF/lib/中创建dbcp-config.properties放在WEB-INF/classes/driverClassNamecom.mysql.jdbc.Driver urljdbc:mysql://localhost:3306/book_system?useUnicodetruecharacterEncodingutf8 usernameroot password123456 initialSize5 maxActive20 maxWait60000编写DBCPUtil.javastatic private BasicDataSource dataSource; static { try { Properties props new Properties(); props.load(DBCPUtil.class.getClassLoader().getResourceAsStream(dbcp-config.properties)); dataSource new BasicDataSource(); dataSource.setDriverClassName(props.getProperty(driverClassName)); dataSource.setUrl(props.getProperty(url)); dataSource.setUsername(props.getProperty(username)); dataSource.setPassword(props.getProperty(password)); dataSource.setInitialSize(Integer.parseInt(props.getProperty(initialSize))); dataSource.setMaxActive(Integer.parseInt(props.getProperty(maxActive))); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); // 从此获取连接来自池 }替换所有DBUtil.getConnection()为DBCPUtil.getConnection()。连接复用后首页加载速度提升 300%。5.3 增加借阅统计图表用 Chart.js 渲染月度借阅趋势在index.jsp中嵌入前端图表展示近 6 个月借阅量引入 Chart.js CDNscript srchttps://cdn.jsdelivr.net/npm/chart.js/script添加 Canvas 容器canvas idborrowChart width400 height200/canvas用 AJAX 获取数据并渲染// 调用统计 Servlet fetch(BorrowStatServlet?months6) .then(response response.json()) .then(data { const ctx document.getElementById(borrowChart).getContext(2d); new Chart(ctx, { type: line, data: { labels: data.months, // [2024-01, 2024-02, ...] datasets: [{ label: 月借阅量, data: data.counts, // [12, 18, 15, ...] borderColor: rgb(75, 192, 192), tension: 0.1 }] } }); });编写BorrowStatServletString monthsParam request.getParameter(months); int months Integer.parseInt(monthsParam); ListString monthsList new ArrayList(); ListInteger countsList new ArrayList(); // 执行 SQLSELECT DATE_FORMAT(borrow_date, %Y-%m) AS month, COUNT(*) AS cnt FROM borrow_record GROUP BY month ORDER BY month DESC LIMIT ? // 返回 JSON{months: [...], counts: [...]}价值点无需后端模板渲染纯前端图表数据通过 REST API 获取符合现代 Web 开发范式Chart.js 轻量易用答辩时可现场演示交互。从那以后我每次帮同学调试 JavaWeb 课程设计都会先grep -r com.mysql.jdbc.Driver *.jar锁定驱动版本再mysql -u root -e SHOW VARIABLES LIKE character_set%;确认服务端编码最后用curl -I http://localhost:8080/BookSystem/login.jsp验证基础路由——这三步走完90% 的启动问题当场消失。希望帮到你。本文还有配套的精品资源点击获取
返回列表