简介这是一份面向计算机专业本科生的Java课程设计与期末大作业实战资源基于B/S架构实现功能完整的图书管理系统帮助学习者掌握JDBC连接MySQL、ServletJSP前后端交互、MVC分层开发等核心技能。资源包共93个文件包含40个Java业务逻辑类、14个JSP页面、11个JavaScript交互脚本、8个XML配置文件含web.xml与数据库连接配置、4个CSS样式文件及配套SQL建库脚本、README文档和IDEA项目配置文件结构清晰、注释详尽开箱即用。压缩包仅3.11MB轻量易部署新手可快速理解模块划分与数据流转逻辑。已有65人下载学习资源附带完整数据库脚本与项目说明文档涵盖用户登录、图书增删改查、借阅管理、权限控制等典型业务场景代码规范、界面简洁是夯实Java Web开发基础的高分课设范例。1. 这不是又一个“Hello World”图书系统它真能跑通、能改、能交作业且不依赖Spring Boot或任何云服务你手头那份被导师标着“需自主完成”的Java课设任务书是不是正压在键盘底下别急着复制粘贴GitHub上那些动辄300个模块、require JDK 17、还要配Nacos和Redis的“高分项目”——这套基于Java Servlet JSP MySQL原生实现的图书管理系统就是专为「没接触过框架、没配过Maven、连Tomcat端口都改不对」的同学设计的。它不炫技但所有功能都在一个标准Web应用结构里跑得稳用户登录/注销、图书增删改查带封面图上传、借阅记录管理、管理员权限隔离、模糊搜索、分页展示甚至包含完整的数据库建表语句和字段注释。源码里每段Java逻辑都有中文注释JSP页面用的是最朴素的% %和% %脚本片段没有EL表达式陷阱也没有JSTL标签报错玄学。我去年帮三个不同学校的学生部署过它——从Win10家庭版装MySQL 5.7开始到最终在IE11里点开借书按钮成功写入记录全程没碰过任何IDE插件或自动构建工具。如果你的目标是两周内交一份老师一眼认出“这学生真写了代码”的大作业而不是交一个连自己都启动不了的ZIP包那它就是你现在该打开的第一个文件。2. 从零部署三步走通整个系统连MySQL安装细节都给你标好版本号这套系统不是“解压即用”但它的部署路径极其清晰数据库 → Java Web容器 → 项目导入。关键在于每一步的版本锚定和配置边界——很多同学翻车不是代码问题而是MySQL驱动版本和JDK不匹配或是Tomcat的web.xml里Servlet映射写错了路径。下面我把每个环节拆成可验证的原子操作所有命令和路径都按Windows环境实测给出Linux/macOS仅需替换路径分隔符。2.1 MySQL 5.7.44 安装与初始化为什么必须是这个版本提示不要用MySQL 8.x本系统SQL脚本使用utf8字符集非utf8mb4且未启用caching_sha2_password认证插件MySQL 8默认开启该插件会导致JDBC连接失败。下载与安装去MySQL官网历史版本页archive.mysql.com下载mysql-5.7.44-winx64.zip解压到C:\mysql路径不含空格和中文。创建C:\mysql\my.ini内容如下[mysqld] port3306 basedirC:\\mysql datadirC:\\mysql\\data character-set-serverutf8 collation-serverutf8_general_ci default-storage-engineINNODB sql_modeNO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES [client] default-character-setutf8注意basedir和datadir必须用双反斜杠\\这是Windows下INI文件解析要求character-set-serverutf8是硬性要求否则中文插入会变问号。初始化并启动服务打开CMD管理员权限执行cd C:\mysql\bin mysqld --initialize-insecure --usermysql mysqld --install MySQL57 net start MySQL57此时root密码为空。立即登录并创建专用用户mysql -u root -p -- 直接回车空密码 CREATE DATABASE books_db CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE USER bookuserlocalhost IDENTIFIED BY book123; GRANT ALL PRIVILEGES ON books_db.* TO bookuserlocalhost; FLUSH PRIVILEGES;2.2 Tomcat 8.5.93 配置为什么不能用Tomcat 10提示Tomcat 10 使用Jakarta EE命名空间jakarta.servlet.*而本项目所有Java类仍继承自javax.servlet.*强行升级会编译报错。下载apache-tomcat-8.5.93-windows-x64.zip官网Archive页解压到C:\tomcat。修改C:\tomcat\conf\server.xml确认Connector端口为8080默认Connector port8080 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 /启动C:\tomcat\bin\startup.bat访问http://localhost:8080出现Tomcat欢迎页即成功。2.3 项目导入与运行IntelliJ IDEA 2023.2 实操步骤项目结构是标准的Java Web传统布局非Maven因此不能直接“Open as Project”必须手动指定Web根目录解压Books-master.zip得到Books-master文件夹。IntelliJ IDEA → File → New → Project from Existing Sources → 选择Books-master文件夹 → 选中 “Create project from external model” → 不勾选Maven → Next → Finish。右键项目名 →Add Framework Support→ 勾选Web Application→ 点击OK。此时IDEA会自动生成WEB-INF/web.xml若已存在则跳过。在Project StructureCtrlAltShiftS→ Modules → Dependencies → 点击→ JARs or directories → 添加Books-master\lib\*.jar共5个JARmysql-connector-java-5.1.47.jar,commons-fileupload-1.3.1.jar,commons-io-2.4.jar,jstl-1.2.jar,standard-1.1.2.jar。配置ArtifactsProject Structure → Artifacts →→ Web Application: Exploded →From modules...→ 选中Books-master:war exploded→ Output directory设为Books-master\out\artifacts\Books_master_war_exploded。运行配置Run → Edit Configurations →→ Tomcat Server → Local → Deployment →→ Artifact → 选择刚创建的Books-master:war exploded→ Application context填/books注意开头斜杠。启动后访问http://localhost:8080/books出现登录页即部署成功。3. 源码结构深度拆解看懂每一层在干什么才能改得安心这套系统的价值不在“能跑”而在“看得懂、改得动”。它把Java Web开发的四个核心层次——表现层JSP、控制层Servlet、业务层Service、数据层DAO——用最直白的方式摊开。下面我带你逐层穿透重点标注哪些文件是“必须改”、哪些是“建议读”、哪些是“可删”。3.1 表现层JSP页面如何组织login.jsp和index.jsp的区别在哪Books-master\src\main\webapp\下的JSP是纯前端逻辑无业务计算login.jsp静态表单提交到LoginServlet校验失败时通过% request.getAttribute(msg) %显示错误提示。关键点表单action/login对应web.xml中servlet-mapping的URL-pattern。index.jsp首页含导航栏和图书列表。列表通过c:forEach遍历requestScope.books由BookListServlet塞入每行调用a hrefbookDetail.jsp?id${book.id}跳转详情页。注意bookDetail.jsp里用request.getParameter(id)获取ID再调用BookDAO.findById()查数据——这是典型的“请求参数→DAO查询→JSP渲染”链路。addBook.jsp含文件上传表单enctypemultipart/form-data后端用commons-fileupload解析。上传的封面图存于Books-master\src\main\webapp\assets\images\路径硬编码在BookService.addBook()中。为什么assets目录放在webapp下因为Tomcat默认将webapp作为Web根目录/assets/images/xxx.jpg可被浏览器直接访问。若你把图片存到WEB-INF下就无法通过HTTP URL加载——这是新手常踩的“图片404”坑。3.2 控制层Servlet如何串联请求与响应LoginServlet做了什么Books-master\src\cn\web\kong\下的Servlet是真正的调度中心LoginServlet.javaprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username request.getParameter(username); String password request.getParameter(password); User user userService.login(username, password); // 调用业务层 if (user ! null) { request.getSession().setAttribute(user, user); // 登录态存Session response.sendRedirect(index.jsp); // 重定向到首页 } else { request.setAttribute(msg, 用户名或密码错误); // 错误信息存Request request.getRequestDispatcher(login.jsp).forward(request, response); // 转发回登录页 } }关键逻辑forward()保持URL不变仍是/login适合表单校验失败sendRedirect()改变URL变成/index.jsp适合登录成功跳转。两者不能混用。BookListServlet.javaprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ListBook books bookService.findAll(); // 获取全部图书 request.setAttribute(books, books); // 塞入Request作用域 request.getRequestDispatcher(index.jsp).forward(request, response); }注意这里没做分页原始代码是全量查库。若你要加limit需在BookDAO.findAll()里拼LIMIT 10并在index.jsp里加“下一页”链接——这就是你扩展功能的第一处切入点。3.3 业务层与数据层Service和DAO如何解耦为什么BookDAO里有SQL字符串Books-master\src\cn\service\和Books-master\src\cn\dao\是纯Java类无框架侵入BookService.java只做业务规则判断如addBook()里检查ISBN是否重复、封面图是否为空。它不碰SQL只调用BookDAO。BookDAO.java真正执行JDBC操作。例如findById()方法public Book findById(int id) { String sql SELECT * FROM books WHERE id ?; try (Connection conn JDBCUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, id); ResultSet rs ps.executeQuery(); if (rs.next()) { Book book new Book(); book.setId(rs.getInt(id)); book.setTitle(rs.getString(title)); book.setAuthor(rs.getString(author)); // ... 其他字段 return book; } } catch (SQLException e) { e.printStackTrace(); } return null; }为什么SQL写死在Java里因为没用MyBatis或Hibernate。好处是调试时一眼看到执行的SQL坏处是修改表结构要同步改Java代码。这也是你后续升级为MyBatis的天然入口点——把BookDAO里的SQL抽成XML文件即可。4. 避坑五个真实翻车现场以及我怎么用记事本修好的这套系统看似简单但部署和调试时极易陷入“页面空白”“404”“500”“中文乱码”等黑匣子状态。以下是我在辅导学生时记录的5个高频问题每条都按“现象→原因→解决”还原拒绝模糊描述。4.1 现象访问http://localhost:8080/books显示404但Tomcat欢迎页正常原因IntelliJ IDEA未正确部署Artifact或Application context路径与实际访问路径不一致。解决检查Run Configuration → Deployment → Artifact是否选中查看Tomcat日志C:\tomcat\logs\catalina.out搜索deploy关键字确认/books是否出现在部署日志中若日志显示Deploying web application directory [C:\tomcat\webapps\books]说明IDEA把项目打成了WAR包放到了webapps下——此时应访问http://localhost:8080/books若日志显示Deploying web application archive [C:\tomcat\webapps\books.war]则WAR包未解压需手动解压或重启Tomcat。4.2 现象登录成功后跳转到index.jsp但页面顶部显示java.lang.NullPointerException原因index.jsp第3行% session.getAttribute(user).getUsername() %试图调用null对象的方法。解决在LoginServlet.java中response.sendRedirect(index.jsp)前添加System.out.println(User login success: user.getUsername());确认user不为null在index.jsp顶部加判空逻辑% User user (User) session.getAttribute(user); % % if (user null) { response.sendRedirect(login.jsp); return; } %4.3 现象添加图书时封面图上传失败assets/images/下无文件原因addBook.jsp表单缺少enctypemultipart/form-data或BookService.addBook()中文件保存路径写错。解决检查addBook.jsp的form标签是否含enctypemultipart/form-data打开BookService.java定位saveImageFile()方法确认String uploadPath request.getServletContext().getRealPath(/) assets/images/;——getRealPath(/)返回的是C:\tomcat\webapps\books\所以图片会存到C:\tomcat\webapps\books\assets\images\若你用IDEA热部署该路径实际指向Books-master\out\artifacts\Books_master_war_exploded\assets\images\需确保此目录存在且有写权限。4.4 现象数据库中文显示为??但Navicat里能看到正确汉字原因JDBC URL未指定字符集或MySQL服务端字符集未生效。解决检查JDBCUtil.java中的URLprivate static final String URL jdbc:mysql://localhost:3306/books_db?useUnicodetruecharacterEncodingutf8;必须含characterEncodingutf8不是utf8mb4在MySQL命令行执行SHOW VARIABLES LIKE character_set_%;确认character_set_server和collation_server均为utf8若仍无效在my.ini的[mysqld]节下追加init_connectSET NAMES utf8重启MySQL。4.5 现象点击“借阅”按钮报500日志显示java.sql.SQLException: Column borrow_time cannot be null原因borrow_records表的borrow_time字段定义为NOT NULL但BorrowServlet.java中未给该字段赋值。解决打开database.sql找到CREATE TABLE borrow_records语句将borrow_time DATETIME NOT NULL改为borrow_time DATETIME DEFAULT CURRENT_TIMESTAMP或在BorrowServlet.java中插入前设置时间record.setBorrowTime(new Timestamp(System.currentTimeMillis())); borrowDAO.addRecord(record);5. 功能增强实战三处可立即动手的加分项附完整代码与效果验证交作业不等于只跑通高分的关键在于“让老师看到你动了脑子”。下面三个增强点我都已在真实课设中验证过改动最小、效果最直观且每处都提供可直接复制的代码和验证方法。5.1 加分项一为图书列表增加按作者模糊搜索无需改数据库原始系统只有全量列表加搜索框只需两步改JSP加输入框 改Servlet传参 改DAO写LIKE查询。修改index.jsp在表格上方加搜索表单form actionBookListServlet methodget 按作者搜索input typetext nameauthor value${param.author} / input typesubmit value搜索 / a hrefBookListServlet显示全部/a /form修改BookListServlet.java的doGet()方法String author request.getParameter(author); ListBook books; if (author ! null !author.trim().isEmpty()) { books bookService.findByAuthor(author.trim()); } else { books bookService.findAll(); } request.setAttribute(books, books); request.getRequestDispatcher(index.jsp).forward(request, response);在BookService.java中新增方法public ListBook findByAuthor(String author) { return bookDAO.findByAuthor(author); }在BookDAO.java中新增方法public ListBook findByAuthor(String author) { String sql SELECT * FROM books WHERE author LIKE ?; ListBook books new ArrayList(); try (Connection conn JDBCUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, % author %); ResultSet rs ps.executeQuery(); while (rs.next()) { books.add(mapToBook(rs)); } } catch (SQLException e) { e.printStackTrace(); } return books; }验证启动后在搜索框输入“金”应只显示作者含“金”的图书如《金瓶梅》《黄金时代》。若无结果检查ps.setString(1, % author %)是否漏掉百分号。5.2 加分项二借阅记录页增加“归还”按钮状态字段改造原始系统借阅后无归还操作我们给borrow_records表加status字段0未归还1已归还并在borrowList.jsp中加按钮。执行SQL修改表结构ALTER TABLE borrow_records ADD COLUMN status TINYINT DEFAULT 0; UPDATE borrow_records SET status 1 WHERE return_time IS NOT NULL;修改BorrowListServlet.java查询时带上statusListBorrowRecord records borrowDAO.findAllWithStatus();在BorrowDAO.java中新增方法public ListBorrowRecord findAllWithStatus() { String sql SELECT br.*, b.title, u.username FROM borrow_records br JOIN books b ON br.book_id b.id JOIN users u ON br.user_id u.id ORDER BY br.borrow_time DESC; // ... 执行查询map时取br.status }修改borrowList.jsp在每行末尾加归还按钮c:if test${record.status 0} a hrefReturnServlet?id${record.id}归还/a /c:if c:if test${record.status 1} 已归还 /c:if新建ReturnServlet.javaprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int id Integer.parseInt(request.getParameter(id)); borrowDAO.updateStatus(id, 1); // 设为已归还 response.sendRedirect(BorrowListServlet); }验证借阅一条记录后登录管理员账号进入借阅记录页点击“归还”刷新页面应显示“已归还”且数据库status字段变为1。5.3 加分项三登录页增加验证码极简版无第三方库不用Kaptcha或Google reCAPTCHA用Java原生BufferedImage生成4位数字验证码存入Session。新建VerifyCodeServlet.javaprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 生成4位随机数 String code String.valueOf((int)(Math.random() * 9000 1000)); request.getSession().setAttribute(verifyCode, code); // 绘制图片 BufferedImage image new BufferedImage(80, 30, BufferedImage.TYPE_INT_RGB); Graphics2D g image.createGraphics(); g.setColor(Color.WHITE); g.fillRect(0, 0, 80, 30); g.setColor(Color.BLACK); g.setFont(new Font(Arial, Font.BOLD, 20)); g.drawString(code, 10, 25); g.dispose(); response.setContentType(image/png); ImageIO.write(image, png, response.getOutputStream()); }修改login.jsp在密码框下方加验证码区域img srcVerifyCodeServlet idverifyImg onclickthis.srcVerifyCodeServlet?Math.random() stylecursor:pointer; / input typetext nameverifyCode placeholder验证码 maxlength4 /修改LoginServlet.java的doPost()String inputCode request.getParameter(verifyCode); String sessionCode (String) request.getSession().getAttribute(verifyCode); if (!inputCode.equalsIgnoreCase(sessionCode)) { request.setAttribute(msg, 验证码错误); request.getRequestDispatcher(login.jsp).forward(request, response); return; }验证刷新登录页验证码图片可点击切换输入错误验证码提示“验证码错误”输入正确则正常登录。从那以后我每次帮学生改课设都会先让他们把这三个增强点跑通——不是为了炫技而是因为它们覆盖了Web开发最核心的三个能力参数传递与查询构造、数据库字段扩展与状态管理、前后端交互与Session控制。当你亲手把一个“能跑”的系统变成“能搜、能还、能防刷”的系统那种对技术边界的掌控感比任何高分都实在。希望帮到你。本文还有配套的精品资源点击获取