多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

JSP+MySQL个人日记本毕设:源码结构、运行与改造全攻略

JSP+MySQL个人日记本毕设:源码结构、运行与改造全攻略 简介基于 JSP 与 MySQL 实现的个人日记本完整源码适合 Java Web 初学者、毕业设计或课程设计参考。项目涵盖用户登录注册、日记条目增删改查、分类管理、个人中心与密码修改等典型功能运行链路完整可帮助开发者理解 JSP 动态页面、Servlet 请求处理、JDBC 数据库操作、Session 会话保持以及表单验证等核心知识点具备较好的 Web 开发实践价值。压缩包共 90 个文件主要有 8 个 JSP 页面、18 个 Java 源码、27 个 HTML 静态页和 21 张 PNG 图片另含少量说明文档、PHP 辅助脚本及配置文件整体约 256KB目录结构清晰便于按模块检索。目前已有 222 人学习下载。通过阅读源码可快速掌握 JSPMySQL 小型项目的设计思路尤其适合想从零搭建个人博客或日记系统、并进一步学习 MVC 分层思想的开发者。1. 源码zip里的个人日记本为什么毕业设计总爱选它每年到了做毕设和课程设计的时间都会有人翻出一个老目录。基于 jspmysql 的 JSP 个人日记本源码.zip解压以后是一个标准 Java Web 工程JSP 页面、Servlet、JavaBean配一个 JDBC 直连 MySQL 的 DBUtil。它的定位非常明确——给“要交系统演示、要能改代码、要能讲清原理”的人用的不是给生产环境用的。适合拿来当基于 jsp 的毕设选题底子也适合当 java 课程设计案例源码做二次开发。它的问题是老但它能跑且结构足够简单一眼能看到头。你拿到手不是要读懂每一行而是先把它跑起来再做三处小改造让老师觉得这是你写的。2. 读懂JSPMySQL日记本的结构Model2 分层、三张表和一个连接工具类2.1 JSP只做展示业务逻辑交给Servlet和JavaBean这类源码最常见的技术骨架是 JSP Model2也就是 MVC 的 Java Web 版本。JSP 页面负责显示数据Servlet 接收请求、调用业务代码、决定跳转到哪个页面JavaBean 承载实体和少量的逻辑。很多第一次打开源码的人会犯一个错误以为所有功能都写在 JSP 里。实际翻一下目录就会发现JSP 页面只处理展示登录、注册、日记的增删改查都集中在 Servlet 层。一个典型的日记本项目会有这样几个包名bean放 User、Diary 这样的实体类dao放访问数据库的类servlet放各种 Controllerutil放工具类。页面在WebContent或webapp目录下面。判断一个源码整理得是否规范就看你能否在三分钟之内把这四个目录对上号。拿到手建议先把请求的流转顺序捋一遍用户在add_diary.jsp填完表单请求提交给DiaryServletServlet 把参数拼进Diary对象调用DiaryDao.addDiary()方法内部通过 DBUtil 拿到数据库连接执行 INSERT最后跳回列表页。这个链路在绝大部分 JSPMySQL 毕设项目里都是一样的你只要理顺一条整个系统就通了。2.2 日记本的“三张表”用户表、日记表以及最容易漏掉的分类字段数据库部分往往比代码更值得先看。不要一下去翻几十个 JSP 文件先把db.sql或init.sql打开看表结构。一个可正常交付的日记本最小数据模型是用户表和日记表两张表常见设计如下。用户表字段类型说明idINT AUTO_INCREMENT主键usernameVARCHAR(50)登录名唯一passwordVARCHAR(50)登录密码nicknameVARCHAR(50)展示昵称日记表字段类型说明idINT AUTO_INCREMENT主键user_idINT关联用户表diary_dateDATE日记日期titleVARCHAR(100)标题contentTEXT正文create_timeTIMESTAMP默认当前时间很多同学在这里会犯一个理解上的偏差日记表只写日期不写用户关联。如果这个表里没有user_id那它只能算“个人便签”不能算多人登录的日记本。登录功能做得再漂亮日记不区分归属答辩时一问就露馅。我一般拿到源码会把建表脚本里的每个字段为什么存在标一遍这个习惯能让你在答辩问答环节省很多事。2.3 一个DBUtil把MySQL和代码串起来这类源码里连接数据库的方式非常统一就是一个DBUtil工具类里面写死 MySQL 的地址、账号、密码通过DriverManager.getConnection()拿连接。代码大致长这样public class DBUtil { private static final String DRIVER com.mysql.jdbc.Driver; private static final String URL jdbc:mysql://127.0.0.1:3306/diary_db ?useUnicodetruecharacterEncodingUTF-8; private static final String USER root; private static final String PASSWORD 123456; static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } }这段代码的逻辑说明很简单静态代码块里通过Class.forName加载驱动只要类被加载一次驱动就注册到 DriverManager 中。每次调用getConnection()时DriverManager 根据 URL 里的jdbc:mysql找到刚才注册的驱动向 MySQL 发起连接请求。有三个参数你必须知道作用。第一characterEncodingUTF-8没有它存入 MySQL 的中文在页面上显示就会变成问号这是 JSP 项目乱码的头号原因。第二diary_db是数据库名建库时叫什么这里就要写什么。第三root/123456是本地数据库账号和密码如果你本机 MySQL 用的不是这个运行前必须改否则连不上。3. 本地跑通JDK/Tomcat/MySQL版本搭配与最小启动流程3.1 版本搭配为什么是“玄学”JDK 8 Tomcat 8.5 MySQL 5.7最稳拿到源码第一件事不是改代码是先把版本搭对。这个项目的技术栈决定了它不挑最新版本反而挑最稳的版本。经过大量类似源码的落地经验最稳妥的组合是 JDK 8、Tomcat 8.5、MySQL 5.7。这三个搭在一起兼容问题最少报错最容易查。为什么不能无脑用最新的Tomcat 10 以后把javax.servlet换成了jakarta.servlet老项目的代码里全是javax开头部署上去直接编译报错。JDK 版本太高同样麻烦JDK 11 以上对 Tomcat 8.5 的反射访问限制变严有时能跑但日志会刷一些奇怪警告。MySQL 8 本身可以用但要换驱动类和加时区参数对不熟悉的人来说又多一个报错点。我第一次带人跑这类源码时对方本机装了 MySQL 8 和 Tomcat 10折腾一下午全是版本坑。后来统一换成 8.5 加 5.7十分钟跑通。版本选得对省下的时间足够你把业务代码读一遍。3.2 第 1 步装好环境并验证 java、mysql、tomcat 三行命令不要凭感觉“我装过了”直接用命令行验证。这里能用后面部署才不卡壳。java -version mysql --version打开 CMD 或终端分别执行这两条命令。正常会输出类似java version 1.8.0_202和mysql Ver 14.14 Distrib 5.7.40的结果。如果提示java不是内部或外部命令先检查JAVA_HOME和PATHJDK 安装后再配环境变量这是 JDK 唯一容易出问题的地方。Tomcat 不需要装下载解压即可验证方式是用它的启动脚本。Windows 下运行bin/startup.batmacOS 或 Linux 下运行bin/startup.sh。启动后浏览器访问http://localhost:8080能看到 Tomcat 欢迎页就算成功。这一步任何报错都先别管先把欢迎页弄出来后面所有问题才有的放矢。3.3 第 2 步导入建库脚本别靠手点界面建表拿到源码的压缩包解压后在根目录或sql子目录里找.sql文件常见命名是diary_db.sql、db.sql或init.sql。这类文件内容通常是建库、建表、插入初始账号。用命令行导入最省事mysql -uroot -p123456 db.sql这里的root是你的 MySQL 账号123456是密码db.sql是脚本文件路径。如果担心密码暴露在命令行历史里可以去掉密码执行MySQL 会提示你输入。导入后进 MySQL 查看SHOW DATABASES; USE diary_db; SHOW TABLES;能查到你导入的日记库和表说明数据层准备好了。我一般会顺手执行一条SELECT * FROM user;确认初始账号存在。很多源码包里会内置一个admin / 123456或类似账号这个信息后面登录要用。3.4 第 3 步改数据库连接配置和JDBC驱动jar解压后的项目里找到src下的 DBUtil.java或src/db.properties。如果是 DBUtil.java把上一章贴过的那段代码打开把 URL、用户名、密码改成你本机的实际值。改完之后注意一点MySQL 5.7 的驱动 jar 和 MySQL 8 的不是同一个地方下载如果你本机是 MySQL 5.7驱动用mysql-connector-java-5.x.jar如果是 MySQL 8代码里的com.mysql.jdbc.Driver要改成com.mysql.cj.jdbc.Driver。驱动 jar 放哪里也很关键必须放在WebContent/WEB-INF/lib或webapp/WEB-INF/lib目录下。有同学图快把 jar 添加到 IDE 的 Build Path 就以为成了结果部署到 Tomcat 里启动时一脸懵。原因是 Tomcat 运行时加载的是 WEB-INF/lib 下的 jar和你 IDE 里的 Build Path 没关系。3.5 第 4 步扔进Tomcat webapps目录浏览器访问首页配置改完后把整个项目目录复制到 Tomcat 的webapps目录下。如果你的项目文件夹叫diary复制完成后确保路径是webapps/diary/WEB-INF/web.xml。然后在 Tomcat 的 bin 目录启动服务bin/startup.sh启动日志如果闪过Deploying web application archive或Deployment of web application directory说明项目已经被容器加载。浏览器输入http://localhost:8080/diary/这里diary是项目目录名如果首页有指定的 servlet 路径比如访问login.jsp或index.jsp再加上具体页面名。看到登录页输入源码里预置的账号密码能进到日记列表页整个链路就通了。4. 改三次把“别人的源码”变成“你的课程设计”4.1 改一给日记加分类字段让老师一眼看到你用到了UPDATE直接用原版源码交差最常见的质疑是“这个项目太简单没有业务规则”。最简单的破法是加一个“情感分类”字段让日记除了标题和正文还有分类维度。这个改造涉及三处表结构、新增页面、SQL 语句。先加字段ALTER TABLE diary ADD COLUMN category VARCHAR(20) DEFAULT 生活;这条 SQL 给日记表加了category列默认值设置成“生活”。在新增日记的 JSP 页面里加一个下拉框select namecategory option value工作工作/option option value生活生活/option option value学习学习/option /select最后改 DAO 里的 INSERT 语句。这里点一下 MySQL 的 INSERT 语法中字段和值必须一一对应INSERT INTO diary (user_id, diary_date, title, content, category) VALUES (?, ?, ?, ?, ?);逻辑说明?是 PreparedStatement 的参数占位符一行一个顺序不能乱。修改之后原来的四行 INSERT 变五行对应的setInt、setString都要同步补一个。改造完列表页可以加一个按分类筛选的下拉框SQL 里用WHERE category ?过滤效果非常直观。4.2 改二标题关键字搜索在JSP页面和DAO各加一段第二个改造做一个按标题关键字的搜索框。原版源码的日记列表页通常只有一个列表加一个搜索框会让页面更完整同时也能展示你会写动态 SQL。页面部分加一个表单form actionDiaryServlet methodget input typetext namekeyword placeholder输入日记标题关键词 button typesubmit搜索/button /formDAO 层把原来的查询方法改成带条件查询。原写法往往是String sql SELECT * FROM diary WHERE user_id? ORDER BY diary_date DESC;改成String keyword request.getParameter(keyword); String sql SELECT * FROM diary WHERE user_id? AND title LIKE ? ORDER BY diary_date DESC;注意LIKE后面的参数需要手动拼接通配符要在 DAO 层做不要在 SQL 里用字符串拼接ps.setString(2, % keyword %);逻辑说明%是 MySQL 的模糊匹配通配符%关键字%表示包含关键字的任意位置都能匹配。为什么不直接写LIKE % keyword %因为你把用户输入直接拼进 SQL输入框里写个 OR 11 --你的条件就被绕过了。用 PreparedStatement 传参MySQL 的驱动会把用户输入当普通字符串处理这就是毕设答辩里可以说两句的 SQL 注入问题。4.3 改三用MD5替换明文密码答辩时能讲的安全点大多数 JSPMySQL 课设源码里密码是明文存储的。你在数据库里能看到password字段直接开着123456这本身没什么技术风险但答辩时容易被问住。稍微改改把密码用 MD5 摘要后存储整段系统看起来就多了一个可以展开的亮点。工具类public static String md5(String input) { try { MessageDigest md MessageDigest.getInstance(MD5); byte[] digest md.digest(input.getBytes(UTF-8)); StringBuilder sb new StringBuilder(); for (byte b : digest) { sb.append(String.format(%02x, b)); } return sb.toString(); } catch (Exception e) { throw new RuntimeException(e); } }逻辑说明MessageDigest是 JDK 自带的消息摘要工具md.digest把字符串按 MD5 算法转成 16 字节数组String.format(%02x, b)把一个字节格式化成两位十六进制的字符串。修改注册和登录的代码密文存储和校验// 注册时 ps.setString(2, MD5Util.md5(password)); // 登录时 String md5Pwd MD5Util.md5(password); String sql SELECT * FROM user WHERE username? AND password?;改完后有个细节要处理原有数据库里的明文密码已经进不去了需要重新用注册页注册一个新账号或手动把当前账号的密码改成密文存储的哈希值。改密码也可以用 UPDATE 语法操作正好面试老师问“你还会写 UPDATE 吗”的时候可以直接现场改一条分类字段把话题引到你改造过的 category 字段上。5. 本地运行避坑清单6个常见的“跑不起来”故障排查5.1 连不上MySQLerror 2002 (HY000) 是服务没启动不是代码问题现象页面一提交就报错后台异常信息里有Cannot create PoolableConnectionFactory或Communications link failure命令行执行 mysql 报ERROR 2002 (HY000): Cant connect to local MySQL server through socket /tmp/mysql.sock。原因MySQL 服务根本没起来。很多同学安装完 MySQL 后没启动服务或者安装时选的不是开机启动模式。代码和数据库配置写对了但服务没监听连接自然失败。解决把 MySQL 服务启动。Windows 用服务管理器找到 MySQL57 或 MySQL 服务点击启动Linux 执行systemctl start mysqld或service mysql start。启动后确认端口监听netstat -an | grep 3306。看到LISTEN状态再跑项目。这一类问题占了本地跑不通故障的一半先查服务再查代码。5.2 java.lang.ClassNotFoundException: com.mysql.jdbc.Driver现象Tomcat 启动正常但一访问触发数据库操作的页面就报ClassNotFoundException: com.mysql.jdbc.Driver。过了几秒又提示Cannot load driver class。原因驱动 jar 缺失或者驱动类名和 MySQL 版本不匹配。MySQL 5.x 时代驱动类是com.mysql.jdbc.DriverMySQL 8 以后改成了com.mysql.cj.jdbc.Driver。解决先确认WEB-INF/lib下确实有mysql-connector-java的 jar 包。没有就下载对应版本放进去并重新启动 Tomcat。如果你用的 MySQL 8 但代码还是老驱动类名把代码改成Class.forName(com.mysql.cj.jdbc.Driver);同时给 URL 后面补一个serverTimezoneAsia/Shanghai否则 MySQL 8 还会报时区错误。5.3 Tomcat 10 导致 javax.servlet 全报错别拿新容器跑老项目现象项目部署到 Tomcat 后访问页面报无法将 JSP 编译为类后台异常里有NoClassDefFoundError: javax/servlet/ServletException或一长串跟jakarta相关的错误。原因Tomcat 10 已经全面切换到了 Jakarta EE包名从javax.servlet.*变成jakarta.servlet.*。老 JSP 项目里的javax全部失效这种源码是为 Tomcat 9 之前的容器写的。解决换回 Tomcat 8.5 或 Tomcat 9 版本代码一行不用改。这里没有任何讨巧的配置也不建议手动把所有javax替换成jakarta因为 JSP 内置对象、隐式引用底层还牵扯着 Tomcat 的编译配置改一半更难受。这类源码用 8.5 是最省事的。5.4 页面上全是问号/乱码字符集三处要一起改现象JSP 页面显示英文正常中文标题显示成???或者数据库里存进去就是乱码。刷新几次有时正常有时乱。原因字符集链路没打通。HTTP 请求、数据库连接、表字段三处只要有一处是latin1或默认字符集中文就可能在传输过程中损坏。解决三处统一设置。第一处JSP 页面顶部写pageEncodingUTF-8第二处数据库连接 URL 加参数useUnicodetruecharacterEncodingUTF-8第三处建库时在 SQL 里显式指定字符集CREATE DATABASE diary_db DEFAULT CHARACTER SET utf8mb4;utf8mb4是 MySQL 5.5.3 以后完整支持 UTF-8 的字符集能存 emoji 和四字节中文符号。如果一个项目已经用默认latin1建了库修改后最好把表也转一下ALTER TABLE diary CONVERT TO CHARACTER SET utf8mb4;5.5 改了代码不生效注意部署目录和源码目录是两个地方现象IDE 里把 Servlet 改了刷新页面还是旧效果。打印日志也还是旧内容重启 Tomcat 也没用。原因Tomcat 部署的不是你的源码目录而是编译后的classes或加载后的项目副本。直接在webapps下运行的项目Tomcat 可能已经解压并缓存了旧版本。解决清理 Tomcat 的工作目录。Tomcat 的work/Catalina下面有编译后的 JSP Servlet 缓存把这个目录清空。如果用 IDE 集成 Tomcat确认代码修改后 IDE 是否执行了重新发布Republish。我自己带项目时有个习惯改完 Java 代码先停 Tomcat然后把webapps下的旧项目删掉再从源码目录重新复制部署这一步虽然麻烦但能杀掉一大批“改了不生效”的幻觉问题。5.6 登录成功后跳回登录页Session丢了先查cookie和路径现象登录页输入正确账号密码提示登录成功但页面一下跳回登录页。反复登录都进不去。原因绝大多数情况下是 Session 保存失败或者是跳转路径出问题。JSP 项目里登录成功后会把用户身份写进 Session比如session.setAttribute(user, user)。如果后面页面判断 Session 的代码位置不对或者跳转用的路径写成了绝对路径index.jsp请求落在当前目录下就会回到登录逻辑。解决打开浏览器的开发者工具查看网络请求。看登录成功后的地址栏路径。我见过很多次是登录成功后跳转地址写错response.sendRedirect(/diary/index.jsp)和response.sendRedirect(index.jsp)的区别在于前者是项目根路径后者是相对路径。如果目录结构是webapps/diary/index.jsp那么正确跳转应该是response.sendRedirect(/diary/index.jsp)。另外确认一下同目录下有没有多个 index 页面比如index.jsp和index.html同时存在Tomcat 的默认欢迎页优先级会直接访问 html 文件把原有逻辑绕过去了。6. 答辩前半小时5项检查单与几个能加分的细节6.1 演示前固定走一遍这 5 项检查项操作方法通过标准MySQL 服务service mysql status或任务管理器3306 端口在监听Tomcat 服务浏览器访问 8080 端口出现 Tomcat 欢迎页登录账号用源码里预置账号登录正常进入日记列表页中文提交新增一条中文标题日记列表页显示无乱码搜索功能输入标题关键词搜索只显示匹配日记这 5 项是我经手这类项目时固定演示前走的流程。特别是第四项很多项目在登录、查询时都正常一到新增操作就暴露字符集问题。提前测一遍比演示现场翻车强得多。6.2 老师问“有什么不足”时怎么回答显得你懂行不要回答“没什么不足”。一个 JSPMySQL 的日记本明摆着的不足有三个提前想好怎么答。第一JDBC 直连没有连接池高并发下会频繁创建连接。这个可以答“我了解过 C3P0 和 Druid在后续版本里可以引入连接池管理”。第二MD5 不是安全的加密算法彩虹表可以破解。可以说“我知道要用加盐哈希或 BCrypt但课程设计里为了演示登录匹配逻辑我选择了 MD5”。第三没有分页日记多了之后列表会很长。可以说“查询语句支持 LIMIT 偏移预留了分页改造位”。主动暴露小缺陷并给出方案比回答得完美更像真做过。我有个习惯答辩或演示前会给自己留一张“后悔药”备忘把本机 MySQL 的账号密码写在标签上贴在电脑边缘把预置登录账号记在手机备忘录里。这些东西平时觉得绝不可能忘但紧张环境下真的会手滑输错三次以下。所有代码和文档都备份一份到另一个目录演示现场永不碰“重新解压”和“重新导入”这种操作。跑通一次就跑通了别在现场制造变量。最后再说一次版本搭配JDK 8、Tomcat 8.5、MySQL 5.7这套组合能让你省掉大部分“怎么别人能跑我不能”的折腾时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表