简介:基于jsp+mysql的个人日记本项目源码,适用于正在学习Java Web开发的初学者,或需要课程设计与毕业设计参考的读者。项目覆盖用户登录验证、Session会话保持、日记分类管理、个人中心维护及数据库增删改查等典型场景,能帮助把JSP、Servlet、JDBC和MVC分层等知识点串联到完整实践流程中。压缩包共90个文件,以18个Java类承担控制与业务逻辑、8个JSP页面构建动态视图,另有27个HTML辅助静态页、21张PNG图片和6个Markdown文档辅助理解,包体仅256KB,结构清晰、便于快速查阅。已有223人在CSDN浏览或下载该源码。配合描述与源码目录,读者可重点学习表单提交处理、Session管理、JDBC连接池配置、日记分类增删改查等实现细节,也可直接复用其前台页面与后台交互框架,作为二次开发或实验教学的实用样本。
1. 个人日记本 JSP 源码下载后跑不起来?先看懂它再动手
很多人下载“基于jsp+mysql的JSP个人日记本源码.zip”之后,第一件事就是解压、导入 IDE、点运行,然后被一串红字劝退。这个源码包的本质是一个老牌的 Java Web 课程设计:JSP 做页面、Servlet 做控制、MySQL 存数据,跑在 Tomcat 上。它能解决两类问题:一是让刚学完 Java Web 的人弄明白一个完整项目的请求链路和增删改查怎么串起来;二是给要交课程设计的人一个底子,改成自己的日记管理功能。但它的坑也集中在这套老技术栈上——JDK/Tomcat 版本不匹配、MySQL 驱动不兼容、中文乱码。本文按“环境准备 → 部署 → 排错 → 改代码”的顺序,把这类源码跑通并改成能答辩的作业。
2. 跑通前的环境准备:JDK、Tomcat、MySQL 的版本搭配与安装
2.1 JDK 与 Tomcat 的版本匹配:为什么 1.8 + Tomcat 8.5 最稳
这类源码大多数是在 JDK 1.8 时代写的,用 Eclipse 或 MyEclipse 导出,JSP 里还留着<%@ page import=... %>这种老写法。如果你电脑上装的是 JDK 17 甚至更高,直接用 Tomcat 10+ 去跑,很可能在启动阶段就报jakarta.servlet相关的错,那是因为 Tomcat 10 把原来的javax.servlet包迁移到了jakarta.servlet,老源码没有跟着换。
我一般会建议先统一用最稳的组合:JDK 1.8 + Tomcat 8.5.x + MySQL 5.7。Tomcat 8.5 既兼容javax.servlet标准,也支持 JDK 8 到 JDK 11,资源占用也不高。如果你的机器上已经装了别的版本,可以先在命令行确认一下环境:
java -version # 期望看到 1.8.0_xxx,如果看到 17 或 21,请先配置 JAVA_HOME 指到 JDK 8 $CATALINA_HOME/bin/version.sh # 或者直接在 Tomcat 解压目录下执行 ./bin/version.sh,会输出 Tomcat 版本和 JVM 版本参数说明:JAVA_HOME要指向 JDK 的根目录,不是bin目录;Tomcat 启动脚本靠它找到 Java。如果系统里同时装了几个 JDK,一定要在启动 Tomcat 的终端里先export JAVA_HOME=/path/to/jdk1.8,否则容易用了默认的新版本。
假设你还没装 JDK,搜索栏里输入“jdk 1.8 下载”能找到很多镜像。装完后在 terminal 里连续输入java -version和javac -version,两个都显示 1.8 才算配好。只装 JRE 是不行的,因为源码编译需要javac,虽然 IDE 会自带编译,但命令行部署时经常踩这个坑。
2.2 MySQL 5.7 与连接驱动:驱动 jar 放哪里、版本怎么选
这套源码的数据库连接方式几乎都是DriverManager.getConnection(url, user, password)或者通过一个工具类读取db.properties。不管哪种写法,都依赖 MySQL 的 JDBC 驱动包。常见驱动是mysql-connector-java-5.1.49.jar,这个版本能同时兼容 MySQL 5.7 和 8.0。驱动 jar 必须放到WEB-INF/lib目录下,不是随便放在工程根目录就行,否则 Tomcat 运行时找不到驱动类。
如果你的 MySQL 是 8.0 及以上,驱动类名和 URL 就得改一改。MySQL 8 的驱动类名是com.mysql.cj.jdbc.Driver,URL 里要加时区参数:
Class.forName("com.mysql.jdbc.Driver"); // 5.7 时代常用 // 或者 8.0 的写法: Class.forName("com.mysql.cj.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/diary?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8";参数说明:useSSL=false在本地开发时强烈建议加上,因为默认会尝试 SSL 握手,部分 MySQL 5.7 配置下会报SSL connection error: protocol wrong or unexpected;serverTimezone只在 8.0 驱动里强制要求,5.7 驱动写不写都行;characterEncoding=utf8是给项目数据存取提供一个基础保证。
如果你还没有装 MySQL,先按“mysql安装教程”这类资料装一个 5.7 或 8.0,注意安装时选择“Use Legacy Password Encryption”或者在配置客户端时用mysql_native_password,否则老驱动连接时会因认证插件问题直接拒绝连接。这点在很多人会用到的“mysql 5.7 安装过程详细”里常被忽略。
2.3 导入工程前先把数据库建好:跑 SQL 脚本的两种方式
这类源码包里通常带一个.sql文件,名字可能是diary.sql或db.sql。不要先急着导入 IDE,先把数据库建好,因为工程的web.xml里配置的welcome-file通常会去请求一个初始化 Servlet,那个 Servlet 在启动时要查表结构。
我习惯用命令行执行脚本,干净没有图形界面干扰:
-- diary.sql 前几行一般是这样的 CREATE DATABASE IF NOT EXISTS diary DEFAULT CHARACTER SET utf8mb4; USE diary; DROP TABLE IF EXISTS t_user; CREATE TABLE t_user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) UNIQUE, password VARCHAR(64), nickname VARCHAR(50) );在终端执行:
mysql -u root -p < diary.sql逻辑说明:<是让 MySQL 客户端把文件里的 SQL 全部读进来执行。注意-p后面不要跟密码,回车后会提示输入,避免密码暴露在 shell 历史里。
执行完可以用mysql -u root -p进去,敲show tables;看到t_user和t_diary之类表就算成功。如果用 Navicat 导库,有个注意点:默认字符集选utf8mb4,排序规则选utf8mb4_general_ci。选错了,之后中文插入会报Incorrect string value,这个坑很典型。
3. 把源码导进 IDE 并调整配置:从报错到能启动的完整流程
3.1 用 Eclipse/IDEA 导入项目:目录结构识别与 Web 工程设置
解压 zip 后,先看目录结构。正常的 JSP 项目会是这样:
diary/ ├── src/ │ └── com/diary/ │ ├── bean/ # 实体类,比如 User.java, Diary.java │ ├── dao/ # 数据访问,比如 UserDao.java │ ├── servlet/ # LoginServlet, RegisterServlet, DiaryServlet... │ └── util/ # DBUtil.java 连接数据库的工具类 ├── WebContent/ # 有的叫 webapp 或 WebRoot │ ├── META-INF/ │ ├── WEB-INF/ │ │ ├── lib/ # mysql-connector-java-xxx.jar │ │ └── web.xml │ ├── css/ │ ├── js/ │ ├── login.jsp │ ├── register.jsp │ └── diaryList.jsp └── diary.sql如果你用 Eclipse,直接File > Import > Existing Projects into Workspace,选择解压目录,Eclipse 会识别.project文件。如果用的是 IDEA,选Import Project,选择WebContent作为 Web 资源目录。
导入后有个常见问题:Eclipse 里项目上出现红叉,看Problems窗口,多半是 JDK 版本不对。右键项目Properties > Java Build Path > Libraries,把 JRE System Library 换成 1.8;Project Facets里把 Dynamic Web Module 版本改成 3.1 或 2.5 都行,关键是跟 Tomcat 8.5 兼容。
Tomcat 8.5 的默认 Servlet 版本是 3.1,但老项目可能用的是 2.5 的web.xml,也没问题。值得注意的是,某些 zip 解压后没有.project和.classpath文件,你需要在 IDEA 里右键选择Add as Maven Project(如果里面有pom.xml)或手动 Build。
3.2 修改 jdbc.properties 里的四个连接参数
大部分源码里数据库连接信息写在src/jdbc.properties或src/db.properties里。最常见的格式:
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/diary?useSSL=false&characterEncoding=utf8 jdbc.username=root jdbc.password=123456逻辑说明:DBUtil.java通常会在静态块里Properties.load()读取这个配置文件,再用Class.forName(driver)注册驱动。改完保存后,注意分类执行Build > Rebuild,让 properties 文件重新编译进 classes 目录,否则改了等于白改。
四个参数里最容易翻车的是password。如果安装 MySQL 时设置了空密码,就写空值但保留等号;如果密码里有&或#,必须用\转义,因为 properties 文件会把&当成分隔符。URL 里我习惯把useSSL=false放在最前面,有些源码里自带useUnicode=true,你直接加一段characterEncoding=utf8,不要重复写 key,重复加载时后面的会覆盖前面的。
3.3 部署到 Tomcat 后启动:看到哪个日志算成功
在 Eclipse 里配置 Tomcat 的步骤:Window > Preferences > Server > Runtime Environments,添加 Tomcat 8.5 的解压目录,然后在 Servers 视图里New > Server,选 Tomcat 8.5。右键项目Run As > Run on Server就能启动。IDEA 里则是Run > Edit Configurations > + > Tomcat Server > Local,在 Deployment 页签加上这个 Artifact。
启动后重点看 Tomcat 控制台的这些日志片段:
INFO: Deployment of web application archive ... has finished in xx ms INFO: Starting ProtocolHandler ["http-bio-8080"]如果看到这两行,说明项目部署成功、Tomcat 在 8080 端口监听了。如果只看到 Tomcat 自己启动、没有项目部署日志,说明项目的 Web 模块没挂上,去查Deployment配置里有没有把项目加进去。
然后访问http://localhost:8080/日记本项目名/。如果出现登录页,说明环境和路径都对。如果直接 404,先看web.xml里的 welcome-file 是什么,手动访问http://localhost:8080/项目名/login.jsp试试。
4. 常见坑与排查:这台机器上跑不起来,真不一定是源码的问题
4.1 404 与 500:URL 映射和 class 编译目录的脏数据
现象:页面访问login.jsp是好的,但点击“登录”按钮后跳转到 404,或者提交表单后 500。
原因:Servlet 的@WebServlet("/login")映射路径和表单里的action="login"对不上;更常见的是项目改过路径,Tomcat 缓存了旧的编译结果。
解决:先确认表单提交地址,再看web.xml里的<servlet-mapping>。如果是 IDEA,执行Build > Rebuild Project清掉target/classes下的旧 class 文件。如果 500 页面上提示ClassNotFoundException: com.mysql.jdbc.Driver,说明 jar 没进到部署产物里,Eclipse 里右键项目Properties > Deployment Assembly,把WEB-INF/lib加上。
4.2 mysql 连接报 SSL 错误或 Public Key Retrieval 的问题
现象:启动后第一次访问数据库相关页面,控制台报SSL connection error: protocol wrong or unexpected,或者Public Key Retrieval is not allowed。
原因:MySQL 8.0 默认用caching_sha2_password认证,老驱动 5.1.x 不支持;MySQL 5.7 的 SSL 证书配置和驱动默认行为不一致也会报 SSL 错误。
解决:驱动换成mysql-connector-java-8.0.28.jar,并且 URL 里显式加上useSSL=false&allowPublicKeyRetrieval=true。如果是 5.7,去 MySQL 执行ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';,刷新权限。
4.3 中文乱码,从请求参数到数据库表的全链路排查
现象:页面能打开,但注册时输入“小明”,登录后显示“???”或者乱码。
原因:至少四层都可能乱码——JSP 页面编码、请求编码、数据库连接编码、表字段编码。
解决:按顺序检查。JSP 头部要写<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>。Servlet 里接收参数前加request.setCharacterEncoding("utf-8");。数据库 URL 里已经加了characterEncoding=utf8,再确认表本身是utf8mb4。具体到 MySQL 命令行,执行ALTER TABLE t_user CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;能把已有表全转过来。还有一个隐藏点:Tomcat 8.5 之后默认 GET 请求的 URI 编码是 UTF-8,但老源码里可能手动new String(param.getBytes("iso-8859-1"), "utf-8"),有这段就把它删掉,否则双重转码反而变乱码。
4.4 端口被占用与 Tomcat 重复启动
现象:启动时日志报Port 8080 required by Tomcat v8.5 Server at localhost is already in use。
原因:上次 Tomcat 没正常关闭,进程还在;或者你装了多个服务占用 8080。
解决:命令行执行netstat -ano | findstr 8080(Windows)或lsof -i:8080(macOS/Linux),找到 PID 后taskkill /PID 进程号 /F。更稳妥的方式是在 Tomcat 的conf/server.xml里把 HTTP 端口改成 8081,但要注意随之改动访问 URL。里有时候是端口占用导致的假 404,关掉旧进程后重新启动就好。
这四条是这类“jsp+mysql源码”最常见的翻车点。如果你是新手,建议先跑通数据库再碰 Tomcat,不要同时开几个窗口反复重启,黑匣子里的报错信息一条一条看,比自己瞎猜快得多。
5. 看懂源码结构:日记本的核心功能在哪些文件里,怎么改
5.1 登录注册模块:session 与 cookie 的用法
日记本源码一定会有一个登录页面、一个注册页面,对应的 LoginServlet 和 RegisterServlet。登录成功后,这类项目最常见的做法是把用户名放入 session:
// LoginServlet.java 核心逻辑 User user = userDao.findByUsernameAndPassword(username, password); if (user != null) { HttpSession session = req.getSession(); session.setAttribute("loginUser", user); resp.sendRedirect("diaryList"); // 重定向到日记列表 } else { req.setAttribute("msg", "用户名或密码错误"); req.getRequestDispatcher("login.jsp").forward(req, resp); }逻辑说明:session.setAttribute把整个 User 对象存进会话,后续 JSP 里用${sessionScope.loginUser.nickname}就能显示昵称。注意这里用的是sendRedirect,表示客户端重新发起请求,地址栏会变成diaryList;如果用forward,地址栏还是login.jsp,但页面内容变成列表,刷新时会重复提交,这是一个容易忽略的体验问题。
如果你想做“记住我”,就再加一个 Cookie,Cookie c = new Cookie("username", username); c.setMaxAge(7*24*3600); resp.addCookie(c);,在登录页初始化时回填。老源码里这块常常写得比较粗暴,你改成这样就是一个小加分点。
5.2 日记的增删改查:JSP 里写 Java 还是走 Servlet
很多课程设计源码为了省事,直接在diaryList.jsp里用<% ... %>拼接 HTML。这种写法看起来直观,但问题很大:页面里混杂了 Java 代码、HTML 和 SQL,你动一个引号,整页编译都过不去。正确但费事的做法是让 Servlet 负责查询,把数据放进request.setAttribute("list", list),然后 JSP 里用 JSTL 的c:forEach输出。
<!-- diaryList.jsp 摘录 --> <table> <tr><th>标题</th><th>日期</th><th>操作</th></tr> <c:forEach var="d" items="${diaryList}"> <tr> <td>${d.title}</td> <td>${d.createTime}</td> <td> <a href="diaryEdit?id=${d.id}">编辑</a> <a href="diaryDelete?id=${d.id}" onclick="return confirm('确认删除?')">删除</a> </td> </tr> </c:forEach> </table>逻辑说明:${diaryList}是 Servlet 里request.setAttribute("diaryList", diaryDao.findAll());拿到的 List。diaryEdit和diaryDelete是两个 Servlet 映射。看到这里你应该明白:源码里的这些 Servlet 大部分只做三件事——接收参数、调用 DAO、跳转页面。
如果你要改源码,先别在 JSP 里大改,优先改 DAO 层的 SQL。比如原始查询是SELECT * FROM t_diary WHERE user_id = ?,你改成按日期区间过滤:
public List<Diary> findByUserAndDate(int userId, String startDay, String endDay) { String sql = "SELECT * FROM t_diary WHERE user_id = ? AND create_time BETWEEN ? AND ?"; // 用 PreparedStatement 设置三个参数 }5.3 加密与校验:MD5 加盐和 SQL 注入的教训
这种老源码的注册模块大概率是直接明文存密码,登录时SELECT * FROM t_user WHERE username = ? AND password = ?。我接手过不下五个类似项目,十个里有八个是不处理 SQL 注入的,昵称输入框里敲一个' OR '1'='1,登录就穿帮了。
一个成本很低的改进是全部换成PreparedStatement。不要再拼字符串了:
// 错误的做法(源码常见) Statement st = conn.createStatement(); ResultSet rs = st.executeQuery("SELECT * FROM user WHERE username='" + username + "'"); // 正确的做法 PreparedStatement ps = conn.prepareStatement("SELECT * FROM user WHERE username=? AND password=?"); ps.setString(1, username); ps.setString(2, password);密码加密方面,毕业设计答辩时老师很喜欢问“密码怎么保管”。你可以把注册时的密码存成 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); } } // 注册时 String salt = "diary2024"; String safePwd = md5(salt + password); // 登录时比对 md5(salt + password) 与库里的值参数说明:盐值写死在代码里不是最安全的,但比明文强得多,也足够应付课程设计。加了 MD5 之后,原数据库里已有的明文密码会全部失效,要么清掉重新注册,要么写一个批量更新脚本统一转一次。
6. 把课程设计改成能答辩的作业:三个加分项与验证清单
6.1 给日记加上分页和按日期检索
列表页日记多了之后一次塞给页面,不但卡,答辩老师也会觉得你欠考虑。常见做法是 GET 请求携带page参数,DAO 里用LIMIT ?, ?。注意 JSP 的mysql LIMIT分页要计算起始行offset = (page-1) * pageSize。检索可以做成一个表单:<input type="date" name="date">,提交后拼进 SQL 的WHERE条件。
6.2 用 Filter 做登录拦截
如果不加拦截,别人直接访问diaryList.jsp也能看到所有日记,这等于没有登录功能。在web.xml里注册一个LoginFilter,拦截/*,放行login.jsp、register.jsp和对应的 Servlet,核心逻辑是session.getAttribute("loginUser") == null就跳回登录页。把这段讲清楚,页面“个人信息展示页面”的直达访问也会被顺手挡掉,答辩经常靠这个拿分。
6.3 验证清单与收尾
动工之前列一下要交的清单:源码压缩包放哪、SQL 脚本版本、数据库字符集、Tomcat 启动步骤能口头复述。最后,我会把 Tomcat 的logs/catalina.out里启动日志截一张图存好,作为项目能跑通的证据。这篇写的就是我做这类“jsp+mysql个人日记本源码”的通常流程,很多次翻车都翻在环境版本上,后来我把 JDK、Tomcat、MySQL 的版本固定成一套祖传配置,就再没出过幺蛾子。希望帮到你。
本文还有配套的精品资源,点击获取