ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Java Web零食电商系统:从Word文档到可运行工程实操指南

Java Web零食电商系统:从Word文档到可运行工程实操指南 简介本资源是一份面向计算机专业本科生与Java初学者的毕业设计级项目文档完整呈现基于Spring Boot与MySQL开发的B/S架构网上零食购物系统的设计与实现全过程。文档涵盖绪论、系统架构、数据库设计、各功能模块用户管理、商品展示、购物车、订单处理、定制服务、促销管理详细实现、多维度测试方案及未来优化方向内容扎实、结构清晰适合作为课程设计参考、毕设选题范本或Java Web开发实战学习材料。资源为单个771KB的Word文档.docx内含摘要、中英文关键词、五章正文及规范目录图文结合技术细节丰富如三层架构图、ER模型、关键代码逻辑说明等。目前已有300人学习下载读者可直接获取完整的系统分析思路、模块划分方法、Spring BootMyBatis整合实践及电商类项目常见功能落地方案。1. 这不是又一个“毕业设计模板”它是一份能跑通、能改、能上线的 Java 零食电商系统实操包你搜“java网上零食购物网站系统”页面刷出来几十个同名文档——点开全是目录整齐、摘要规范、参考文献堆满页脚的 Word。但真正敢把web.xml贴出来、把UserDaoImpl.java里 MyBatis 的select标签写法标清楚、把 SQL Server 2008 连接字符串里integratedSecurityfalse和usersa;password123456的坑明明白白列出来的不到三份。这份《基于Java网上零食购物网站系统设计与实现.docx》就是其中之一。它不是理论推演而是一套在 Windows 8 Tomcat 7.0 JDK 1.5 SQL Server 2008 环境下真实部署过、前台能加购、后台能审单、订单号能生成、用户密码用 MD5 加密虽然后期被指出弱但代码里真写了的完整闭环。它解决的不是“怎么写论文”而是“怎么让一个刚学完 Servlet 的人三天内把首页跑起来七天内把订单流程走通”。适合两类人一是需要交毕设但不想从零造轮子的学生二是想快速复现一个 B/S 架构电商骨架、验证自己 Spring Boot 迁移思路的初级 Java 工程师。别被标题里的“零食”二字骗了——它的模块划分、数据库字段命名逻辑、前后台权限隔离方式和你正在做的生鲜、图书、数码商城底层结构一模一样。2. 从 Word 文档到可运行工程环境还原与项目结构解剖这份文档的价值不在于它写了什么而在于它暴露了什么——暴露了 2010 年代初 Java Web 开发的真实技术栈断面没有 Spring Boot 自动装配没有 Maven 依赖管理甚至没有 Logback 日志框架只有web.xml里手写的servlet映射、lib目录下塞满的commons-dbcp-1.4.jar和sqlserver.jar、以及src下按com.xxx.dao/com.xxx.servlet/com.xxx.bean三层硬编码的包结构。要让它活过来第一步不是写代码而是把文档里散落在第 5 章“详细设计与实现”和第 4 章“数据库设计”里的碎片拼成一个可编译、可部署的工程。2.1 项目物理结构还原五个核心目录的生死线文档虽未提供源码压缩包但所有路径、文件名、包名均在正文中明确给出。我们按 MyEclipse 5.1 的标准 Web Project 结构反向重建snack-shop-web/ # 项目根目录文档中未命名按惯例取 ├── src/ # Java 源码根目录对应文档 5.3.2 技术简介 │ ├── com/snack/dao/ # 数据访问层文档 4.2.2 表结构 5.5.1 用户维护模块 │ │ ├── UserDao.java # 接口定义 login()、register() 方法 │ │ └── UserDaoImpl.java # 实现类含 JDBC 连接池获取、PreparedStatement 执行逻辑 │ ├── com/snack/servlet/ # 控制层文档 5.4 首页设计 5.5 前台功能 │ │ ├── LoginServlet.java # 处理 /login.do 请求调用 UserDao.login() │ │ ├── AddToCartServlet.java # 处理购物车添加操作 session.setAttribute(cart, cartList) │ │ └── OrderSubmitServlet.java # 处理收银台提交生成订单号并插入 order 表 │ ├── com/snack/bean/ # 实体层文档 4.2.2 字段定义直接映射 │ │ ├── User.java # 含 id, username, pwd, cx(权限), addtime │ │ ├── Snack.java # 对应 shangpinxinxi 表id, bianhao, mingcheng, jiage1, tupian... │ │ └── Order.java # 对应订单表id, userid, address, total, addtime, status │ └── com/snack/util/ # 工具类文档未提但实际必须存在 │ └── DBUtil.java # 封装 Connection 获取、关闭逻辑关键参数见下文 ├── WebContent/ # Web 资源根目录文档 5.4 首页设计 │ ├── index.jsp # 系统首页含新品上架、特价区、销售排行文档 4.1 前台模块 │ ├── login.jsp # 用户登录页表单 action/login.do │ ├── cart.jsp # 购物车页面遍历 session 中的 cartList │ ├── order.jsp # 订单确认页展示商品地址总价 │ └── admin/ # 后台管理目录文档 5.6 │ ├── index.jsp # 后台首页含订单管理、商品管理入口 │ └── snackManage.jsp # 商品管理页表格展示 shangpinxinxi 表数据 ├── WEB-INF/ │ ├── web.xml # 核心配置文档 5.3.1 MyEclipse 简介隐含要求 │ └── lib/ # 依赖库文档 5.2 运行环境 5.3.1 开发工具 │ ├── sqlserver.jar # SQL Server 2008 JDBC 驱动关键版本必须匹配 │ ├── commons-dbcp-1.4.jar # 连接池文档 2.3 技术可行性提到“性能要求” │ ├── servlet-api.jar # Tomcat 7.0 提供开发时需引入 │ └── jstl.jar # JSP 标签库文档 5.4 首页设计用 c:forEach 遍历 └── database/ # 数据库脚本文档 4.2.2 明确列出 10 张表结构 └── create_table.sql # 手工整理的建表语句见下文提示文档中gonggao公告、dx类别、zhubaoshoucang收藏等表名明显是早期开发时用拼音缩写规避中文表名兼容性问题。这不是 bug是时代印记——SQL Server 2008 对中文标识符支持不稳定很多团队强制用英文或拼音。2.2 数据库建表脚本从 Word 表格到可执行 SQL 的转换文档第 4.2.2 节用 Word 表格列出了 10 张表的字段但格式混乱如shangpinxinxi表中Jiage1money 8是255 价格。我们必须将其标准化为可执行的 T-SQL。以最核心的shangpinxinxi商品信息表为例原文档字段序号字段名称字段类型大小允许为空最大长度备注1IDInt4自增编号10 Id2bianhaoVarChar50是255编号3mingchengVarChar200是255名称.....................转换逻辑ID→ID INT IDENTITY(1,1) PRIMARY KEY自增主键非INT(4)SQL Server 无宽度限制bianhao→bianhao VARCHAR(50) NULLVARCHAR长度取“大小”列值NULL对应“允许为空”为“是”mingcheng→mingcheng VARCHAR(200) NULL注意原文档“大小”列写 200“最大长度”列写 255以“大小”为准因VARCHAR(200)已覆盖 255 字符需求Jiage1→Jiage1 DECIMAL(10,2) NULL原文档Jiage1money 8是255 价格money类型在 SQL Server 中精度高但易出错实战中统一用DECIMAL(10,2)存价格8指存储字节数非精度-- database/create_table.sql -- 创建数据库文档未指定按惯例命名为 snack_shop CREATE DATABASE snack_shop; GO USE snack_shop; GO -- 1. 用户表 (allusers) CREATE TABLE allusers ( ID INT IDENTITY(1,1) PRIMARY KEY, username VARCHAR(50) NULL, pwd VARCHAR(50) NULL, -- 注意文档中密码存明文或简单MD5生产环境必须升级 cx VARCHAR(50) NULL, -- 权限字段user/admin addtime DATETIME NULL ); -- 2. 公告表 (gonggao) CREATE TABLE gonggao ( ID INT IDENTITY(1,1) PRIMARY KEY, biaoti VARCHAR(50) NULL, neirong VARCHAR(50) NULL, -- 原文档字段长度仅50实际应为TEXT或VARCHAR(MAX) addtime DATETIME NULL ); -- 3. 商品信息表 (shangpinxinxi) - 核心业务表 CREATE TABLE shangpinxinxi ( ID INT IDENTITY(1,1) PRIMARY KEY, bianhao VARCHAR(50) NULL, mingcheng VARCHAR(200) NULL, Leibie1 VARCHAR(50) NULL, -- 大类 Leibie2 VARCHAR(50) NULL, -- 小类 Jiage1 DECIMAL(10,2) NULL, -- 销售价 Jiage2 DECIMAL(10,2) NULL, -- 定金定制场景 tupian VARCHAR(50) NULL, -- 图片路径如 /images/snack1.jpg tianjiaren VARCHAR(50) NULL, addtime DATETIME NULL ); -- 4. 订单主表 (order_main) - 文档中未命名按逻辑推导 -- 文档 4.2.1 提到“订单基本信息”和“订单明细信息”需拆分为两张表 CREATE TABLE order_main ( ID INT IDENTITY(1,1) PRIMARY KEY, userid INT NOT NULL, -- 关联 allusers.ID address VARCHAR(200) NULL, total DECIMAL(10,2) NULL, status VARCHAR(20) NULL, -- unpaid,paid,shipped,completed addtime DATETIME NULL ); -- 5. 订单明细表 (order_detail) CREATE TABLE order_detail ( ID INT IDENTITY(1,1) PRIMARY KEY, orderid INT NOT NULL, -- 关联 order_main.ID snackid INT NOT NULL, -- 关联 shangpinxinxi.ID quantity INT NULL, price DECIMAL(10,2) NULL, -- 快照价格避免商品调价影响历史订单 addtime DATETIME NULL ); -- 其余 dx, Leibie1, Leibie2, xinwentongzhi 等表依同样规则创建参数说明DECIMAL(10,2)表示最多 10 位数字其中 2 位小数足够支撑万元级商品价格DATETIME在 SQL Server 2008 中精度为 3.33 毫秒满足订单时间戳需求VARCHAR(200)用于商品名称比文档中的VARCHAR(50)更合理——试想“进口比利时黑巧克力松露手工牛轧糖礼盒装”已超 50 字。2.3 关键配置文件web.xml与DBUtil.java的血泪经验文档第 5.2 节只说“软件环境为 Windows 8 SQL Server 2008 JDK1.5 MyEclipse5.1 Tomcat7.0”但没给web.xml内容。而这是整个项目启动的咽喉。根据 MyEclipse 5.1 Servlet 2.4 规范web.xml必须包含以下三要素!-- WEB-INF/web.xml -- ?xml version1.0 encodingUTF-8? web-app xmlnshttp://java.sun.com/xml/ns/j2ee xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd version2.4 !-- 1. 配置欢迎文件 -- welcome-file-list welcome-fileindex.jsp/welcome-file /welcome-file-list !-- 2. 配置 Servlet 映射文档 5.4 首页设计 5.5 前台功能-- servlet servlet-nameLoginServlet/servlet-name servlet-classcom.snack.servlet.LoginServlet/servlet-class /servlet servlet-mapping servlet-nameLoginServlet/servlet-name url-pattern/login.do/url-pattern /servlet-mapping servlet servlet-nameAddToCartServlet/servlet-name servlet-classcom.snack.servlet.AddToCartServlet/servlet-class /servlet servlet-mapping servlet-nameAddToCartServlet/servlet-name url-pattern/cart/add.do/url-pattern /servlet-mapping !-- 3. 配置监听器文档未提但连接池必需 -- listener listener-classcom.snack.util.ContextListener/listener-class /listener /web-app而DBUtil.java是数据库连接的命脉。文档第 2.3 节强调“SQL Server 2008 数据库存储数据”但没给连接字符串。这里踩过无数人的坑SQL Server 2008 默认实例名是SQLEXPRESS且默认禁用 TCP/IP 协议。DBUtil的关键代码如下// src/com/snack/util/DBUtil.java package com.snack.util; import java.sql.*; public class DBUtil { // 关键SQL Server 2008 连接字符串文档 5.2 运行环境指定了版本 private static final String URL jdbc:sqlserver://localhost:1433;databaseNamesnack_shop;integratedSecurityfalse;; private static final String USER sa; // 文档 4.2.1 提到“管理员 ID、密码” private static final String PASSWORD 123456; // 生产环境严禁硬编码 static { try { Class.forName(com.microsoft.sqlserver.jdbc.SQLServerDriver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } public static void close(Connection conn, PreparedStatement ps, ResultSet rs) { if (rs ! null) try { rs.close(); } catch (SQLException e) {} if (ps ! null) try { ps.close(); } catch (SQLException e) {} if (conn ! null) try { conn.close(); } catch (SQLException e) {} } }逻辑说明integratedSecurityfalse表示使用 SQL Server 身份验证而非 Windows 身份验证这是开发环境最稳妥的方式端口1433是 SQL Server 默认端口若被占用需在 SQL Server 配置管理器中修改databaseNamesnack_shop必须与CREATE DATABASE语句一致。血泪经验第一次运行报Connection refused90% 是因为 SQL Server 服务没启动或 TCP/IP 协议未启用——打开“SQL Server 配置管理器 - SQL Server 网络配置 - MSSQLSERVER 的协议”右键启用 TCP/IP。3. 前台核心功能落地从首页渲染到订单生成的四步链路文档第 4.1 节将前台划分为“零食展台”、“零食查询”、“我的收藏”等六大模块但真正构成用户旅程闭环的是四个动作看商品 → 加购物车 → 填地址 → 生成订单。这四步在index.jsp、cart.jsp、order.jsp和OrderSubmitServlet.java中完成代码虽简陋却暴露了 B/S 架构最原始的交互本质。3.1 首页商品展示JSP JDBC 的暴力美学文档第 5.4 节说“系统首页设计”但没给代码。我们根据其“新品上架、分页显示特价零食、零食销售排行”的需求写出index.jsp的核心片段。它不依赖任何框架纯 JSP 脚本直连数据库查shangpinxinxi表!-- WebContent/index.jsp -- % page languagejava importjava.util.*,com.snack.bean.*,com.snack.dao.* pageEncodingUTF-8% % taglib prefixc urihttp://java.sun.com/jsp/jstl/core % % // 1. 查询新品按 addtime 降序取前8条 ListSnack newSnacks new SnackDao().findNewSnacks(8); request.setAttribute(newSnacks, newSnacks); // 2. 查询特价Jiage2 Jiage1即定金低于售价 ListSnack specialSnacks new SnackDao().findSpecialSnacks(8); request.setAttribute(specialSnacks, specialSnacks); // 3. 查询销售排行需额外 order_detail 表关联统计此处简化为按销量字段 ListSnack topSnacks new SnackDao().findTopSnacks(8); request.setAttribute(topSnacks, topSnacks); % !DOCTYPE html html headtitle零食在线销售系统/title/head body !-- 新品上架区 -- div classsection h2新品上架/h2 c:forEach items${newSnacks} varsnack div classsnack-item img src${snack.tupian} alt${snack.mingcheng} width100/ p${snack.mingcheng}/p p¥${snack.Jiage1}/p a hrefcart/add.do?snackid${snack.id}加入购物车/a /div /c:forEach /div !-- 特价区 -- div classsection h2特价零食/h2 c:forEach items${specialSnacks} varsnack div classsnack-item img src${snack.tupian} alt${snack.mingcheng} width100/ p${snack.mingcheng}/p pdel¥${snack.Jiage1}/del ¥${snack.Jiage2}/p a hrefcart/add.do?snackid${snack.id}立即抢购/a /div /c:forEach /div /body /html参数说明findNewSnacks(8)方法在SnackDao.java中执行SELECT TOP 8 * FROM shangpinxinxi ORDER BY addtime DESCtupian字段存的是相对路径如/images/1.jpg需确保WebContent/images/目录存在对应图片c:forEach是 JSTL 标签依赖jstl.jar否则页面会报错。玄学提示如果图片不显示检查tupian字段值是否带前导/JSP 中src属性对路径敏感/images/1.jpg是绝对路径从域名开始images/1.jpg是相对路径从当前 JSP 所在目录。3.2 购物车实现Session 与 List 的脆弱平衡文档第 5.5.3 节提到“购物车处理”但没描述技术细节。在 Servlet 2.4 时代购物车几乎 100% 依赖HttpSession存储一个ListCartitem。Cartitem是一个临时 Bean非数据库实体// src/com/snack/bean/Cartitem.java package com.snack.bean; public class Cartitem { private int snackid; // 商品ID private String name; // 商品名称 private double price; // 单价快照 private int quantity; // 数量 private String image; // 图片路径 // getter/setter 省略 }AddToCartServlet.java的核心逻辑是// src/com/snack/servlet/AddToCartServlet.java protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int snackid Integer.parseInt(request.getParameter(snackid)); // 1. 从数据库查商品信息为生成 Cartitem Snack snack new SnackDao().findById(snackid); // 2. 从 Session 获取购物车 List HttpSession session request.getSession(); ListCartitem cartList (ListCartitem) session.getAttribute(cart); if (cartList null) { cartList new ArrayList(); session.setAttribute(cart, cartList); } // 3. 判断商品是否已在购物车按 snackid boolean exists false; for (Cartitem item : cartList) { if (item.getSnackid() snackid) { item.setQuantity(item.getQuantity() 1); // 数量1 exists true; break; } } if (!exists) { Cartitem newItem new Cartitem(); newItem.setSnackid(snackid); newItem.setName(snack.getMingcheng()); newItem.setPrice(snack.getJiage1()); newItem.setQuantity(1); newItem.setImage(snack.getTupian()); cartList.add(newItem); } response.sendRedirect(cart.jsp); // 重定向到购物车页 }逻辑说明session.setAttribute(cart, cartList)将购物车存入 Session生命周期与用户浏览器会话绑定response.sendRedirect()是重定向避免用户刷新导致重复提交Cartitem中price字段存的是快照价格防止商品调价后历史订单金额错乱。翻车预警如果用户同时开多个标签页操作购物车cartList的并发修改可能导致ConcurrentModificationException——这是该架构的固有缺陷文档未提及但你必须知道。3.3 订单生成事务边界与状态机的雏形文档第 5.4 节“收银台处理”描述“填写订单信息确定无误后系统产生订单编号完成在线下达订单”。这背后是典型的数据库事务扣库存 插主表 插明细 更新状态。OrderSubmitServlet.java的关键代码// src/com/snack/servlet/OrderSubmitServlet.java protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 获取用户ID从Session HttpSession session request.getSession(); User user (User) session.getAttribute(user); if (user null) { response.sendRedirect(login.jsp); return; } // 2. 获取收货地址等参数 String address request.getParameter(address); String phone request.getParameter(phone); // 3. 从Session获取购物车 ListCartitem cartList (ListCartitem) session.getAttribute(cart); if (cartList null || cartList.isEmpty()) { request.setAttribute(msg, 购物车为空); request.getRequestDispatcher(cart.jsp).forward(request, response); return; } Connection conn null; PreparedStatement psMain null; PreparedStatement psDetail null; try { conn DBUtil.getConnection(); conn.setAutoCommit(false); // 开启事务 // 4. 插入订单主表 String sqlMain INSERT INTO order_main(userid, address, total, status, addtime) VALUES(?, ?, ?, ?, ?); psMain conn.prepareStatement(sqlMain, Statement.RETURN_GENERATED_KEYS); double total 0.0; for (Cartitem item : cartList) { total item.getPrice() * item.getQuantity(); } psMain.setInt(1, user.getId()); psMain.setString(2, address); psMain.setDouble(3, total); psMain.setString(4, unpaid); // 初始状态 psMain.setTimestamp(5, new Timestamp(System.currentTimeMillis())); psMain.executeUpdate(); // 5. 获取生成的订单ID ResultSet rs psMain.getGeneratedKeys(); int orderId 0; if (rs.next()) { orderId rs.getInt(1); } // 6. 插入订单明细 String sqlDetail INSERT INTO order_detail(orderid, snackid, quantity, price, addtime) VALUES(?, ?, ?, ?, ?); psDetail conn.prepareStatement(sqlDetail); for (Cartitem item : cartList) { psDetail.setInt(1, orderId); psDetail.setInt(2, item.getSnackid()); psDetail.setInt(3, item.getQuantity()); psDetail.setDouble(4, item.getPrice()); psDetail.setTimestamp(5, new Timestamp(System.currentTimeMillis())); psDetail.executeUpdate(); } conn.commit(); // 提交事务 session.removeAttribute(cart); // 清空购物车 request.setAttribute(orderId, orderId); request.getRequestDispatcher(order_success.jsp).forward(request, response); } catch (SQLException e) { if (conn ! null) { try { conn.rollback(); } catch (SQLException ex) {} } e.printStackTrace(); request.setAttribute(msg, 下单失败 e.getMessage()); request.getRequestDispatcher(order.jsp).forward(request, response); } finally { DBUtil.close(conn, psMain, null); DBUtil.close(null, psDetail, null); } }参数说明conn.setAutoCommit(false)是事务起点Statement.RETURN_GENERATED_KEYS让INSERT返回自增主键order_main.status字段是状态机的起点后续需管理员后台更新为paid/shippedsession.removeAttribute(cart)是关键否则用户刷新order_success.jsp会再次提交。后悔药如果事务中某一步失败如库存不足rollback()会回滚所有操作保证数据一致性——这是该系统最接近生产级的设计点。4. 后台管理与权限控制cx字段的双刃剑与避坑指南文档第 5.6 节详述了“零食类别管理”、“信息管理”、“用户注册信息管理”、“用户订单信息管理”四大后台模块但所有功能都指向同一个核心字段allusers.cx权限。这个仅 50 字符长的VARCHAR字段承载了整个系统的访问控制逻辑也是最容易崩塌的环节。4.1 权限验证cx字段的硬编码判断文档第 1.3 节“系统设计思想”第 4 条要求“会员可以随时修改自己的基本资料”第 5 条要求“实现零食定制的功能”但未明确谁有权限操作后台。从allusers.cx字段的备注“权限”及后台页面路径/admin/可推断cxadmin的用户才能访问后台。验证逻辑散落在每个后台 Servlet 中// src/com/snack/servlet/AdminBaseServlet.java (基类) public abstract class AdminBaseServlet extends HttpServlet { Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session request.getSession(); User user (User) session.getAttribute(user); if (user null || !admin.equals(user.getCx())) { // 硬编码判断 request.setAttribute(msg, 无权访问后台); request.getRequestDispatcher(/login.jsp).forward(request, response); return; } doAdminWork(request, response); } protected abstract void doAdminWork(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException; } // src/com/snack/servlet/SnackManageServlet.java (继承基类) public class SnackManageServlet extends AdminBaseServlet { Override protected void doAdminWork(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ListSnack snacks new SnackDao().findAll(); request.setAttribute(snacks, snacks); request.getRequestDispatcher(/admin/snackManage.jsp).forward(request, response); } }逻辑说明AdminBaseServlet是所有后台 Servlet 的父类强制进行cx字段校验doAdminWork()是模板方法子类只需实现业务逻辑admin字符串硬编码在代码中而非配置文件这是典型的技术债。边界提醒cx字段长度为VARCHAR(50)理论上可存super_admin或editor但文档中所有后台功能都只认admin扩展性为零。4.2 后台商品管理CRUD 的朴素实现/admin/snackManage.jsp页面展示shangpinxinxi表全量数据并提供“添加”、“编辑”、“删除”按钮。其背后的SnackManageServlet处理逻辑极简// src/com/snack/servlet/SnackManageServlet.java protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String action request.getParameter(action); // add, update, delete if (add.equals(action)) { Snack snack new Snack(); snack.setBianhao(request.getParameter(bianhao)); snack.setMingcheng(request.getParameter(mingcheng)); snack.setLeibie1(request.getParameter(leibie1)); snack.setLeibie2(request.getParameter(leibie2)); snack.setJiage1(Double.parseDouble(request.getParameter(jiage1))); snack.setJiage2(Double.parseDouble(request.getParameter(jiage2))); snack.setTupian(request.getParameter(tupian)); snack.setTianjiaren(admin); // 固定添加人 new SnackDao().insert(snack); } else if (update.equals(action)) { // ... update logic } else if (delete.equals(action)) { int id Integer.parseInt(request.getParameter(id)); new SnackDao().delete(id); } response.sendRedirect(snackManage.do); // 重定向回列表页 }参数说明request.getParameter(action)通过表单隐藏域或链接参数传递操作类型new SnackDao().insert(snack)执行INSERT INTO shangpinxinxi (...) VALUES (...)response.sendRedirect()避免 F5 刷新重复提交。安全警告此代码无任何输入校验request.getParameter(jiage1)若传入非数字字符串Double.parseDouble()会抛NumberFormatException导致 500 错误——这是文档中埋下的典型“教学式漏洞”提醒你必须加try-catch和前端 JS 校验。4.3 避坑后台管理的五大血泪教训这份文档的后台部分是新手最容易栽跟头的雷区。以下是我在真实部署中踩过的坑按现象、原因、解决三步归因现象 1后台登录后跳转到index.jsp而非admin/index.jsp原因LoginServlet.java中验证成功后request.getRequestDispatcher(index.jsp).forward(request, response)硬编码了跳转路径未判断cx字段。解决在LoginServlet中增加判断if (admin.equals(user.getCx())) { request.getRequestDispatcher(/admin/index.jsp).forward(request, response); } else { request.getRequestDispatcher(index.jsp).forward(request, response); }现象 2商品图片上传后路径错误页面显示404原因文档未提供图片上传功能tupian字段由管理员手动填写路径如/images/1.jpg但WebContent/images/目录不存在或路径大小写不匹配Windows 不敏感Linux 敏感。解决创建WebContent/images/目录在snackManage.jsp表单中图片路径输入框加 placeholder 提示格式如images/1.jpg或增加简易上传 Servlet需commons-fileupload依赖。现象 3订单管理页点击“发货”按钮无反应原因文档第 5.6.4 节只写了“用户订单信息管理设计与实现”但未提供OrderManageServlet.java的ship方法admin/orderManage.jsp中的发货按钮a hreforder/ship.do?id123指向的 Servlet 不存在。解决新建OrderShipServlet.java执行UPDATE order_main SET statusshipped WHERE id?并在web.xml中配置映射。现象 4后台新增商品后前台首页不显示原因SnackDao.insert()方法中addtime字段未设置默认为NULL而index.jsp的findNewSnacks()查询条件是ORDER BY addtime DESCNULL值排在最后。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进