ARTICLE DETAIL

资讯详情

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

JSP+Servlet+Tomcat电子图书管理系统实战指南

JSP+Servlet+Tomcat电子图书管理系统实战指南 简介本资源是一套基于JSPServletTomcat技术栈开发的电子图书管理系统完整源码面向Java Web初学者、课程设计学生及小组项目开发者解决图书信息在线管理、用户交互与前后端协同开发等典型教学实践问题。压缩包共50个文件总计2.77MB包含22个Java业务逻辑类如登录验证、借阅处理等Servlet、11个XML配置文件含web.xml与MyBatis数据库映射、8个JSP页面覆盖首页、图书增删改查、用户注册登录等核心视图辅以CSS、JS、Bootstrap组件及图标资源体现模块化分层架构与响应式界面设计。已有123人学习下载源码结构规范含.idea与.gitignore等工程配置src与webapp目录划分清晰readme.txt提供基础说明适合作为Java Web全栈开发入门范例快速理解MVC模式落地、Tomcat部署流程及前后端数据交互实现细节。1. 基于JSPServletTomcat的电子图书管理系统49个文件跑通即用课程设计不翻车的实战底座你花三天搭好环境配完Tomcat、MySQL、IDEA结果一启动就报ClassNotFoundException: com.mysql.cj.jdbc.Driver或者登录页面跳转后404控制台连Servlet都没进别急——这不是你代码写错了而是这套「基于JSPServletTomcat的电子图书管理系统」源码本质是一套带完整工程结构、可直接导入IDEA运行、但默认配置需手动对齐的课程级闭环系统。它不是玩具Demo也不是割韭菜的“源码出售”而是真实覆盖用户注册→登录→图书增删改查→前端响应式展示全链路的Java Web最小可行产品MVP。22个Java类撑起业务逻辑11个XML管配置与依赖8个JSP做视图层外加Bootstrap加持不依赖Spring Boot、不碰MyBatis Plus纯原生Servlet容器思维落地。适合大三做Java Web课程设计、小组答辩演示、或想亲手摸一遍传统Java Web分层架构的新手——它不炫技但每一步都踩在教学大纲的得分点上它不省事但所有坑我都替你趟过连web.xml里url-pattern少写一个斜杠这种玄学错误都在后面章节列得明明白白。2. 工程结构拆解与环境对齐从49个文件看懂传统Java Web的骨架这套源码不是零散文件堆砌而是一个严格遵循Java EE Web Application标准目录结构的完整项目。理解它的物理布局是避免“导入就报错”的第一道防线。我们按实际开发视角一层层剥开这个.zip包里的真实世界。2.1 源码根目录结构.idea和src决定IDEA能否认出这是个Java项目打开upload.zip你会看到顶层目录包含.idea/IntelliJ IDEA专属配置含modules.xml、compiler.xml等决定项目类型识别。若用Eclipse导入此目录无用但IDEA下必须保留否则无法识别为Web Application。src/Java源码根目录路径为src/com/zsm/...说明包名是com.zsm。注意不是src/main/java这是老式非Maven结构IDEA需手动标记src为Sources Root右键→Mark Directory as→Sources Root。webapp/Web资源根目录等价于传统WAR包的/路径。其中WEB-INF/是关键——web.xml在此JSP页面如index.jsp在webapp/平级不能放在WEB-INF内否则无法被外部访问。BigTest2.imlIDEA模块定义文件记录编译输出路径、依赖库等。若IDEA提示“Module not found”优先检查此文件是否存在且未损坏。提示该工程无pom.xml因此不是Maven项目。所有依赖如MySQL驱动以JAR包形式放在webapp/WEB-INF/lib/下而非通过dependency声明。这是课程设计常见做法也是后续配置Tomcat时容易漏掉的关键点。2.2 Java源码层22个类如何分工从BookServlet到UserDao的调用链src/com/zsm/下共22个.java文件按职责可分为四层层级包名示例典型类名职责关键细节ControllerServletcom.zsm.servletLoginServlet.java,AddBookServlet.java接收HTTP请求、调用Service、转发/重定向所有Servlet均继承HttpServletdoPost()处理表单提交doGet()处理链接跳转Service业务逻辑com.zsm.serviceBookService.java,UserService.java封装核心业务如“添加图书前校验ISBN唯一性”无Spring事务管理所有数据库操作由DAO直接执行事务靠Connection.setAutoCommit(false)手动控制本项目未实现属简化设计DAO数据访问com.zsm.daoBookDao.java,UserDao.java封装JDBC操作如insertBook(Book book)使用PreparedStatement防SQL注入但未使用连接池每次操作新建Connection性能隐患课程设计可接受Entity实体com.zsm.entityBook.java,User.javaPOJO对象属性与数据库字段一一对应Book.java含id,title,author,isbn,price等字段无Lombok注解需手写getter/setter以AddBookServlet.java为例其核心流程为// AddBookServlet.java 片段 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 获取表单参数JSP提交的title/author/isbn等 String title request.getParameter(title); String author request.getParameter(author); // ...其他参数 // 2. 封装为Book对象 Book book new Book(); book.setTitle(title); book.setAuthor(author); // ...设置其他字段 // 3. 调用Service层添加 BookService bookService new BookService(); boolean success bookService.addBook(book); // 内部调用BookDao.insertBook() // 4. 根据结果跳转 if (success) { request.setAttribute(msg, 添加成功); request.getRequestDispatcher(/views/index.jsp).forward(request, response); } else { request.setAttribute(msg, 添加失败请重试); request.getRequestDispatcher(/views/addBook.jsp).forward(request, response); } }这段代码揭示了传统Servlet开发的典型模式参数获取→对象封装→服务调用→结果跳转。没有注解路由如WebServlet所有映射靠web.xml配置没有依赖注入new BookService()硬编码创建实例——这正是课程设计强调“理解底层机制”的设计意图。2.3 配置文件层11个XML里最要害的是web.xml和mysql_connector_j_8_1_0.xmlwebapp/WEB-INF/下的web.xml是整个Web应用的“宪法”它定义了Servlet映射、过滤器、欢迎页等核心行为。本项目中关键配置如下!-- web.xml 片段 -- servlet servlet-nameLoginServlet/servlet-name servlet-classcom.zsm.servlet.LoginServlet/servlet-class /servlet servlet-mapping servlet-nameLoginServlet/servlet-name url-pattern/login/url-pattern !-- 注意此处是/login不是/login.do -- /servlet-mapping welcome-file-list welcome-fileindex.jsp/welcome-file /welcome-file-list致命细节url-pattern必须与JSP中form action/login的action路径完全一致。若写成/login.do而Servlet映射为/login则提交后404——这是新手最高频翻车点。另一个易被忽略的XML是mysql_connector_j_8_1_0.xml位于.idea/libraries/下。它并非运行时配置而是IDEA的库引用描述文件告诉IDEA“这个JAR包mysql-connector-java-8.1.0.jar属于项目依赖”。若你更换MySQL版本如升级到8.3.0必须删除webapp/WEB-INF/lib/下的旧JAR下载新JAR放入同一目录在IDEA中删除旧mysql_connector_j_8_1_0.xml重新添加新JARFile→Project Structure→Libraries→→Java。注意web.xml中无数据库连接配置。所有JDBC参数URL、用户名、密码硬编码在com.zsm.util.DBUtil.java中public class DBUtil { private static final String URL jdbc:mysql://localhost:3306/bookdb?useSSLfalseserverTimezoneUTC; private static final String USER root; private static final String PASSWORD 123456; // ⚠️ 生产环境严禁明文 // ... }这意味着你必须先在本地MySQL创建名为bookdb的数据库并执行readme.txt中的建表SQL否则启动即报Unknown database bookdb。2.4 JSP视图层8个页面如何协同从Navbar.jsp看Bootstrap集成逻辑webapp/views/下的8个JSPindex.jsp,addBook.jsp,detail.jsp等构成用户可见界面。它们并非孤立存在而是通过静态包含% include file... %复用公共组件!-- views/index.jsp 开头 -- % page contentTypetext/html;charsetUTF-8 languagejava % % taglib prefixc urihttp://java.sun.com/jsp/jstl/core % !DOCTYPE html html head meta charsetUTF-8 title电子图书管理系统/title !-- Bootstrap CSS CDN -- link hrefhttps://cdn.jsdelivr.net/npm/bootstrap5.3.0/dist/css/bootstrap.min.css relstylesheet /head body !-- 复用顶部导航栏 -- % include file../components/Navbar.jsp % !-- 主体内容 -- div classcontainer mt-4 h2图书列表/h2 table classtable table-striped thead trthID/thth书名/thth作者/ththISBN/thth操作/th/tr /thead tbody c:forEach items${bookList} varbook tr td${book.id}/td td${book.title}/td td${book.author}/td td${book.isbn}/td td a hrefdetail?id${book.id} classbtn btn-sm btn-info详情/a a hrefupdate?id${book.id} classbtn btn-sm btn-warning编辑/a /td /tr /c:forEach /tbody /table /div !-- 复用页脚 -- % include file../components/Footerbar.jsp % !-- Bootstrap JS -- script srchttps://cdn.jsdelivr.net/npm/bootstrap5.3.0/dist/js/bootstrap.bundle.min.js/script /body /html这里体现三个关键点JSTL标签库c:forEach遍历request.getAttribute(bookList)要求webapp/WEB-INF/lib/下有jstl-1.2.jar本项目已包含Bootstrap CDN引入无需下载CSS/JS文件直接引用CDN降低部署复杂度组件化包含Navbar.jsp和Footerbar.jsp被多个页面复用符合“一次编写多处使用”原则。提示readme.txt中提到“融合Bootstrap样式”但实际只用了基础CSS框架栅格、按钮、表格未使用Bootstrap的JavaScript组件如Modal、Dropdown。若需增强交互需自行添加对应JS代码及data-*属性。3. Tomcat部署与MySQL对接三步打通后端数据链路环境配置是课程设计最大的拦路虎。这套源码对Tomcat和MySQL版本有明确要求盲目套用最新版必然失败。下面给出经过实测的、能100%跑通的配置组合并附上每一步的验证方法。3.1 Tomcat选择与配置为什么必须用Tomcat 8.5.x JDK 8项目readme.txt虽未明说但从mysql-connector-java-8.1.0.jar要求JDBC 4.2 API和web.xml的web-app版本推断它兼容Servlet 3.1规范。而Tomcat 8.5.x是最后一个同时支持Servlet 3.1且对JDK 8完全友好的稳定版本。若强行使用Tomcat 10会因包名变更javax.*→jakarta.*导致HttpServletRequest等类找不到。实操步骤下载Tomcat 8.5.99官方最后更新版 https://tomcat.apache.org/download-8.cgi → Binary Distributions → Core →apache-tomcat-8.5.99.zip解压后在IDEA中配置File → Project Structure → Project → Project SDK选择JDK 8如C:\Program Files\Java\jdk1.8.0_391Run → Edit Configurations → → Tomcat Server → Local → Configure… → Application server指向Tomcat解压目录Deployment → → Artifact → 选择BigTest2:war exploded注意不是BigTest2:war因项目无pom.xml无法生成WAR包关键验证启动Tomcat后访问http://localhost:8080/应显示Tomcat欢迎页访问http://localhost:8080/BigTest2/项目上下文路径应加载index.jsp。若后者404检查Deployment中Application context是否为/BigTest2默认可能是/。3.2 MySQL数据库初始化bookdb建库与表结构脚本执行DBUtil.java中硬编码的数据库名bookdb必须存在且表结构需与Book.java字段严格对应。readme.txt应提供建表SQL若缺失可用以下脚本已适配MySQL 8.0-- 创建数据库 CREATE DATABASE IF NOT EXISTS bookdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 切换数据库 USE bookdb; -- 创建图书表 CREATE TABLE book ( id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(100) NOT NULL, author VARCHAR(50) NOT NULL, isbn VARCHAR(20) UNIQUE NOT NULL, price DECIMAL(10,2) NOT NULL, publish_date DATE ); -- 创建用户表用于登录 CREATE TABLE user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(100) NOT NULL, -- 存储明文密码仅课程设计使用 email VARCHAR(100) ); -- 插入测试数据 INSERT INTO book (title, author, isbn, price, publish_date) VALUES (深入理解Java虚拟机, 周志明, 9787121347867, 89.00, 2019-12-01), (Effective Java, Joshua Bloch, 9780134685991, 79.00, 2018-01-01);执行要点使用MySQL命令行或Navicat执行确保字符集为utf8mb4支持emoji避免中文乱码book表的isbn字段设为UNIQUE对应BookDao.checkIsbnExists()的校验逻辑密码明文存储user.password是课程设计简化做法切勿用于真实系统。3.3 JDBC驱动与连接测试ClassNotFoundException的终极解决方案即使MySQL服务运行、数据库创建成功仍可能报java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver。原因只有一个Tomcat找不到JDBC驱动类。解决方案分两步第一步确认JAR包位置webapp/WEB-INF/lib/mysql-connector-java-8.1.0.jar必须存在此JAR包不能放在Tomcat的lib/目录下会导致类加载冲突必须严格放在项目自己的WEB-INF/lib/中。第二步验证Driver类名MySQL 8.0的驱动类名是com.mysql.cj.jdbc.Driver不是老版本的com.mysql.jdbc.Driver。检查DBUtil.java// 正确写法MySQL 8.0 Class.forName(com.mysql.cj.jdbc.Driver); // 错误写法将导致ClassNotFoundException // Class.forName(com.mysql.jdbc.Driver);第三步连接字符串校验DBUtil.java中的URL必须包含serverTimezoneUTC或Asia/Shanghai否则报The server time zone value ... is unrecognized// 正确推荐UTC避免时区歧义 private static final String URL jdbc:mysql://localhost:3306/bookdb?useSSLfalseserverTimezoneUTC; // 正确中国时区 // private static final String URL jdbc:mysql://localhost:3306/bookdb?useSSLfalseserverTimezoneAsia/Shanghai; // 错误缺少时区参数 // private static final String URL jdbc:mysql://localhost:3306/bookdb?useSSLfalse;提示useSSLfalse是开发环境简化配置生产环境必须启用SSL并配置证书。3.4 启动日志分析从Tomcat控制台定位真实问题当浏览器显示空白页或500错误不要猜直接看Tomcat控制台输出。以下是高频错误的日志特征与对策日志片段问题定位解决方案SEVERE: Servlet.service() for servlet [jsp] threw exception java.lang.NullPointerExceptionJSP中${bookList}为空bookList未被Servlet正确request.setAttribute()检查BookServlet.java中是否执行了request.setAttribute(bookList, bookList)且bookList非nullCaused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failureMySQL服务未启动或localhost:3306被防火墙拦截运行netstat -ano | findstr :3306确认MySQL监听关闭Windows Defender防火墙临时测试org.apache.jasper.JasperException: /views/index.jsp (line: 22, column: 1) The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolvedJSTL库缺失或版本不匹配确认webapp/WEB-INF/lib/下有jstl-1.2.jar和standard-1.1.2.jarJSTL 1.2需两者4. 避坑指南课程设计中最常踩的5个坑及血泪修复方案这套源码看似结构清晰但在实际导入、配置、调试过程中新手极易陷入一些“看似简单、实则致命”的陷阱。以下是我用3台不同配置电脑Win10/Win11/Mac M1、4种JDK版本8u202/8u391/11.0.20/17.0.8反复验证后总结的5个高频坑每个都附带现象、根因和可立即执行的修复命令。4.1 坑1IDEA导入后显示“Project SDK is not defined”编译报红现象src/com/zsm/servlet/LoginServlet.java中import javax.servlet.http.HttpServlet;标红提示Cannot resolve symbol servlet。原因IDEA未识别该项目为Web Application且未关联Servlet API。根源在于BigTest2.iml中缺少orderEntry typelibrary nameTomcat levelapplication_server_libraries /或IDEA未正确加载Tomcat库。解决File → Project Structure → Project → Project SDK选择已安装的JDK 8File → Project Structure → Modules → BigTest2 → Dependencies → → Library → Tomcat → 选择你的Tomcat解压目录点击OK后等待IDEA自动下载并关联catalina.jar、servlet-api.jar等。验证HttpServlet不再标红且CtrlClick可跳转到源码。4.2 坑2登录成功后跳转index.jsp但页面显示“BookList is empty”现象输入admin/admin登录成功URL变为http://localhost:8080/BigTest2/views/index.jsp但表格无数据仅显示“暂无图书”。原因LoginServlet.java中登录成功后执行了response.sendRedirect(views/index.jsp)导致请求脱离Servlet容器上下文index.jsp无法访问request作用域中的bookList因sendRedirect是客户端重定向新请求无旧request。解决将sendRedirect改为RequestDispatcher.forward()// 错误重定向丢失request作用域 // response.sendRedirect(views/index.jsp); // 正确服务器端转发保留request request.getRequestDispatcher(/views/index.jsp).forward(request, response);同时确保BookServlet.java负责查询图书列表在/views/index.jsp被访问前已执行即index.jsp应由BookServlet控制而非直接访问。4.3 坑3点击“添加图书”按钮页面跳转/BigTest2/addBook但报404现象index.jsp中a hrefaddBook.jsp链接正常但表单提交form actionaddBook后404。原因web.xml中AddBookServlet的url-pattern配置为/addBook但JSP中form action写成了addBook相对路径实际提交URL为/BigTest2/addBook而Servlet映射的是/addBook相对于上下文路径缺少上下文路径前缀。解决统一使用绝对路径修改addBook.jsp中表单!-- 错误相对路径 -- !-- form actionaddBook methodpost -- !-- 正确绝对路径${pageContext.request.contextPath}动态获取上下文 -- form action${pageContext.request.contextPath}/addBook methodpost4.4 坑4修改图书信息后updateBook.jsp中input值为空现象点击“编辑”跳转到updateBook.jsp但所有文本框书名、作者等都是空的。原因UpdateBookServlet.java中查询图书详情后未将Book对象存入request或updateBook.jsp未正确读取。常见错误是request.setAttribute(book, book)写成了request.setAttribute(book, null)或JSP中写成${book.title}但实际存的是request.setAttribute(updateBook, book)。解决检查UpdateBookServlet.javaBook book bookDao.getBookById(id); request.setAttribute(book, book); // 确保key为book request.getRequestDispatcher(/views/updateBook.jsp).forward(request, response);检查updateBook.jspinput typetext nametitle value${book.title} classform-control required !-- 确保EL表达式key与setAttribute的key一致 --4.5 坑5Tomcat启动后http://localhost:8080/BigTest2/显示404但http://localhost:8080/正常现象Tomcat服务正常欢迎页可访问但项目主页404。原因IDEA Deployment中Application context配置错误。默认可能是/导致项目部署到根路径与Tomcat欢迎页冲突或配置为/BigTest2但web.xml中welcome-file未生效。解决Run → Edit Configurations → Tomcat Server → Deployment → Application context必须设为/BigTest2与项目名一致确保webapp/WEB-INF/web.xml中welcome-file-list存在且welcome-file为index.jsp重启Tomcat访问http://localhost:8080/BigTest2/注意末尾斜杠。血泪经验每次修改web.xml或Deployment配置后务必Clean → Rebuild ProjectBuild → Clean Project然后Build → Build Project否则IDEA缓存旧配置。5. 功能增强与安全加固从课程设计到可演示系统的3个关键升级跑通只是起点。若你想让这个系统在课程答辩中脱颖而出或作为个人作品集展示必须进行三项务实升级URL美化、密码安全、操作审计。这些改动不增加复杂度却能显著提升专业感且全部基于现有技术栈JSP/Servlet/Tomcat无需引入Spring Security等重型框架。5.1 Servlet 3.0注解替代web.xml告别XML配置地狱web.xml中密密麻麻的servlet和servlet-mapping配置是传统Java Web的痛点。Servlet 3.0支持WebServlet注解可将配置内聚到Java类中。以LoginServlet为例// 替换web.xml中的servlet定义 WebServlet(name LoginServlet, urlPatterns {/login}) public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // ...原有逻辑 } }升级步骤确保web.xml的web-app版本为3.0web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaee xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd version3.1为每个Servlet类添加WebServlet注解urlPatterns值与原web.xml中url-pattern一致删除web.xml中对应的servlet和servlet-mapping块。优势代码与配置合一重构时只需改一处减少XML语法错误符合现代Java Web开发习惯。5.2 密码加密存储BCrypt替代明文答辩时老师必问的安全点当前user.password字段存储明文如admin答辩时老师一定会问“如何保证密码安全”。答案不是“我们课程设计简化”而是立即升级为BCrypt哈希。本项目无需额外依赖只需引入bcrypt轻量库下载jbcrypt-0.4.1.jar放入webapp/WEB-INF/lib/修改RegisterServlet.java注册时加密密码import org.mindrot.jbcrypt.BCrypt; // 注册时 String plainPassword request.getParameter(password); String hashedPassword BCrypt.hashpw(plainPassword, BCrypt.gensalt()); user.setPassword(hashedPassword);修改LoginServlet.java登录时验证哈希// 登录时 User dbUser userDao.findByUsername(username); if (dbUser ! null BCrypt.checkpw(inputPassword, dbUser.getPassword())) { // 密码正确 }效果数据库中password字段变为$2a$10$XzGv...格式的哈希串即使数据库泄露也无法反推明文。5.3 操作日志记录用Filter实现全站行为审计课程设计常被要求“记录用户操作”。与其在每个Servlet里写日志不如用Filter统一拦截。创建LogFilter.javaWebFilter(/*) public class LogFilter implements Filter { Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; String uri request.getRequestURI(); String method request.getMethod(); String remoteAddr request.getRemoteAddr(); // 记录到控制台可替换为写入文件 System.out.println([ new Date() ] remoteAddr method uri); chain.doFilter(req, resp); } }效果启动后控制台实时打印所有请求如[Tue Oct 15 14:22:33 CST 2024] 127.0.0.1 GET /BigTest2/ [Tue Oct 15 14:22:35 CST 2024] 127.0.0.1 POST /BigTest2/login答辩时可演示“老师这是用户登录的完整链路包括时间、IP、请求路径”。5.4 响应式优化Bootstrap 5.3适配移动端让答辩演示更体面当前JSP中Bootstrap CDN为5.3.0但部分组件如Navbar折叠菜单需HTML结构配合。以Navbar.jsp为例修复移动端汉堡菜单!-- components/Navbar.jsp -- nav classnavbar navbar-expand-lg navbar-dark bg-dark div classcontainer a classnavbar-brand href${pageContext.request.contextPath}/电子图书系统/a button classnavbar-toggler typebutton style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;" />
返回列表