首页 / 资讯中心 / 文章详情

JSP记账系统毕设实战:JDK8+Tomcat8.5+MySQL5.7环境搭建与避坑指南

JSP记账系统毕设实战:JDK8+Tomcat8.5+MySQL5.7环境搭建与避坑指南 ★ FEATURED ARTICLE
简介本资源是一套完整的基于JSP技术的记账管理系统毕业设计实现方案面向计算机相关专业本科生及Java Web初学者聚焦课程设计、毕设选题与Web开发实践能力提升。系统采用B/S架构以JSPServletMySQL为核心技术栈覆盖用户管理、账目录入、分类统计、报表导出等典型财务功能具备可运行、可部署、可扩展的工程完整性。压缩包共91.24MB包含项目报告含需求分析、系统设计与测试、答辩PPT逻辑清晰、重点突出、完整源代码含JSP页面、Java类、配置文件、MySQL数据库脚本含建表语句与示例数据以及全流程部署教学视频含环境配置、项目导入、数据库连接与运行演示。目前已有254人学习下载内容组织规范模块划分明确特别适合零基础入门Java Web开发、快速理解MVC分层结构与毕业设计文档撰写规范的学习者。1. 为什么一个用 JSP 做的记账系统至今仍是高校毕业设计的“稳态选择”不是因为它多先进——Servlet 3.0 都是十年前的规范了也不是因为技术栈多稀缺——Spring Boot 三行代码起服务的时代JSP 页面里还嵌着% out.print(Hello); %这种“古董语法”。但它偏偏在某高校连续五年、某实验室七届本科生的毕设选题池里始终稳居 Top 3。原因很实在它够轻、够全、够可控。一个能跑通登录→记账→分类统计→导出报表全流程的 JSP 系统不依赖云服务、不强求 Docker 编排、不卡在 Maven 仓库镜像同步失败上学生能在一台 8GB 内存的笔记本上从 Tomcat 下载、JDK 配置、数据库建表、页面调试一路敲到部署视频录完。它不解决高并发记账场景但能扎实覆盖 Web 开发核心闭环前后端交互逻辑、MVC 分层意识、SQL 注入防范意识、会话状态管理、基础权限控制。如果你正面临开题 deadline、导师只认“可演示、有源码、能讲清流程”的硬指标这个 JSP 记账系统不是怀旧而是经过千人验证的最小可行交付体。2. 从零搭起可运行环境JDK Tomcat MySQL 的黄金三角配置JSP 不是独立语言它是 Java Web 技术栈里最贴近“手写时代”的一层胶水。要让它动起来必须亲手把三个组件拧紧JDK 提供编译与运行时Tomcat 承载 Servlet 容器MySQL 存储每一笔收支。这不是装个 IDE 就完事的流程每一步的版本对齐和路径细节直接决定你能否在http://localhost:8080/account/login.jsp看到第一个登录框。2.1 JDK 8u202 是当前最稳妥的基线版本别碰 JDK 17——不是它不行而是 JSP 编译器Jasper在新版中默认禁用脚本片段% %而毕业设计源码里大量存在这类写法。强行启用需改web.xml加jsp-config节点新手极易漏配导致 500 错误。JDK 8u202 是 Oracle 最后一个公开更新的 JDK 8 版本兼容性已由数万份毕设项目验证。# 检查是否生效必须输出 1.8.0_202 java -version # 同时确认 JAVA_HOME 指向正确路径Windows 示例 echo %JAVA_HOME% # Linux/macOS 请确保 ~/.bashrc 中有 # export JAVA_HOME/usr/lib/jvm/java-8-openjdk-amd64提示java -version输出含OpenJDK也可用但务必确认其为 8u202 或同级如build 1.8.0_202-b08。OpenJDK 11 默认不支持% %切勿混用。2.2 Tomcat 8.5.94唯一推荐的容器版本Tomcat 9 默认启用 HTTP/2 和更严格的 MIME 类型校验而 JSP 源码中常见link relstylesheet hrefcss/style.css却未声明typetext/css导致 CSS 不加载Tomcat 10 已全面迁移到jakarta.*命名空间所有javax.servlet.*包全部失效——这意味着你连HttpServlet都 import 不进来。Tomcat 8.5.94 是最后一个完整支持javax.*且对静态资源宽容的稳定版。# 解压后进入 bin 目录Windows 执行 startup.bat # Linux/macOS 执行 chmod x startup.sh ./startup.sh # 观察 logs/catalina.out 是否出现 # INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [xxx] milliseconds参数说明启动前务必检查conf/server.xml中Connector port8080是否未被注释若端口被占用改port8081即可后续所有 URL 改为:8081。2.3 MySQL 5.7.39避免字符集与权限的双重陷阱MySQL 8.0 默认caching_sha2_password插件而 JSP 项目中Class.forName(com.mysql.jdbc.Driver)使用的是老版 JDBC 驱动mysql-connector-java-5.1.47.jar无法握手认证。MySQL 5.7.39 仍用mysql_native_password开箱即用。同时必须显式创建数据库并指定字符集否则中文记账内容入库后变???。-- 登录 MySQL 后执行注意分号结尾 CREATE DATABASE account_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER account_userlocalhost IDENTIFIED BY acc0unt2024; GRANT ALL PRIVILEGES ON account_db.* TO account_userlocalhost; FLUSH PRIVILEGES;逻辑说明utf8mb4是真正支持 4 字节 UTF-8如 emoji、生僻汉字的编码utf8在 MySQL 中仅是阉割版最多 3 字节FLUSH PRIVILEGES强制重载权限表否则新用户无法连接。3. 源码结构解剖看懂.jsp、.java、.properties三类文件如何协同记账拿到.zip解压后你会看到典型的 Java Web 项目结构/WebContent下是前端页面/src下是 Java 类/WEB-INF/web.xml是总调度员。但毕业设计源码常因压缩/打包过程丢失关键路径或配置直接丢进 Tomcat 会 404。必须按三层定位法逐层校验。3.1/WebContent是你的“可见世界”JSP 页面的生存法则标准结构应为/WebContent/ ├── login.jsp ← 入口页面必须存在且可访问 ├── index.jsp ← 主页登录后跳转目标 ├── account/ │ ├── add.jsp ← 新增记账页 │ ├── list.jsp ← 账单列表页 │ └── report.jsp ← 统计报表页 └── css/js/images/ ← 静态资源路径必须与 JSP 中 href/src 一致关键检查点所有 JSP 文件顶部必须有% page contentTypetext/html;charsetUTF-8 %缺则中文乱码form actionservlet/AddAccountServlet中的action值必须与web.xml中servlet-mapping的url-pattern完全一致注意大小写和斜杠若页面引用js/common.js则实际路径必须是/WebContent/js/common.js而非/src/js/——JSP 只能访问WebContent及其子目录。3.2/src是你的“逻辑心脏”Servlet 与 DAO 的调用链必须闭合典型调用链add.jsp→AddAccountServlet.java→AccountDAO.java→DBUtil.java→ 数据库。任一环断裂表单提交就卡死。// 示例AddAccountServlet.java 关键片段注意包声明与 import package servlet; // 必须与 web.xml 中 servlet-class 一致 import dao.AccountDAO; import util.DBUtil; public class AddAccountServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) { String amount request.getParameter(amount); AccountDAO dao new AccountDAO(); // 实例化 DAO boolean success dao.addRecord(amount); // 调用数据库方法 if (success) { response.sendRedirect(account/list.jsp); // 成功跳转 } else { request.setAttribute(error, 保存失败); request.getRequestDispatcher(account/add.jsp).forward(request, response); } } }参数说明response.sendRedirect()是客户端跳转URL 变request.getRequestDispatcher().forward()是服务器端跳转URL 不变但能传 request 属性。毕业设计中两者混用是常见翻车点——比如错误信息用sendRedirect就丢失了request.setAttribute()。3.3/WEB-INF/web.xml是“交通警察”URL 映射必须字字精准这是整个项目路由的宪法。若此处写错所有 Servlet 请求都会 404。!-- web.xml 片段Servlet 定义 -- servlet servlet-nameAddAccountServlet/servlet-name servlet-classservlet.AddAccountServlet/servlet-class /servlet !-- URL 映射注意 url-pattern 必须带 / 且与 JSP 中 action 一致 -- servlet-mapping servlet-nameAddAccountServlet/servlet-name url-pattern/servlet/AddAccountServlet/url-pattern /servlet-mapping逻辑说明servlet-class的值是完整类路径含包名url-pattern是浏览器地址栏中?前的部分。例如访问http://localhost:8080/account/servlet/AddAccountServlet其中/account/是应用上下文即项目文件夹名/servlet/AddAccountServlet是 pattern。4. 数据库落地实操从 SQL 脚本建表到 JDBC 连接验证毕业设计附带的database.sql往往是半成品字段类型不匹配、主键缺失、外键未启用、中文注释乱码。直接source database.sql极易报错。必须人工校验并分步执行。4.1 表结构四要素校验清单以核心表t_account为例执行前逐项核对检查项正确写法示例错误示例后果存储引擎ENGINEInnoDB DEFAULT CHARSETutf8mb4ENGINEMyISAM事务不支持中文乱码主键定义id INT PRIMARY KEY AUTO_INCREMENTid INT无 PRIMARY KEY插入失败ID 为 0时间字段create_time DATETIME DEFAULT CURRENT_TIMESTAMPcreate_time VARCHAR(20)时间无法自动填充注释语法COMMENT 记账金额单引号COMMENT 记账金额双引号MySQL 5.7 报错-- 正确建表语句可直接执行 CREATE TABLE t_account ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 主键ID, amount DECIMAL(10,2) NOT NULL COMMENT 金额, category VARCHAR(20) NOT NULL COMMENT 类别, remark TEXT COMMENT 备注, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT记账主表;4.2 JDBC 连接字符串一个符号定生死/src/util/DBUtil.java中的连接字符串是数据库连通的最后关卡。常见错误集中于?后参数拼写和编码声明。// 正确写法MySQL 5.7 mysql-connector-java-5.1.47 private static final String URL jdbc:mysql://localhost:3306/account_db?useUnicodetruecharacterEncodingUTF-8serverTimezoneGMT%2B8; // 错误写法举例会导致连接成功但中文存为 ??? // ❌ 缺少 characterEncodingUTF-8 // ❌ serverTimezoneUTC中国服务器应为 GMT%2B8 // ❌ useSSLtrueMySQL 5.7 默认关闭 SSL设 true 反而报错参数说明%2B8是8的 URL 编码因在 URL 中表示空格useUnicodetrue启用 Unicode 支持characterEncodingUTF-8指定传输编码二者缺一不可。4.3 连接测试写一段独立 Java 类验证不要等跑完整项目才知数据库不通。新建TestDBConnection.java独立验证// 文件位置/src/TestDBConnection.java import java.sql.*; public class TestDBConnection { public static void main(String[] args) { String url jdbc:mysql://localhost:3306/account_db?useUnicodetruecharacterEncodingUTF-8serverTimezoneGMT%2B8; String user account_user; String pwd acc0unt2024; try (Connection conn DriverManager.getConnection(url, user, pwd)) { System.out.println(✅ 数据库连接成功); try (Statement stmt conn.createStatement(); ResultSet rs stmt.executeQuery(SELECT COUNT(*) FROM t_account)) { if (rs.next()) { System.out.println( 当前账单总数 rs.getInt(1)); } } } catch (SQLException e) { System.err.println(❌ 连接失败 e.getMessage()); e.printStackTrace(); } } }执行方式在命令行中cd到/src目录执行javac -cp .:../lib/mysql-connector-java-5.1.47.jar TestDBConnection.java java -cp .:../lib/mysql-connector-java-5.1.47.jar TestDBConnection注意-cp中的分隔符Windows 用;Linux/macOS 用:。5. 部署视频录制与答辩 PPT 设计让评审老师一眼看懂你的工作量答辩不是代码秀而是逻辑呈现。老师平均每人看 15 份毕设你只有 8 分钟。PPT 不是源码截图堆砌视频不是功能点罗列。必须用“问题-解法-证据”三幕剧结构把技术决策讲成故事。5.1 PPT 四页铁律封面、架构图、核心流程、总结页封面页标题姓名学号日期加一行小字“基于 JSP/Servlet/MVC 模式的轻量级个人记账系统”点明技术栈与定位架构图页手绘风格 UML 部署图非 Visio 自动生成标注Browser → Tomcat(JSP/Servlet) → MySQL三层箭头旁写HTTP、JDBC体现分层意识核心流程页聚焦一个高频操作如“新增一笔餐饮支出”用 4 步流程图展示用户在add.jsp输入金额、选择“餐饮”类别表单 POST 到/servlet/AddAccountServletServlet 调用AccountDAO.addRecord()执行 INSERTDAO 通过DBUtil.getConnection()获取连接并提交事务每步旁加一句技术价值“步骤2体现请求分发机制”、“步骤3体现数据访问抽象”总结页只列 3 条真实收获如✅ 掌握了 JSP 页面生命周期与内置对象request,session的实际作用域✅ 理解了 MVC 中 ControllerServlet与 ModelDAO的职责边界✅ 实践了 SQL 注入防护所有参数均使用PreparedStatement而非字符串拼接5.2 部署视频3 分钟内完成“可验证交付”视频不是录屏全过程而是剪辑出 5 个关键帧每帧停留 3 秒配画外音解说时间点画面内容画外音脚本精简0:00Tomcatstartup.bat运行成功日志“第一步启动 Tomcat 容器监听 8080 端口”0:15浏览器打开http://localhost:8080/account/login.jsp“第二步访问登录页JSP 页面正常渲染”0:35输入账号密码点击登录跳转至index.jsp“第三步凭据验证通过进入主界面”1:20在add.jsp输入 50 元、选‘交通’、提交“第四步新增记录后端接收并持久化到数据库”2:05list.jsp显示刚添加的账单含正确金额与时间“第五步数据实时查询展示闭环验证完成”提示视频开头加 2 秒黑屏白字“本系统部署于本地 Windows 10 环境JDK 8u202 Tomcat 8.5.94 MySQL 5.7.39”消除环境质疑。5.3 答辩现场必答三问预判老师思维路径老师不会问“JSP 是什么”而是从交付质量反推你的理解深度Q1“为什么不用 Spring Boot”→答“本次设计目标是掌握 Web 开发底层机制。Spring Boot 封装了自动配置与内嵌容器反而掩盖了 Servlet 生命周期、web.xml 配置、JDBC 手动管理等核心概念。我选择 JSP 是为了亲手构建每一层而非调用一个RestController。”Q2“登录密码明文存储是否安全”→答“在需求文档中明确限定为‘个人单机记账系统’无多用户并发与网络暴露风险。但我在UserDAO.java中预留了encryptPassword()方法 stub并在报告第 3.2 节说明若升级为多用户系统将集成 BCrypt 加密。”Q3“报表功能只有页面展示没导出 Excel”→答“当前实现基于 HTML Table 渲染符合基础功能要求。我在扩展计划中提出可引入 Apache POI 库在report.jsp添加‘导出 Excel’按钮调用ExportExcelServlet生成.xlsx文件——这正是我下一步想深入的技术点。”6. 避坑指南那些让答辩前夜崩溃的 5 个真实血泪经验这些不是教科书里的“注意事项”而是某高校连续三年毕设季助教在凌晨两点收到的最高频求助。每一条都对应一个具体错误现象、根本原因和可立即执行的修复命令。6.1 现象登录成功后跳转index.jsp页面空白查看源码全是乱码字符→原因index.jsp文件本身是 GBK 编码保存但页面顶部% page contentTypetext/html;charsetUTF-8 %声明为 UTF-8浏览器按 UTF-8 解码 GBK 字节流必然乱码。→解决用 VS Code 或 Notepad 打开index.jsp右下角查看当前编码点击切换为UTF-8保存。切勿用记事本另存为 UTF-8它会加 BOM 头JSP 解析器会报错。6.2 现象add.jsp提交后页面卡住浏览器显示“正在连接 localhost:8080”F12 Network 标签页中请求状态为pending→原因web.xml中servlet-mapping的url-pattern写成了/AddAccountServlet缺/servlet/前缀而add.jsp表单actionservlet/AddAccountServlet发送请求到不存在的路径Tomcat 无法路由连接挂起。→解决打开web.xml找到servlet-mapping将url-pattern改为与action属性完全一致的值包括大小写和斜杠数量。6.3 现象数据库能连上但list.jsp查不到任何数据后台日志无报错→原因AccountDAO.java中 SQL 查询语句写成SELECT * FROM account但实际表名是t_account带前缀t_MySQL 严格区分表名大小写尤其 Linux 环境account表不存在。→解决在 MySQL 中执行SHOW TABLES;确认真实表名然后修改 DAO 中所有 SQL 语句的表名为t_account。永远不要假设表名与类名一致。6.4 现象login.jsp提交用户名密码LoginServlet.java中request.getParameter(username)返回null→原因login.jsp中input标签缺少name属性如input typetext idusername只有id没有name表单提交时该字段不会被发送。→解决检查所有input、select、textarea确保均有namexxx且name值与 Servlet 中getParameter(xxx)的字符串完全一致。6.5 现象部署到另一台电脑Tomcat 启动报错java.lang.ClassNotFoundException: com.mysql.jdbc.Driver→原因mysql-connector-java-5.1.47.jar未放入/WebContent/WEB-INF/lib/目录。Tomcat 只扫描此目录下的 jar 包/lib/项目根目录或CLASSPATH环境变量中的 jar 对 Web 应用无效。→解决将mysql-connector-java-5.1.47.jar复制到/WebContent/WEB-INF/lib/重启 Tomcat。验证命令ls /WebContent/WEB-INF/lib/ | grep mysql应输出 jar 文件名。7. 一个让老师眼前一亮的进阶技巧用 Filter 实现统一登录拦截毕业设计的登录验证90% 的同学写在每个 Servlet 的doGet/doPost开头如if(session.getAttribute(user)null) response.sendRedirect(login.jsp)。这叫“横切关注点分散”是代码坏味道。用Filter实现统一拦截只需 3 步就能让架构图瞬间专业感拉满。7.1 创建 LoginFilter.java拦截所有受保护路径// 文件位置/src/filter/LoginFilter.java package filter; import javax.servlet.*; import javax.servlet.http.*; import java.io.IOException; public class LoginFilter implements Filter { Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req (HttpServletRequest) request; HttpServletResponse resp (HttpServletResponse) response; // 定义需要登录才能访问的路径前缀 String path req.getServletPath(); if (path.startsWith(/account/) || path.startsWith(/user/)) { HttpSession session req.getSession(false); if (session null || session.getAttribute(user) null) { resp.sendRedirect(req.getContextPath() /login.jsp); return; // 拦截不放行 } } chain.doFilter(request, response); // 放行 } }逻辑说明getServletPath()返回 URL 中?前的部分如/account/list.jspgetContextPath()返回应用名如/account拼接后重定向到正确上下文路径。7.2 在 web.xml 中注册 Filter声明拦截规则!-- web.xml 末尾添加 -- filter filter-nameLoginFilter/filter-name filter-classfilter.LoginFilter/filter-class /filter filter-mapping filter-nameLoginFilter/filter-name url-pattern/*/url-pattern !-- 拦截所有请求 -- /filter-mapping参数说明url-pattern/*/url-pattern表示拦截所有请求Filter 代码内部再用path.startsWith()做细粒度判断比写多个 mapping 更灵活。7.3 效果验证与答辩话术部署后测试访问http://localhost:8080/account/list.jsp未登录→ 自动跳转login.jsp登录成功后再次访问 → 正常显示账单列表访问http://localhost:8080/login.jsp无需登录→ 不跳转正常显示答辩话术“我用 Filter 实现了 AOP 思想的前置拦截将登录校验这一横切逻辑从业务 Servlet 中剥离。这样既避免了代码重复又提升了可维护性——未来若要增加 IP 白名单或请求频率限制只需修改 Filter无需改动每个 Servlet。”这是我带过的某跨平台系统课程设计中A同学在答辩时用的方案。他没提“Spring AOP”只说“把登录检查从 5 个 Servlet 里抽出来集中管”老师当场在评分表“架构设计”栏打了满分。技术深度不在于用了多炫的词而在于你是否真的把一个问题拆解到了能动手、能解释、能演化的程度。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站