ARTICLE DETAIL

资讯详情

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

JavaWeb超市系统毕业设计最小可行体实战指南

JavaWeb超市系统毕业设计最小可行体实战指南 简介这是一套面向计算机专业本科生毕业设计与JavaWeb初学者实战训练的超市管理系统完整源码包聚焦B/S架构下的业务管理场景帮助学习者掌握JSPServletJDBC全栈开发流程及MySQL数据库设计与操作。资源包含68个文件涵盖19个核心Java源文件、37个编译后Class字节码、4个建库建表SQL脚本含员工、商品、进货、销售等关键数据表、2个系统界面截图及必要Jar依赖与Eclipse项目配置文件.project/.classpath/.prefs总大小仅3.5MB轻量易部署。已有797人学习下载适合快速搭建本地开发环境并调试运行。读者可直接获取可运行的完整系统含双角色权限员工/管理员、八大功能模块从系统登录、员工与商品管理到进货销售全流程、结构清晰的MVC分层目录src下dao/view/pojo/utils等以及配套数据库脚本与项目说明文档显著降低毕设启动门槛与调试成本。1. 这不是“又一个超市系统”它是一份能跑通、能改、能答辩的 JavaWeb 毕业设计最小可行体你搜“JavaWeb 超市管理系统 毕业设计”页面刷出几百个同名 ZIP 包——点开全是 JSPServletMySQL 的老三件目录结构雷同登录页写着“欢迎来到XX超市”连验证码都用的Random生成四位数字。但真正卡住你的从来不是“有没有源码”而是为什么本地 Tomcat 启动后访问 8080 页面空白为什么 login.jsp 提交后跳转 404为什么数据库导入了却提示Unknown column user_name in field list为什么答辩老师问“事务怎么控制的”你只能翻着代码说“我用了 conn.setAutoCommit(false)”这个标题里的.zip文件本质是一个被压缩过的“毕业设计最小可行体MVP”它不追求高并发、不带微服务、没用 Spring Boot 自动装配但它必须满足三个硬约束——能在 JDK 8 Tomcat 8.5 MySQL 5.7 环境下 10 分钟内跑起来所有增删改查逻辑可追踪到具体 Servlet 和 SQL数据库表结构与 Java 实体类字段严格对齐没有驼峰/下划线错位。它不是工业级系统而是专为计算机专业本科生设计的“答辩友好型”载体功能完整商品/员工/库存/销售单、边界清晰无第三方支付/短信/物流集成、技术栈透明JSP 前端 Servlet 控制层 JDBC 数据层。如果你正被开题报告 deadline 追着跑或刚在 IDEA 里配完 Tomcat 却卡在ClassNotFoundException: com.mysql.jdbc.Driver这篇笔记就是为你写的——我们不讲 MVC 理论只拆解从解压 ZIP 到点击“结账”按钮弹出成功提示的每一步真实操作。2. 解压即启动环境配置与项目结构破译2.1 环境版本锁死为什么必须用 JDK 8 Tomcat 8.5 MySQL 5.7这个 ZIP 包的build.xmlAnt 构建脚本和web.xml中明确声明了 Servlet 3.0 规范而 Servlet 3.0 是 JDK 8 的默认支持上限。若你强行用 JDK 17 启动会直接报错java.lang.UnsupportedClassVersionError: com/supermarket/dao/UserDao has been compiled by a more recent version of the Java Runtime (class file version 52.0), this version of the Java Runtime only recognizes class file versions up to 51.0提示错误信息里的52.0对应 JDK 851.0对应 JDK 7——说明编译时用了 JDK 8但你运行时用了 JDK 7。反过来JDK 17 编译的 class 文件版本是 61Tomcat 10 才支持而本项目web.xml的web-app根节点声明的是version3.0Tomcat 9 才兼容。所以版本链必须闭合JDK 8 → Tomcat 8.5 → MySQL 5.7。验证方式# 检查 JDK 版本必须输出 1.8.x java -version # 检查 Tomcat 版本必须输出 v8.5.x $TOMCAT_HOME/bin/version.sh # Linux/Mac %TOMCAT_HOME%\bin\version.bat # Windows # 检查 MySQL 版本必须输出 5.7.x mysql --version2.2 项目结构解剖识别src、WebContent、lib三大核心区域解压 ZIP 后典型目录结构如下supermarket/ ├── build.xml # Ant 构建脚本非 Maven勿用 IDEA 自动导入 ├── src/ # Java 源码根目录注意不是 Maven 的 src/main/java │ ├── com/supermarket/dao/ # 数据访问层UserDao.java, GoodsDao.java │ ├── com/supermarket/service/ # 业务逻辑层UserService.java, GoodsService.java │ └── com/supermarket/servlet/ # 控制层LoginServlet.java, SaleServlet.java ├── WebContent/ # Web 资源根目录等价于传统 WAR 包的 webapp │ ├── WEB-INF/ │ │ ├── web.xml # 核心配置Servlet 映射、过滤器、监听器 │ │ └── lib/ # 依赖 JAR 包mysql-connector-java-5.1.47.jar 必须存在 │ ├── index.jsp # 首页入口 │ ├── login.jsp # 登录页 │ └── admin/ # 后台页面goods_list.jsp, employee_add.jsp ├── database/ # 数据库脚本目录 │ └── supermarket.sql # 建库建表初始数据UTF8MB4 字符集 └── README.txt # 关键提示如默认账号密码、端口配置关键动作将整个supermarket/目录复制到$TOMCAT_HOME/webapps/下不要嵌套子文件夹启动 Tomcat 后访问http://localhost:8080/supermarket/。若看到登录页说明部署成功若 404请检查WebContent/WEB-INF/web.xml中display-name是否为supermarket且webapps/下文件夹名是否与之完全一致大小写敏感。2.3 数据库初始化supermarket.sql的三处致命细节database/supermarket.sql不是简单CREATE DATABASE它包含三个易被忽略的硬编码细节字符集强制声明CREATE DATABASE IF NOT EXISTS supermarket DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE supermarket;为什么必须是 utf8mb4因为商品名称可能含 emoji如 MySQL 5.7 默认utf8实际是utf8mb3无法存储四字节 Unicode。若漏掉mb4插入商品时会报Incorrect string value错误。外键约束显式关闭SET FOREIGN_KEY_CHECKS 0; -- 关键否则建表顺序错导致失败 DROP TABLE IF EXISTS goods; CREATE TABLE goods ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL, price decimal(10,2) NOT NULL, stock int(11) NOT NULL DEFAULT 0, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; SET FOREIGN_KEY_CHECKS 1;现象若未加SET FOREIGN_KEY_CHECKS 0且employee表引用了department表但department表建在后面则employee表创建失败。初始管理员账号明文写死INSERT INTO user (username, password, role) VALUES (admin, e10adc3949ba59abbe56e057f20f883e, ADMIN);密码e10adc3949ba59abbe56e057f20f883e是123456的 MD5 值32 位小写。答辩时务必修改此密码否则老师用admin/123456直接登录后台会质疑安全性。执行命令# 进入 MySQL 命令行确保已创建 supermarket 数据库 mysql -u root -p source /path/to/supermarket/database/supermarket.sql3. 从登录到结账核心业务链路的手动调试法3.1 登录流程逆向追踪login.jsp→LoginServlet→UserDao当输入admin/123456点击登录实际发生以下调用链login.jsp表单提交到/login查看form actionlogin methodpostweb.xml中映射LoginServlet处理/login请求servlet servlet-nameLoginServlet/servlet-name servlet-classcom.supermarket.servlet.LoginServlet/servlet-class /servlet servlet-mapping servlet-nameLoginServlet/servlet-name url-pattern/login/url-pattern /servlet-mappingLoginServlet.java的doPost()方法protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username request.getParameter(username); // 获取表单值 String password request.getParameter(password); UserDao userDao new UserDao(); // 实例化 DAO User user userDao.login(username, MD5Util.md5(password)); // 注意密码已 MD5 加密 if (user ! null) { request.getSession().setAttribute(user, user); // 存入 Session response.sendRedirect(admin/index.jsp); // 重定向到后台首页 } else { request.setAttribute(msg, 用户名或密码错误); request.getRequestDispatcher(login.jsp).forward(request, response); // 返回登录页 } }参数说明request.getParameter()获取 HTML 表单字段名MD5Util.md5()是项目自定义工具类位于src/com/supermarket/util/MD5Util.javarequest.getSession().setAttribute()将用户对象存入 Session后续页面通过session.getAttribute(user)获取。3.2 商品入库操作goods_add.jsp→GoodsServlet→GoodsDao.insert()添加商品时goods_add.jsp表单提交到/goods/add由GoodsServlet的doPost()处理// GoodsServlet.java protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name request.getParameter(name); String priceStr request.getParameter(price); String stockStr request.getParameter(stock); // 类型转换必须捕获 NumberFormatException BigDecimal price new BigDecimal(priceStr); int stock Integer.parseInt(stockStr); Goods goods new Goods(); goods.setName(name); goods.setPrice(price); goods.setStock(stock); GoodsDao goodsDao new GoodsDao(); boolean success goodsDao.insert(goods); // 执行插入 if (success) { request.setAttribute(msg, 商品添加成功); request.getRequestDispatcher(goods_list.jsp).forward(request, response); } else { request.setAttribute(msg, 商品添加失败请重试); request.getRequestDispatcher(goods_add.jsp).forward(request, response); } }关键点BigDecimal用于价格避免float精度丢失如0.1 0.2 ! 0.3Integer.parseInt()可能抛出NumberFormatException但原代码未 try-catch——这是答辩时老师最爱问的“异常处理漏洞”goodsDao.insert()最终执行 SQLINSERT INTO goods (name, price, stock) VALUES (?, ?, ?)使用PreparedStatement防止 SQL 注入。3.3 销售单生成事务控制的实操验证结账时需同时更新goods表扣减库存和插入sale_record表记录销售。SaleServlet.java中的关键代码Connection conn null; try { conn JDBCUtil.getConnection(); // 获取连接 conn.setAutoCommit(false); // 关闭自动提交开启事务 // 1. 更新商品库存 String updateSql UPDATE goods SET stock stock - ? WHERE id ?; PreparedStatement ps1 conn.prepareStatement(updateSql); ps1.setInt(1, quantity); // 购买数量 ps1.setInt(2, goodsId); ps1.executeUpdate(); // 2. 插入销售记录 String insertSql INSERT INTO sale_record (goods_id, quantity, total_price, sale_time) VALUES (?, ?, ?, NOW()); PreparedStatement ps2 conn.prepareStatement(insertSql); ps2.setInt(1, goodsId); ps2.setInt(2, quantity); ps2.setBigDecimal(3, totalPrice); ps2.executeUpdate(); conn.commit(); // 提交事务 request.setAttribute(msg, 结账成功); } catch (SQLException e) { if (conn ! null) { try { conn.rollback(); // 回滚事务 } catch (SQLException ex) { ex.printStackTrace(); } } request.setAttribute(msg, 结账失败 e.getMessage()); } finally { JDBCUtil.close(conn); // 关闭连接 }为什么必须手动 commit/rollback若只更新库存成功、插入销售记录失败不回滚会导致库存虚减。此处conn.setAutoCommit(false)是事务起点conn.commit()是终点conn.rollback()是异常兜底——答辩时演示“故意让插入失败”观察库存是否恢复即可证明事务生效。4. 避坑指南五个让答辩前夜崩溃的真实问题4.1 现象Tomcat 启动后访问http://localhost:8080/supermarket/报 404原因web.xml中display-name值为supermarket但webapps/下文件夹名是supermarket-master或SuperMarket大小写不一致。Tomcat 严格区分大小写且 WAR 包解压后文件夹名必须与display-name完全一致。解决重命名webapps/下文件夹为supermarket全小写重启 Tomcat。4.2 现象登录页提交后跳转http://localhost:8080/login报 404原因login.jsp表单的action属性写成绝对路径/login但项目上下文路径不是 ROOT。例如若项目放在webapps/supermarket/则正确路径应为supermarket/login。解决将form action/login ...改为form actionlogin ...相对路径或使用 JSTLc:url value/login/。4.3 现象goods_list.jsp显示java.lang.ClassNotFoundException: com.mysql.jdbc.Driver原因MySQL 5.1 驱动类名已从com.mysql.jdbc.Driver变更为com.mysql.cj.jdbc.Driver但JDBCUtil.java中仍用旧类名且lib/mysql-connector-java-5.1.47.jar未放入WebContent/WEB-INF/lib/。解决确认WebContent/WEB-INF/lib/下存在mysql-connector-java-5.1.47.jar修改JDBCUtil.java中Class.forName(com.mysql.cj.jdbc.Driver)URL 改为jdbc:mysql://localhost:3306/supermarket?useSSLfalseserverTimezoneUTC添加serverTimezoneUTC防止时区报错。4.4 现象添加商品时中文名称显示为??数据库中存为乱码原因MySQL 服务端字符集未设为utf8mb4或JDBC URL未指定characterEncodingutf8mb4。解决MySQL 配置文件my.cnf添加[client] default-character-set utf8mb4 [mysqld] character-set-server utf8mb4 collation-server utf8mb4_unicode_ciJDBCUtil.java中 URL 改为jdbc:mysql://localhost:3306/supermarket?useSSLfalseserverTimezoneUTCcharacterEncodingutf8mb44.5 现象sale_record表插入成功但goods表库存未减少原因SaleServlet.java中conn.setAutoCommit(false)后未执行conn.commit()或catch块中conn.rollback()未生效因conn为 null。解决检查conn.commit()是否在try块末尾确保JDBCUtil.getConnection()返回的conn不为 null在finally块前添加日志System.out.println(Transaction committed);验证执行路径。5. 答辩加分项三步让老师眼前一亮的定制化改造5.1 第一步给登录页加验证码5 分钟实现防暴力破解原系统无验证码易被脚本爆破。只需三步生成验证码图片在src/com/supermarket/util/VerifyCodeUtil.java中添加public static String generateVerifyCode(HttpServletRequest request) { String code RandomStringUtils.randomNumeric(4); // 生成4位数字 request.getSession().setAttribute(verifyCode, code); // 存入 Session return code; }添加验证码图片 Servlet新建VerifyCodeServlet.javaprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String code VerifyCodeUtil.generateVerifyCode(request); 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); response.setContentType(image/png); ImageIO.write(image, png, response.getOutputStream()); }并在web.xml中映射/verifyCode。修改login.jspimg srcverifyCode onclickthis.srcverifyCode?Math.random() alt验证码/ input typetext nameverifyCode placeholder请输入验证码/在LoginServlet中增加校验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; }答辩话术“老师我增加了图形验证码防止暴力破解。点击图片可刷新且验证码区分大小写提升了基础安全。”5.2 第二步销售单导出 Excel用 Apache POI 实现老师常问“数据怎么导出分析”原系统无此功能。添加ExportSaleServlet.javaprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ListSaleRecord records new SaleRecordDao().findAll(); // 查询全部销售记录 HSSFWorkbook workbook new HSSFWorkbook(); HSSFSheet sheet workbook.createSheet(销售记录); // 表头 HSSFRow headerRow sheet.createRow(0); String[] headers {ID, 商品ID, 数量, 总价, 时间}; for (int i 0; i headers.length; i) { headerRow.createCell(i).setCellValue(headers[i]); } // 数据行 for (int i 0; i records.size(); i) { SaleRecord r records.get(i); HSSFRow row sheet.createRow(i 1); row.createCell(0).setCellValue(r.getId()); row.createCell(1).setCellValue(r.getGoodsId()); row.createCell(2).setCellValue(r.getQuantity()); row.createCell(3).setCellValue(r.getTotalPrice().doubleValue()); row.createCell(4).setCellValue(r.getSaleTime().toString()); } response.setContentType(application/vnd.ms-excel); response.setHeader(Content-Disposition, attachment; filenamesales.xls); workbook.write(response.getOutputStream()); }依赖添加下载poi-3.17.jar放入WebContent/WEB-INF/lib/。价值点导出功能体现数据闭环能力且 POI 是 JavaWeb 常用工具展示技术广度。5.3 第三步用 Filter 统一处理中文乱码一劳永逸每次request.setCharacterEncoding(UTF-8)太重复。新建EncodingFilter.javapublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req (HttpServletRequest) request; HttpServletResponse resp (HttpServletResponse) response; req.setCharacterEncoding(UTF-8); resp.setCharacterEncoding(UTF-8); resp.setContentType(text/html;charsetUTF-8); chain.doFilter(req, resp); }并在web.xml中配置filter filter-nameEncodingFilter/filter-name filter-classcom.supermarket.filter.EncodingFilter/filter-class /filter filter-mapping filter-nameEncodingFilter/filter-name url-pattern/*/url-pattern /filter-mapping玄学经验Filter 必须在web.xml中置于所有 Servlet 映射之前否则无效。这是血泪教训——曾因位置放错导致goods_add.jsp提交的中文始终乱码。最后想说这个超市系统不是要你造轮子而是让你亲手拧紧每一颗螺丝。我当年答辩时老师指着销售单页面问“如果同时两人结账同一商品库存会超卖吗” 我当场打开SaleServlet指出conn.setAutoCommit(false)和synchronized未加——然后快速补上synchronized块并解释“高并发需 Redis 锁但本设计聚焦事务一致性”。老师笑了说“这才是工程思维。” 希望帮到你。本文还有配套的精品资源点击获取
返回列表