☰
JavaWeb点餐系统源码实操指南:Servlet+JSP+MySQL工程化落地
2026/10/8 10:33:25 网站建设 项目流程

简介:本资源是一套基于JavaWeb与Vue2的前后端分离点餐系统后端源码,面向Java Web开发初学者及全栈学习者,适用于课程设计、毕业项目或中小餐饮系统原型开发。项目采用原生Servlet构建后端服务,集成MyBatis-Flex简化数据库操作,结合Redis与JWT实现认证授权及单点登录,并通过ZXing生成订单二维码,技术栈覆盖企业级Web开发核心组件。压缩包共157个文件,含137个Java业务与控制层代码、12个XML配置与映射文件、2个SQL建表与初始化脚本、2个properties配置文件,以及HTTP接口测试用例和README说明,整体仅168KB,结构紧凑、模块清晰(如OrderService、PayService、AuthService等职责分明)。已有454人学习下载,读者可直接部署运行,深入理解RESTful接口设计、会话管理、数据库事务处理及前后端协作逻辑,快速掌握真实业务场景下的JavaWeb工程实践方法。

1. 为什么一个“基于JavaWeb的点餐系统源码.zip”能让你少踩三个月坑?

你不是在找一个能跑起来的Demo,而是在找一套真实业务闭环可推演、技术栈边界清晰、部署路径不玄学的JavaWeb落地样本。这个压缩包里藏的不是“学生课设”,而是餐饮SaaS早期版本的最小可行切片:用户扫码进店→浏览带图片与分类的菜单→加购→微信/支付宝支付回调→后厨打印小票→管理员后台实时看订单状态与销量统计。它用最朴素的Servlet+JSP+MySQL+DBUtils组合,没上Spring Boot自动装配的糖衣,也没用Vue搞前后端分离——正因如此,你才能看清HTTP请求怎么一层层穿过Filter、Servlet、DAO,最终变成一条INSERT语句落库;才能亲手调通Tomcat连接池配置,而不是靠IDEA一键生成的黑匣子;才能在web.xml里改一个<url-pattern>就理解路径映射的本质。适合两类人:刚学完JDBC但卡在“写完DAO不知道下一步怎么串起来”的Java新手;或需要快速交付中小餐馆定制化系统的外包工程师——它不炫技,但每行代码都对应着真实需求里的一个按钮、一个弹窗、一次数据库事务。别被“源码.zip”四个字骗了,这其实是份带注释的《JavaWeb工程化实操手记》。


2. 从解压到首页渲染:五步跑通最小可运行路径

提示:不要急着导入IDEA!先用文本编辑器打开README.md(如果有)或index.jsp,确认项目结构是否符合经典JavaWeb布局。常见陷阱是源码作者把WEB-INF放在了根目录下而非src/main/webapp/,导致IDEA识别失败。

2.1 确认项目结构:三类文件夹必须存在且位置正确

一个可部署的JavaWeb项目必须包含以下三个核心目录(以标准Maven WebApp结构为准):

目录路径必须存在关键内容说明
src/main/java/✅所有Servlet、DAO、实体类(如OrderServlet.java,FoodDao.java,User.java)
src/main/webapp/✅JSP页面(index.jsp,menu.jsp)、静态资源(css/,js/,images/)、核心配置(WEB-INF/web.xml)
src/main/resources/⚠️(常见缺失)数据库配置文件(db.properties或jdbc.properties),若缺失需手动创建

注意:如果压缩包里直接是WebContent/而非src/main/webapp/,说明这是Eclipse老项目结构。你需要将WebContent/重命名为src/main/webapp/,并补全pom.xml中<packaging>war</packaging>和Servlet API依赖(见2.3节)。别跳过这步——否则IDEA会报“Cannot resolve symbol ‘HttpServlet’”。

2.2 配置数据库:四行代码决定能否连上MySQL

点餐系统必然依赖MySQL。打开src/main/resources/db.properties(若不存在则新建),填入你的本地数据库信息:

# src/main/resources/db.properties driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/food_order?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username=root password=your_password_here

参数说明:

  • useSSL=false:开发环境禁用SSL(生产环境必须开启)
  • serverTimezone=Asia/Shanghai:强制时区,避免java.sql.SQLException: The server time zone value 'XXX' is unrecognized
  • allowPublicKeyRetrieval=true:MySQL 8.0+必需,解决公钥检索异常
    若项目用的是旧版MySQL驱动(mysql-connector-java-5.1.x.jar),需将driver改为com.mysql.jdbc.Driver,url中去掉cj.

接着检查src/main/java/com/xxx/dao/BaseDao.java(或类似名称的数据库工具类),确认其加载db.properties的路径正确:

// 示例:BaseDao.java 中的静态代码块 static { try { // 关键:路径必须是 classpath 下的 resources 目录 InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties"); Properties props = new Properties(); props.load(is); // 此处若抛 NullPointerException,90%是 db.properties 路径错 // ... 后续解析 props 获取 url/username/password } catch (Exception e) { e.printStackTrace(); } }

2.3 补全Maven依赖:三依赖缺一不可

打开pom.xml,确保包含以下核心依赖(版本号按项目实际调整,推荐统一用较新稳定版):

<dependencies> <!-- Servlet API:提供 HttpServletRequest/Response 等基础类 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> <!-- 注意:scope 必须为 provided,Tomcat 自带 --> </dependency> <!-- MySQL JDBC Driver:连接数据库 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> <!-- 与 db.properties 中 driver 版本严格匹配 --> </dependency> <!-- DBUtils:简化JDBC操作,避免手写ResultSet遍历 --> <dependency> <groupId>commons-dbutils</groupId> <artifactId>commons-dbutils</artifactId> <version>1.7</version> </dependency> </dependencies>

血泪经验:若IDEA提示Cannot resolve symbol 'QueryRunner',说明commons-dbutils未引入;若启动时报ClassNotFoundException: javax.servlet.http.HttpServlet,则是javax.servlet-api的scope写成了compile而非provided——Tomcat容器已提供该类,重复引入会冲突。

2.4 在IDEA中正确导入:两步绕过“Artifact is not configured”

  1. File → Project Structure → Project Settings → Project → Project SDK:选择你安装的JDK(必须JDK 8+,JavaWeb项目普遍不兼容JDK 17)
  2. File → Project Structure → Project Settings → Modules → Dependencies:点击+→JARs or directories→ 选中src/main/webapp/WEB-INF/lib/下的所有.jar(如commons-dbutils-1.7.jar),同时勾选Export(否则编译时找不到类)

关键动作:右键项目根目录 →Add Framework Support...→ 勾选Web Application→Version 4.0→OK。此时IDEA会自动生成artifacts配置,web.xml会被识别为部署描述符。

2.5 启动Tomcat并访问首页:验证路径映射是否生效

  1. 点击IDEA右上角Add Configuration→+→Tomcat Server→Local
  2. 在Deployment选项卡中,点击+→Artifact→ 选择your-project-name:war exploded
  3. 启动服务器,在浏览器输入:http://localhost:8080/
    • 若看到首页(通常是index.jsp渲染的餐厅Logo+“立即点餐”按钮),说明成功!
    • 若返回404,检查web.xml中<welcome-file-list>是否指向index.jsp:
      <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list>

3. 让登录和下单真正可用:三处关键代码修改与数据初始化

光有首页没用——用户点“登录”跳转404、加购后购物车为空、提交订单报空指针,才是真实场景。这三处修改直击业务主链路。

3.1 修复用户登录:Servlet路径与表单action必须严格一致

打开login.jsp,找到登录表单:

<!-- login.jsp --> <form action="LoginServlet" method="post"> <input type="text" name="username" /> <input type="password" name="password" /> <input type="submit" value="登录" /> </form>

检查src/main/java/com/xxx/servlet/LoginServlet.java的@WebServlet注解或web.xml配置:

// LoginServlet.java @WebServlet("/LoginServlet") // 注意:斜杠开头,与 form action 完全一致 public class LoginServlet extends HttpServlet { ... }

若web.xml中配置,则需匹配:

<servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>com.xxx.servlet.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/LoginServlet</url-pattern> <!-- 必须与 form action 一致 --> </servlet-mapping>

3.2 初始化测试数据:五条SQL让菜单和用户立刻可用

在MySQL中执行以下SQL(替换food_order为你创建的数据库名):

-- 创建用户表(若不存在) CREATE TABLE IF NOT EXISTS `user` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `username` VARCHAR(50) NOT NULL, `password` VARCHAR(50) NOT NULL, `role` VARCHAR(10) DEFAULT 'user' -- 'admin' 或 'user' ); -- 插入测试账号:用户名 admin,密码 123456(明文,仅测试用) INSERT INTO `user` (`username`, `password`, `role`) VALUES ('admin', '123456', 'admin'); INSERT INTO `user` (`username`, `password`, `role`) VALUES ('zhangsan', '123456', 'user'); -- 创建菜品表 CREATE TABLE IF NOT EXISTS `food` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(100) NOT NULL, `price` DECIMAL(10,2) NOT NULL, `category` VARCHAR(20) DEFAULT '主食', `image_path` VARCHAR(200) DEFAULT '/images/default.jpg' ); -- 插入三道测试菜 INSERT INTO `food` (`name`, `price`, `category`, `image_path`) VALUES ('宫保鸡丁', 28.00, '热菜', '/images/gongbao.jpg'), ('米饭', 2.00, '主食', '/images/rice.jpg'), ('酸梅汤', 12.00, '饮品', '/images/plum.jpg');

提示:image_path指向src/main/webapp/images/下的文件。若图片不存在,JSP中<img src="${food.image_path}">会显示空白,但不影响功能。建议先放一张default.jpg占位。

3.3 购物车持久化:Session vs Cookie 的取舍逻辑

点餐系统购物车通常存于HttpSession(非Cookie),因为需存储对象(如List<Food>)。检查AddToCartServlet.java:

// AddToCartServlet.java HttpSession session = request.getSession(); List<Food> cart = (List<Food>) session.getAttribute("cart"); if (cart == null) { cart = new ArrayList<>(); session.setAttribute("cart", cart); // 关键:存入session,非request或application } // ... 添加菜品逻辑

验证方法:在cart.jsp中打印session ID

<p>当前购物车ID:<%= session.getId() %></p>

若每次刷新页面ID不变,说明session正常;若变化,检查Tomcat配置或浏览器禁用了cookie。


4. 避坑指南:五个让新手当场崩溃的典型问题与解法

4.1 现象:启动Tomcat后控制台疯狂刷java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver

原因:mysql-connector-javaJAR包未被Tomcat加载。常见于两种情况:

  • IDEA中Project Structure → Modules → Dependencies未勾选Export(导致编译通过但运行时找不到)
  • pom.xml中mysql-connector-java依赖scope被误设为test或provided(应为compile)
    解决:
  1. 检查target/your-project-name/WEB-INF/lib/目录下是否存在mysql-connector-java-8.0.33.jar
  2. 若不存在,执行mvn clean package重新构建
  3. 在IDEAArtifacts配置中,确认WEB-INF/lib包含该JAR

4.2 现象:登录成功后跳转到/index.jsp,但页面显示“欢迎,null”

原因:LoginServlet中未将用户对象存入session,或存入的key与index.jsp中获取的key不一致。
排查步骤:

  1. 在LoginServlet.java的doPost末尾添加日志:
    System.out.println("即将存入session的user: " + user.getUsername()); session.setAttribute("user", user); // 注意key是"user"
  2. 在index.jsp中检查获取方式:
    <% User user = (User) session.getAttribute("user"); %> <p>欢迎,<%= user != null ? user.getUsername() : "游客" %></p>
    若user为null,说明setAttribute未执行(如密码校验失败直接return)或key写错(如写成"currentUser")

4.3 现象:点击“提交订单”报java.lang.NullPointerException,堆栈指向OrderDao.addOrder(...)

原因:OrderDao中QueryRunner未正确初始化,或数据库连接获取失败。
定位方法:

  1. 在OrderDao.java的addOrder方法开头加日志:
    System.out.println("QueryRunner instance: " + qr); // 若为null,说明构造函数未执行 System.out.println("Connection from DataSource: " + dataSource.getConnection()); // 若抛异常,说明db.properties配置错
  2. 检查OrderDao是否继承了BaseDao(含QueryRunner初始化),或是否手动new了QueryRunner但未传入DataSource

4.4 现象:JSP页面中文显示为乱码(如“????”),但数据库中数据正常

原因:JSP页面未声明字符编码,或Tomcat默认编码非UTF-8。
解决:

  1. 在所有JSP顶部添加:
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. 在web.xml中配置全局过滤器(推荐):
    <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

4.5 现象:管理员后台admin.jsp打不开,提示HTTP Status 403 – Forbidden

原因:项目启用了web.xml中的安全约束(<security-constraint>),但未配置登录认证。
检查点:

  1. 打开web.xml,搜索<security-constraint>标签
  2. 若存在,临时注释掉整个<security-constraint>块(生产环境需配<login-config>)
  3. 或确认<auth-constraint>中<role-name>与user表中role字段值一致(如<role-name>admin</role-name>对应数据库role='admin')

5. 连接MySQL的终极验证:用原生JDBC写一个独立测试类

别信“配置好了就行”,亲手写一段脱离Web容器的JDBC代码,才是检验数据库连通性的后悔药。这一步能提前暴露90%的驱动、URL、权限问题。

5.1 创建独立测试类:TestDBConnection.java

在src/test/java/下新建包com.xxx.test,创建类:

// src/test/java/com/xxx/test/TestDBConnection.java package com.xxx.test; import java.sql.*; public class TestDBConnection { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/food_order?useSSL=false&serverTimezone=Asia/Shanghai"; String username = "root"; String password = "your_password"; try (Connection conn = DriverManager.getConnection(url, username, password); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM food")) { if (rs.next()) { int count = rs.getInt(1); System.out.println("✅ 连接成功!菜品表共有 " + count + " 条记录"); } } catch (SQLException e) { System.err.println("❌ 连接失败:" + e.getMessage()); e.printStackTrace(); } } }

关键细节:

  • 使用try-with-resources自动关闭连接,避免资源泄漏
  • SELECT COUNT(*) FROM food比SELECT *更轻量,且能验证表存在性
  • 错误信息直接打印e.getMessage(),比IDEA堆栈更聚焦根本原因(如“Access denied for user”说明密码错,“Unknown database”说明库名错)

5.2 运行测试并解读结果

  1. 右键TestDBConnection.java→Run 'TestDBConnection.main()'
  2. 观察控制台输出:
    • ✅连接成功!菜品表共有 X 条记录→ 数据库层完全畅通,可放心调试Web层
    • ❌Access denied for user 'root'@'localhost'→ 检查MySQL用户密码,或执行ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password'; FLUSH PRIVILEGES;
    • ❌Unknown database 'food_order'→ 登录MySQL执行CREATE DATABASE food_order CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    • ❌No suitable driver found for jdbc:mysql://...→pom.xml中mysql-connector-java依赖未生效,或JDK版本与驱动不兼容(MySQL 8.0+需JDK 8+)

5.3 将测试逻辑注入Web层:在Servlet中复用验证

把上述逻辑封装成工具方法,插入到LoginServlet的init()方法中(仅开发期启用):

// LoginServlet.java public class LoginServlet extends HttpServlet { @Override public void init() throws ServletException { // 开发期自检:启动时验证数据库 if (!DBUtil.testConnection()) { throw new ServletException("数据库连接失败,服务无法启动"); } } }

其中DBUtil.testConnection()即复用TestDBConnection的核心逻辑。这样每次重启Tomcat,你都会在控制台第一眼看到数据库状态——比翻几十行日志高效得多。

我的习惯:在接手任何JavaWeb源码前,必先跑通这个独立测试类。它不解决业务逻辑,但能瞬间划清责任边界——如果这里都连不上,后面所有404、500都是假象,根源永远在数据库配置。省下三天排查时间,就靠这二十行代码。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询