JavaWeb三层架构图书系统:增删改查+Excel导出+权限控制实战

发布时间:2026/10/9 3:21:24
JavaWeb三层架构图书系统:增删改查+Excel导出+权限控制实战
简介本资源是一套高分通过的JavaWeb课程设计项目——图书管理系统源码及配套数据库面向高校计算机专业学生与Java初学者解决课程设计选题、系统开发与部署实践等核心需求。压缩包共352个文件含37个Java源文件、91个class编译文件、91个依赖jar包、41个Excel模板用于数据导入导出、14个HTML页面、12个JavaScript与13个CSS前端资源、11个XML配置文件以及5个SQL脚本和2个JSP动态页面完整覆盖MVC三层架构实现整体大小64.65MB。已有448人学习下载资源经实际运行验证代码结构清晰、注释充分包含用户管理、图书增删改查、借阅记录、Excel批量导入导出等核心功能模块且提供可直接执行的数据库脚本与详细部署说明开箱即用显著降低课程设计落地门槛。1. 这不是又一个“Hello World”图书系统它真能跑通增删改查Excel导出用户权限分离95分背后是三层结构没偷懒你肯定见过那种“JavaWeb图书管理系统”的压缩包——解压进去index.jsp一打开就404Tomcat启动报ClassNotFoundException: com.mysql.jdbc.Driver数据库脚本里连表名都拼错成bookinfo和book_info混用更别说Excel导出功能点一下直接500。但这个95分课程设计不一样它用的是标准ServletJSPMySQL三层架构BookInfoOperate.class和UserInfoOperate.class明确分离业务逻辑AppendUserInExcelService.class这种命名说明作者真写了Excel写入逻辑而不是只贴了个Apache POI的import语句完事。它解决的不是“能不能跑”而是“跑起来后能不能真实模拟图书馆管理员日常操作”——比如批量导入新书时自动校验ISBN格式、删除用户前强制二次确认、导出借阅记录时按日期范围过滤并保留原始Excel样式。适合正在赶JavaWeb课设 deadline 的本科生也适合想快速搭个带权限的后台原型的前端转全栈同学。别被“课程设计”四个字骗了——它的DAO层用了PreparedStatement防SQL注入web.xml里配置了Filter做登录拦截连UserInfoExcelOperate.class里都做了空指针防护这不是交作业的半成品是能当小项目骨架复用的实战组合。2. 拆包即运行从解压到首页展示的六步落地流程含Tomcat 9MySQL 8适配细节2.1 解压后先认准三个核心目录WebContent、src、sql别急着双击start.bat拿到.zip后不要直接双击任何bat文件——这是90%翻车的起点。先解压到一个无中文、无空格的路径例如D:\javaweb-book-system。解压后你会看到三个关键目录WebContent/存放JSP、CSS、JS、WEB-INF含web.xmlsrc/Java源码按包名分层com.book.dao、com.book.service、com.book.servletsql/包含book_system.sql建库脚本和可能的init_data.sql提示如果解压后看到build或target目录说明作者用Maven打包过但本项目未提供pom.xml请忽略这些目录以src和WebContent为准。2.2 数据库初始化MySQL 8必须改密码策略否则root用户连不上进入sql/目录用MySQL客户端执行book_system.sql。但注意MySQL 8默认启用caching_sha2_password认证插件而本项目JDBC连接字符串仍用老式com.mysql.jdbc.Driver对应mysql-connector-java 5.1.x会导致Access denied for user rootlocalhost。解决方案分两步-- 步骤1登录MySQL用安装时设置的root密码 mysql -u root -p -- 步骤2修改root用户认证方式关键 ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY your_new_password; FLUSH PRIVILEGES;然后检查WebContent/WEB-INF/web.xml中数据库配置是否匹配context-param param-namedriver/param-name param-valuecom.mysql.cj.jdbc.Driver/param-value !-- 注意MySQL 8必须用cj版本 -- /context-param context-param param-nameurl/param-name param-valuejdbc:mysql://localhost:3306/book_system?useSSLfalseamp;serverTimezoneGMT%2B8amp;allowPublicKeyRetrievaltrue/param-value /context-param参数说明useSSLfalse关闭SSL课程环境常禁用、serverTimezoneGMT%2B8解决时区报错、allowPublicKeyRetrievaltrue应对MySQL 8.0.23新安全策略。若你用的是MySQL 5.7把com.mysql.cj.jdbc.Driver换回com.mysql.jdbc.DriverURL中去掉allowPublicKeyRetrievaltrue。2.3 Tomcat部署别用IDE一键部署手动拷贝WAR包更可控本项目未提供Maven支持禁止在IDEA/Eclipse里右键→Run on Server——因为web.xml中servlet映射依赖绝对路径IDE自动部署会破坏结构。正确做法将整个WebContent/目录重命名为book_system与数据库名一致把book_system文件夹整体拷贝到Tomcat的webapps/目录下启动Tomcatbin/startup.batWindows或bin/startup.shLinux访问http://localhost:8080/book_system/login.jsp为什么不用WAR因为课程设计常要求手动生成WAR验证打包能力。若需生成进入WebContent父目录执行jar -cvf book_system.war .注意末尾的.再把war包丢进webapps/Tomcat会自动解压。2.4 首次登录账号admin/admin 是后门但密码明文存于login.jsp需立即修改项目默认账号密码为admin/admin但密码未加密直接明文写在login.jsp的form里input typepassword namepassword valueadmin / !-- 危险 --这显然不符合课程设计评分标准安全项扣分。实际登录后应立即修改进入src/com/book/dao/UserInfoOperate.java找到checkUser方法其SQL为String sql SELECT * FROM user_info WHERE username? AND password?;密码存储在user_info表的password字段当前为明文存储。若要升级为BCrypt加密需替换DAO层逻辑并修改注册/登录Servlet中密码处理部分。2.5 功能验证清单五个必测动作漏一个就说明环境没配对动作预期结果关键路径失败信号登录管理员账号跳转到main.jsp显示“欢迎 admin”/login.jsp → /servlet/LoginServlet404或500检查web.xml中LoginServlet的servlet-class是否为com.book.servlet.LoginServlet添加一本新书book_info表新增记录ISBN校验位自动计算/addBook.jsp → /servlet/AddBookServlet提交后页面空白检查AddBookServlet中request.setCharacterEncoding(UTF-8)是否缺失中文乱码查询所有用户表格列出user_info全部数据含角色字段/showAllUsers.jsp → /servlet/ShowAllUsersServlet表格为空检查UserInfoOperate.java中selectAllUsers()的SQL是否为SELECT * FROM user_info非user或users导出用户列表到Excel下载users_export.xls含表头和数据点击“导出Excel”按钮 →AppendUserInExcelService.class触发下载文件打不开检查poi-3.17.jar是否在WEB-INF/lib/下缺jar包则500删除一个用户数据库记录消失页面刷新后不再显示/servlet/DeleteUserServlet?idxxx删除后仍存在检查DeleteUserServlet中id参数获取是否用request.getParameter(id)非getId()3. 三层架构怎么分的看懂DAO/Service/Servlet的职责边界才能改代码3.1 DAO层BookInfoOperate.class不是工具类是数据访问契约src/com/book/dao/BookInfoOperate.java是典型的DAO实现但它没用Hibernate或MyBatis而是纯JDBC封装。关键点在于所有方法返回boolean或ListBookInfo不暴露Connection对象addBook()方法中使用PreparedStatement预编译防止SQL注入getBookById()里rs.getString(isbn)的字段名必须与数据库book_info.isbn列名完全一致大小写敏感MySQL在Linux下区分大小写。public boolean addBook(BookInfo book) { String sql INSERT INTO book_info (isbn, title, author, price, stock) VALUES (?, ?, ?, ?, ?); try (Connection conn JDBCUtil.getConnection(); PreparedStatement pstmt conn.prepareStatement(sql)) { pstmt.setString(1, book.getIsbn()); pstmt.setString(2, book.getTitle()); pstmt.setString(3, book.getAuthor()); pstmt.setDouble(4, book.getPrice()); pstmt.setInt(5, book.getStock()); return pstmt.executeUpdate() 0; // executeUpdate返回影响行数 } catch (SQLException e) { e.printStackTrace(); return false; } }参数说明JDBCUtil.getConnection()是自定义工具类读取web.xml中的数据库参数。若修改数据库配置只需改web.xml无需动DAO代码——这就是DAO层的价值。3.2 Service层AppendUserInExcelService.class藏着Excel导出的玄学细节src/com/book/service/AppendUserInExcelService.java负责Excel生成但它不是简单调用POI API而是处理了课程设计常被忽略的细节使用HSSFWorkbook.xls格式而非XSSFWorkbook.xlsx兼容老版Excel设置单元格样式标题行加粗、居中、背景色#C0C0C0对user_info.role字段做枚举转换0→管理员, 1→普通用户避免导出数字ID。// 关键创建HSSFCellStyle控制样式 HSSFCellStyle style workbook.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER); style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); style.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 写入角色字段时做映射 String roleStr user.getRole().equals(0) ? 管理员 : 普通用户; cell.setCellValue(roleStr);注意若你遇到导出Excel后中文乱码不是POI问题是response.setContentType没设对。检查ExportUserServlet.java中response.setContentType(application/vnd.ms-excel;charsetUTF-8); response.setHeader(Content-Disposition, attachment;filenameusers_export.xls);3.3 Servlet层LoginServlet.class的请求流转逻辑决定权限控制成败src/com/book/servlet/LoginServlet.java是入口控制器它的设计暴露了权限控制的脆弱点登录成功后把用户对象存入sessionrequest.getSession().setAttribute(user, user)但main.jsp顶部仅用session.getAttribute(user) ! null判断登录态没校验角色若用户直接访问http://localhost:8080/book_system/main.jspsession为空时会NPE。// LoginServlet中关键逻辑 if (userInfo ! null) { HttpSession session request.getSession(); session.setAttribute(user, userInfo); // 存的是UserInfo对象 response.sendRedirect(main.jsp); } else { request.setAttribute(msg, 用户名或密码错误); request.getRequestDispatcher(login.jsp).forward(request, response); }改进方案在main.jsp顶部加角色校验% UserInfo user (UserInfo) session.getAttribute(user); if (user null || !0.equals(user.getRole())) { // 只有role0才允许进main response.sendRedirect(login.jsp); return; } %3.4 JSP层showAllBooks.jsp里的EL表达式为什么总报错WebContent/showAllBooks.jsp用EL表达式遍历书籍列表c:forEach items${bookList} varbook tr td${book.isbn}/td td${book.title}/td td${book.author}/td /tr /c:forEach但常报javax.el.PropertyNotFoundException: Property isbn not found。原因有三BookInfo实体类缺少getter方法必须有public String getIsbn(){return isbn;}注意是getIsbn不是getisbnbookList存入request时key名不匹配ShowAllBooksServlet.java中必须是request.setAttribute(bookList, list)没引入JSTL标签库JSP顶部必须有% taglib prefixc urihttp://java.sun.com/jsp/jstl/core %。血泪经验实体类字段名private String isbn;对应的getter必须严格遵循JavaBean规范——首字母大写即getIsbn()。写成getisbn()或getISBN()都会导致EL失效。4. 避坑指南五个真实踩过的坑每个都让调试时间翻倍4.1 现象启动Tomcat后访问/book_system/login.jsp报404原因WebContent目录未重命名为book_system或拷贝时漏掉了WEB-INF文件夹Tomcat识别不到web应用解决检查tomcat/webapps/book_system/WEB-INF/web.xml是否存在若不存在重新完整拷贝WebContent目录并重命名。4.2 现象登录成功后跳转到空白页浏览器地址栏显示/book_system/main.jsp原因main.jsp中${user.username}取值失败因LoginServlet存入session的key是user但main.jsp里写成了${sessionScope.user.name}字段名应为username非name解决统一实体类字段名与getter方法名UserInfo.java中确保有private String username;和public String getUsername(){return username;}。4.3 现象点击“添加图书”提交后数据库没新增页面卡住原因AddBookServlet.java中未设置请求编码中文标题/作者乱码导致SQL插入失败如title乱码解决在doPost方法开头添加request.setCharacterEncoding(UTF-8);且必须在request.getParameter()之前调用。4.4 现象导出Excel功能点击无反应控制台无报错原因WEB-INF/lib/下缺少poi-3.17.jar但AppendUserInExcelService.class已编译运行时抛NoClassDefFoundError被静默吞掉解决下载 Apache POI 3.17 解压后将poi-3.17.jar、poi-scratchpad-3.17.jar、poi-ooxml-3.17.jar全部放入WEB-INF/lib/。4.5 现象修改UserInfoOperate.java后重启Tomcat仍执行旧逻辑原因Tomcat热部署未生效WEB-INF/classes/下的class文件未更新IDEA/Eclipse未开启自动编译或手动编译后未覆盖解决停止Tomcat → 删除tomcat/webapps/book_system/WEB-INF/classes/com/book/dao/UserInfoOperate.class→ 用javac -cp WEB-INF/lib/* -d WEB-INF/classes src/com/book/dao/UserInfoOperate.java重新编译 → 启动Tomcat。5. 进阶改造把课程设计变成可商用的后台三个必须动手的升级点5.1 数据库层升级从明文密码到BCrypt加密五步完成安全加固课程设计密码明文存储是硬伤升级BCrypt需改动三处步骤1添加BCrypt依赖下载bcrypt-3.1.jar放入WEB-INF/lib/。步骤2修改注册逻辑在RegisterServlet.java中密码加密后存库String rawPassword request.getParameter(password); String hashedPassword BCrypt.hashpw(rawPassword, BCrypt.gensalt()); // 生成盐并加密 user.setPassword(hashedPassword); new UserInfoOperate().addUser(user); // 存入hash后的密码步骤3修改登录校验UserInfoOperate.java中checkUser()方法改为public UserInfo checkUser(String username, String password) { String sql SELECT * FROM user_info WHERE username?; // ... 获取结果集rs ... if (rs.next()) { String storedHash rs.getString(password); if (BCrypt.checkpw(password, storedHash)) { // 用BCrypt校验 return new UserInfo(...); } } return null; }步骤4清理测试数据执行SQL清空旧用户DELETE FROM user_info WHERE username ! admin;再用新注册流程重建账号。步骤5前端密码输入框加强度提示在register.jsp中添加JavaScript实时校验function checkPasswordStrength() { const pwd document.getElementById(password).value; if (pwd.length 6) { alert(密码至少6位); return false; } if (!/[A-Z]/.test(pwd) || !/[a-z]/.test(pwd) || !/\d/.test(pwd)) { alert(密码需包含大小写字母和数字); return false; } return true; }5.2 前端体验升级用AJAX替代页面跳转实现无刷新操作原系统所有操作都整页刷新用户体验差。以“删除图书”为例改造为AJAX后端新建DeleteBookAjaxServlet.java返回JSONprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String isbn request.getParameter(isbn); boolean success new BookInfoOperate().deleteBookByIsbn(isbn); response.setContentType(application/json;charsetUTF-8); response.getWriter().write({\success\: success }); }前端在showAllBooks.jsp中绑定删除按钮事件function deleteBook(isbn) { if (!confirm(确定删除这本书)) return; fetch(servlet/DeleteBookAjaxServlet, { method: POST, headers: {Content-Type: application/x-www-form-urlencoded}, body: isbn isbn }) .then(res res.json()) .then(data { if (data.success) { alert(删除成功); location.reload(); // 或用DOM操作移除TR行 } else { alert(删除失败); } }); }注意AJAX需处理CSRF课程设计可暂略但商用必须加token校验。5.3 权限控制升级从角色字符串到RBAC模型四张表撑起完整权限体系当前user_info.role字段0/1无法支撑复杂权限。升级为RBAC需建四张表表名字段说明sys_userid, username, password, status用户主表原user_info精简sys_roleid, role_name, description角色表如“图书管理员”、“借阅员”sys_permissionid, perm_code, perm_name, url_pattern权限表如book:add,/servlet/AddBookServletsys_user_roleuser_id, role_id用户-角色关联表sys_role_permrole_id, perm_id角色-权限关联表改造要点LoginServlet登录后从数据库查出用户所有权限URL存入sessionsession.setAttribute(perms, permList)自定义Filter拦截请求校验request.getRequestURI()是否在权限列表中main.jsp侧边栏根据权限动态渲染菜单项。从那以后我每次接手课程设计源码第一件事就是打开UserInfoOperate.java看密码字段怎么存的——如果还是明文立刻停下手头工作先做BCrypt升级。不是为了炫技而是因为去年帮学弟调试时他导出的Excel里用户密码被老师当堂打开投影仪展示全场安静了三分钟。希望帮到你。本文还有配套的精品资源点击获取