简介:面向高校JavaWeb课程设计、毕业设计及初学者的图书管理系统项目,采用JSP+Servlet+JavaBean的MVC分层架构,搭配MySQL 5数据库,完整实现图书信息管理、学生注册登录、图书借阅、图书归还、逾期查询等核心业务功能。项目已在MyEclipse/Eclipse、JDK1.7、Tomcat8、MySQL5.6/5.7环境下实际运行通过,代码经过测试,分层清晰,便于对照学习。系统设计包含管理员与读者两类角色,管理员可维护图书信息并处理借阅归还,读者可检索图书、查看个人借阅记录。压缩包大小约8.74MB,以ZIP形式提供,除整套工程源码外,还包含运行部署文档、配套论文及答辩PPT,源码中涵盖JSP页面、Servlet控制器、JavaBean业务类与数据库脚本,方便逐层理解请求响应流程。读者可通过该项目掌握Servlet处理请求、JSP页面渲染、JavaBean业务封装、数据库连接与增删改查等常见开发技能,也可学习如何整理项目文档、绘制功能模块图并完成答辩演示。目前已有1321人学习使用,适合作为期末项目或毕业设计的实战参考。
1. 用 Servlet+JSP 手写图书管理系统:这仍是 JavaWeb 课设最稳的路线
如果你正在找一份能直接跑通、能写进简历、能拿来答辨的 JavaWeb 课设源码,jsp+servlet+javabean+mvc+mysql 这套组合依然是目前最稳的选择。虽然 Spring Boot 已经是主流,但绝大多数高校的 JavaWeb 课程考核点仍然停留在 Servlet 和 JSP 层面——你交一个 SSM 项目上去,老师反而可能没法快速验收。这份图书管理系统覆盖了登录鉴权、读者管理、图书借阅、归还、逾期处理等完整闭环,用的是经典的 Model1/Model2 混合模式,代码结构清楚,自带运行文档、配套论文和答辩 PPT,属于拿到手就能跑的课设级别项目。适合三类人:JavaWeb 刚学完想找实战练手的学生、需要交课程设计报告的在读生、以及想快速回顾 Servlet+JSP 老技术栈的开发者。
2. 项目底层拆解:JSP+Servlet+JavaBean+MVC 的分工逻辑
2.1 为什么这个年代还要看 Servlet+JSP
很多同学上来就问:为什么不直接上 Spring Boot?答案很简单:你的课程大纲没教。Servlet 是 JavaWeb 的基石,JSP 本质上是被容器编译成 Servlet 再执行的,搞懂这套链路,后面学 Spring MVC 的时候你会秒懂 DispatcherServlet 到底在干什么。
这套项目里的 MVC 分层非常典型:JSP 负责视图层,Servlet 充当控制器,JavaBean 承担模型层的业务逻辑与数据封装,数据库操作通过 JDBC 完成。你不妨把 Servlet 理解成前台接待——所有请求先到它手里,它根据 url-pattern 判断该找哪个部门处理,然后返回结果给 JSP 去展示。学完这个项目,你对 HTTP 请求到响应这条链路会有实感,这是直接上手 Spring Boot 的人很难补上的一课。
2.2 目录结构:拿到源码先看什么
解压后先别急着往 Tomcat 里丢,先摸清工程的骨架。以下是这类 Servlet+JSP 项目的典型目录结构,这份资源里的布局基本一致,你可以对照着找:
src/ ├── com.xxx.bean/ // 实体类:Book.java, Reader.java, BorrowInfo.java ├── com.xxx.dao/ // 数据访问层:BookDao.java, ReaderDao.java ├── com.xxx.servlet/ // 控制器:LoginServlet.java, BookServlet.java ├── com.xxx.filter/ // 过滤器:EncodingFilter.java, LoginFilter.java └── com.xxx.util/ // 工具类:DBUtil.java, StringUtil.java WebRoot/ ├── index.jsp // 登录页 ├── book/ // 图书管理相关页面 ├── reader/ // 读者管理相关页面 ├── borrow/ // 借阅/归还页面 └── WEB-INF/ ├── web.xml // 部署描述符,配置 Servlet 路由 └── lib/ // mysql-connector-java-x.x.x-bin.jar先读web.xml,这里定义了所有 Servlet 的访问路径,等于项目的路由表。再看DBUtil.java,搞清数据库连接信息配置在哪里,后面改库改密码都要动它。最后按 实体类→DAO→Servlet→JSP 的顺序读代码,你会看到一条清晰的数据流:JSP 表单提交 → Servlet 接收参数 → 调用 DAO 操作数据库 → 返回结果集 → 跳转回 JSP 渲染。
2.3 JavaBean 的三层职责:实体、业务、数据库访问
这套项目里的 JavaBean 不只是一个纯数据载体,它还承担了业务逻辑。以借书操作为例,流程涉及两个核心 JavaBean 的协作:
- 实体 Bean:
Book、Reader、Borrow,属性对应数据库表的字段,提供 getter/setter - 业务/DAO Bean:
BookDao、BorrowDao,里面写的是 SQL 语句和 JDBC 操作
// BorrowDao.java 核心方法:借书逻辑(简化版) public boolean borrowBook(int bookId, int readerId) { Connection conn = DBUtil.getConnection(); PreparedStatement ps = null; ResultSet rs = null; try { // 第一步:检查图书库存是否大于 0 String sqlCheck = "SELECT stock FROM book WHERE id = ?"; ps = conn.prepareStatement(sqlCheck); ps.setInt(1, bookId); rs = ps.executeQuery(); if (rs.next() && rs.getInt("stock") > 0) { // 第二步:插入借阅记录,归还日期默认为空 String sqlBorrow = "INSERT INTO borrow_info(book_id, reader_id, borrow_date, is_returned) VALUES(?, ?, NOW(), 0)"; ps = conn.prepareStatement(sqlBorrow); ps.setInt(1, bookId); ps.setInt(2, readerId); int rows = ps.executeUpdate(); if (rows > 0) { // 第三步:同步扣减库存 String sqlUpdate = "UPDATE book SET stock = stock - 1 WHERE id = ?"; ps = conn.prepareStatement(sqlUpdate); ps.setInt(1, bookId); ps.executeUpdate(); return true; } } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(conn, ps, rs); } return false; }这段代码就是整个借书模块的心脏。我第一次在课设里写类似逻辑时翻过车,漏了第三步扣库存,结果书被借走了库存数量纹丝不动,最后盘点数据全是乱的。注意看事务边界:因为这里用的是单条连接且没有显式开启事务,借阅记录插入与库存扣减是两条独立 SQL,存在中间失败导致数据不一致的风险。如果你想优化,可以把conn.setAutoCommit(false)加进去,两步操作后统一 commit,异常时 rollback,这也是答辩时老师喜欢追问的加分点。
3. 环境搭建与版本搭配:JDK1.7+Tomcat8+MySQL5.6 的兼容性说明
3.1 为什么是 JDK1.7 而不是 JDK8 或 11
这份资源的运行文档里明确写了 jdk1.7 + tomcat8 + mysql5.6/5.7,这不是随手填的,而是经过验证的稳定组合。JDK1.7 对应 Java 7 语法,代码里不会出现 Lambda、try-with-resources 这些新特性,保证了你在 Eclipse 里导入后不报语法错误。Tomcat8 支持 Servlet 3.1 规范,JSP 2.3,对 JDK1.7 完全兼容。MySQL 5.6/5.7 则是那个年代课设项目最常见的数据库版本。
这里有个常见翻车点:很多同学电脑上装的是 MySQL 8.0,导入项目后启动 Tomcat 报错Access denied for user 'root'@'localhost'或者驱动类找不到。原因是 MySQL 8.0 的认证插件换成了 caching_sha2_password,而项目里 mysql-connector-java 5.x 驱动只支持 mysql_native_password。解决办法有两个:要么按项目要求装 MySQL 5.7,要么在 8.0 里执行ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';把认证插件改回去。
我的建议是:如果你只是要跑通课设,直接按原配置来,装 MySQL 5.7 最省事。如果想顺便练练兼容性排查,再试 MySQL 8.0 的坑。
3.2 Eclipse 导入 Web 项目的正确姿势
用 Eclipse 而不是 IDEA 导入这类老项目,是有讲究的。IDEA 社区版对 JSP/Servlet 项目的支持不是不好,而是配置路径和 Eclipse 生成的项目结构不兼容。这份资源本身也是按 Eclipse/MyEclipse 组织的,所以跟着走不容易卡壳。
导入步骤:
1. Eclipse 菜单栏选择 File -> Import -> General -> Existing Projects into Workspace 2. Select root directory 指向解压后的项目文件夹 3. 确认项目出现在列表中,勾选 Copy projects into workspace(可选) 4. 点击 Finish,等待构建完成 5. 右键项目 -> Properties -> Targeted Runtimes,勾选 Apache Tomcat 8 6. 右键项目 -> Run As -> Run on Server,选择 Tomcat 8 启动注意第 5 步经常被漏掉。不设置 Targeted Runtimes 的话,Eclipse 会报错说项目缺少运行时环境,或者HttpServlet类找不到。如果你在导入后看到大量红叉,先别慌,八成是这两类问题:JRE System Library 没绑定到 JDK1.7,或者 Server Runtime 没选 Tomcat8。解决方式是在项目 Properties 里的 Java Build Path 中把 JRE 切到本地装的 JDK,再在 Targeted Runtimes 里勾上 Tomcat。
我要提醒一句:MyEclipse 和 Eclipse 对 WebRoot 目录的识别有差异。MyEclipse 会自动把 WebRoot 当作 Web 根目录,而 Eclipse 默认认的是 WebContent。如果你的 Eclipse 识别不到 JSP 文件,检查 Project Facets 里的 Dynamic Web Module 设置,手动指定 WebRoot 作为 Content Directory。这个细节卡住过很多人,项目看起来没问题,启动后就 404。
3.3 Tomcat8 的下载与启动配置
Tomcat 不需要安装,解压就能用。但有两个环境变量要配好:JAVA_HOME指向你的 JDK 安装目录,CATALINA_HOME指向 Tomcat 解压目录。在 Eclipse 里配置 Server 的时候,它会自动读取这两个变量。
启动 Tomcat 之前,先验证一下端口有没有被占用。Tomcat 默认跑在 8080,如果你之前装过其他服务占了这个端口,启动就会失败。在命令行执行:
netstat -ano | findstr :8080有输出就说明端口被占,要么杀掉占用进程,要么改 Tomcat 的 conf/server.xml,把 HTTP 端口改成 8081。改端口之后访问项目 URL 也要跟着变,这点容易忽略。我见过同学改了端口忘了改访问地址,在浏览器里输 8080 打不开,对着屏幕发呆半天,其实就是个端口问题。
4. 数据库初始化与项目联调:从 SQL 脚本到第一行日志
4.1 创建数据库和导入数据表
项目里应该带了一个book_manager.sql或者library.sql文件,这就是数据库的初始化脚本。里面包含了建库、建表、插入初始数据的完整语句。打开 MySQL 命令行或者 Navicat,按以下步骤执行:
-- 第一步:创建数据库,注意字符集要和项目里 DBUtil 配置一致 CREATE DATABASE IF NOT EXISTS book_manager DEFAULT CHARACTER SET utf8; -- 第二步:切换到目标库 USE book_manager; -- 第三步:执行项目自带的 SQL 脚本 -- 如果你用的是 Navicat,直接打开 .sql 文件并运行即可 -- 命令行方式:source 文件路径(注意路径中不能有中文)执行完后确认至少这几张表存在:book(图书表)、reader(读者表)、borrow_info(借阅信息表)、admin(管理员表)。每张表的关键字段大体如下设计:
| 表名 | 核心字段 | 说明 |
|---|---|---|
| book | id, book_name, author, publisher, stock | stock 表示当前可借库存 |
| reader | id, reader_name, phone, reg_date | 读者注册信息 |
| borrow_info | id, book_id, reader_id, borrow_date, return_date, is_returned | is_returned 0/1 标记是否已归还 |
| admin | id, username, password | 管理员登录账号 |
4.2 修改 DBUtil 里的数据库连接参数
打开DBUtil.java,你会看到类似这样的代码:
// DBUtil.java 数据库连接工具类 private static final String DRIVER = "com.mysql.jdbc.Driver"; private static final String URL = "jdbc:mysql://localhost:3306/book_manager?useUnicode=true&characterEncoding=utf-8"; private static final String USERNAME = "root"; private static final String PASSWORD = "root"; // 改成你自己 MySQL 的密码这里的USE和PASSWORD一定要改成你本机 MySQL 的实际账号密码。很多同学倒了数据库之后启动项目,Tomcat 控制台报Communications link failure,第一反应是项目有问题,其实十有八九是这里密码没改。
URL 里的characterEncoding=utf-8是必须要保留的参数。不配置的话,插入中文会出现乱码,页面显示全是问号。如果你在改密码时顺手把 URL 改成了jdbc:mysql://localhost:3306/book_manager,那么恭喜,中文乱码坑等着你踩。
4.3 发布到 Tomcat 并验证第一个页面
在 Eclipse 里右键项目 → Run As → Run on Server,Eclipse 会自动完成编译、打包、部署到 Tomcat 的 webapps 目录下。这一步如果一切顺利,控制台会输出类似INFO: Server startup in [xxx] milliseconds的日志。
打开浏览器输入http://localhost:8080/项目名/index.jsp,看到登录页面就是初步成功了。用项目文档里提供的管理员账号密码登录,正常会进入后台首页,显示图书统计信息和菜单导航。
如果这一页没出来,先看 Eclipse 的 Console 面板,找红色报错信息。最常见的三种报错我帮你列一下:
ClassNotFoundException: com.mysql.jdbc.Driver——说明 mysql 驱动 jar 没放进 WEB-INF/lib,检查 Build Path 和部署 Assemblyorg.apache.jasper.JasperException: Unable to compile class for JSP——JSP 文件里有语法错误,通常是编码问题导致HTTP Status 404——访问路径不对,检查 web.xml 里 Servlet 的 url-pattern
这三种我都实际踩过,尤其是第一种,自己明明把 jar 放进 lib 了还报错。后来发现是 Eclipse 的 Deployment Assembly 没把 lib 目录打进发布包。右键项目 → Properties → Deployment Assembly → Add → Folder,把 WebRoot/WEB-INF/lib 加进去,问题解决。
5. 避坑指南:Servlet+JSP 项目部署运行的五个经典坑
5.1 乱码问题:页面显示中文全是问号
现象:登录页能打开,但所有中文显示为???,或者插入数据库的中文变成乱码。
原因:三层编码有一层没统一。最常见的情况是 JSP 页面编码设置了GBK,而数据库是utf8,或者 URL 里没有传characterEncoding参数。也可能是 Tomcat 的server.xml里没有配置 URIEncoding。
解决:统一改成 UTF-8。JSP 文件头部确认pageEncoding="UTF-8";DBUtil.java的 URL 末尾追加?useUnicode=true&characterEncoding=utf-8;在web.xml里加一个 EncodingFilter,强制所有请求和响应走 UTF-8。这份资源自带了一个字符编码过滤器,导入后确认它被正确配置了即可。
<!-- web.xml 中配置编码过滤器 --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>com.xxx.filter.EncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>5.2 数据库连接失败:Unknown database 或 Access denied
现象:Tomcat 启动时报Unknown database 'book_manager'或Access denied for user 'root'@'localhost'。
原因:前者是数据库没创建成功,可能 SQL 脚本执行时因为某条语句报错中断了;后者是 DBUtil 里的账号密码和 MySQL 实际账号不一致,或者 MySQL 的 root 密码为空但你写了个密码,反之亦然。
解决:在 MySQL 命令行执行SHOW DATABASES;,确认book_manager存在。不存在就重新执行脚本;存在但报 Access denied,就用你实际能登录的账号密码去改 DBUtil。MySQL 5.7 的 root 密码默认是安装时手动设置的,别凭印象乱填。
5.3 404 或跳转不到页面:Servlet 路径匹配不上
现象:点击菜单跳转时,地址栏 URL 变了但页面显示 404,或者提示找不到某个 Servlet。
原因:web.xml里配置的<url-pattern>和 JSP 表单里action提交的地址不一致。比如 Servlet 配置的是/bookServlet,但 JSP 里写的是/bookManager,肯定跳不过去。
解决:打开web.xml,逐个核对 servlet-mapping 里的路径,再去 JSP 文件里搜索action=和href=,确保两边的路径完全匹配。最省事的办法是统一在 JSP 里用${pageContext.request.contextPath}拼接绝对路径,这样不管部署在什么上下文下都不会错。
5.4 借书按钮点了没反应:JS 报错或表单提交被拦截
现象:借书操作没有报错,但数据没有写入数据库,页面也不刷新。
原因:这类老项目的前端代码有时还混着原生 JS 和 jQuery,代码里可能引用了本地不存在的 js 文件,导致后续脚本全部失效;或者是表单按钮的类型写成了type="button"而没有绑定 submit 事件。
解决:浏览器按 F12 打开开发者工具,切到 Console 面板,看有没有红色报错。如果有jQuery is not defined,说明 js 文件路径不对;如果按钮绑定的事件没触发,看按钮的type是否写成了button。把type="submit"或手动调用 form.submit() 即可。
5.5 运行文档里的启动步骤和自己电脑对不上
现象:照着运行文档操作,到了某一步界面和文档截图不一样,或者文档写的是 MyEclipse 的操作路径,而你用的是 Eclipse,界面完全不同。
原因:MyEclipse 和 Eclipse 的菜单差异很大,文档按 MyEclipse 截图是很正常的,但你的环境是 Eclipse 就会对不上。同理,文档说导入后直接启动,但你用的 Tomcat 版本是 9 或 10,JDK 是 11,和项目要求的版本体系不匹配。
解决:不要强行对照文档每一步,抓住核心几条:项目导入、数据库导入、JDK/Tomcat 版本确认、DBUtil 配置、启动部署。只要这五步的环境变量和配置文件都正确,项目就能跑起来。版本方面不要用 Tomcat 10,因为 Tomcat 10 把javax.*包换成了jakarta.*,Servlet 代码直接编译不过。这是老项目重跑时最容易忽略的差异。
6. 答辩准备与项目扩容:把课设源码变成自己的作品
6.1 答辩高频问题与回答要点
老师对这份项目的提问集中在这几个方向,你自己心里先有底。第一个必问的是项目整体架构,你要能画出请求流转图并讲出来:JSP 页面发起请求 → Servlet 接收并解析参数 → 调用 JavaBean 中的业务方法 → DAO 层执行 SQL → 返回结果 → Request 域传递数据 → 转发到 JSP 渲染。第二个高频问题是数据库表设计,为什么borrow_info表要单独建,而不是在book表里加一个字段存借阅人——你要回答出“一对多关系拆分”这个点。第三个问题是会话管理,Servlet 里怎么判断用户是登录状态——用HttpSession里的 flag 属性来判断,用户登录成功时就session.setAttribute("user", ...),退出时session.invalidate()。
再有一个容易被追问的细节是,分页是怎么做的。如果原项目没做分页,你可以自己加一个。核心思路是 SQL 用LIMIT offset, pageSize,Servlet 接收页码参数,查询总记录数算出总页数,把当前页数据放进 Request 域,JSP 底部渲染页码链接。这段代码加完后,项目从功能完整变成“有亮点”,答辩印象分会不一样。
6.2 给项目加一个“借阅排行”:推荐的功能小改造
如果你想在答辩时展示一点主动思考,我给个具体的小改造方向:在首页加一个“热门图书 Top 10”排行榜。实现思路是新增一个 SQL 查询,按borrow_info表里每本书的借阅次数倒序排列,取前十条显示在首页。
-- 热门图书排行 SQL:统计每本书被借阅的次数,取前 10 SELECT b.id, b.book_name, COUNT(bi.book_id) AS borrow_count FROM book b LEFT JOIN borrow_info bi ON b.id = bi.book_id GROUP BY b.id, b.book_name ORDER BY borrow_count DESC LIMIT 10;在 DAO 层加一个方法执行这条查询,把结果封装成List<Book>返回。Servlet 里调用它,把排行榜放进 Request 域,首页 JSP 里遍历输出即可。这个改造涉及 SQL 聚合、多表联查、Java 集合传递、JSP 动态渲染,四个技能点全是你亲手写的,讲解起来非常加分的。老师如果问你性能,你就说后续可以加索引优化borrow_info.book_id列。
6.3 答辩前必须跑通的三条路径
给项目写个自查清单,答辩前按顺序走一遍:管理员登录 → 新增一本图书 → 借阅该书 → 归还该书 → 删除该图书。这条流程覆盖了增删改查的完整链路,任何环节报错都必须在答辩前解决。第二条路径是异常流程:用错误密码登录,看是否提示“用户名或密码错误”,并且不能进入后台。第三条是会话超时路径:登录后长时间不操作或直接关闭浏览器,再访问后台页面,应该被过滤器拦截并跳回登录页。三条路径都顺畅,你的项目就稳了。
我记得自己当年答辩前夜,临时把数据库密码改了,没同步改 DBUtil,第二天现场演示直接连不上库,冷汗都下来了。从那以后我每次给课设写文档,第一页都加粗写一行“部署前必检:DBUtil 账号密码与本地 MySQL 一致”,这个习惯也保留到了现在。希望这份拆解能帮你把项目跑顺、把答辩讲好,祝你顺利完成课设。
本文还有配套的精品资源,点击获取