尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Java Web个人博客系统源码部署与课程设计答辩改造指南

Java Web个人博客系统源码部署与课程设计答辩改造指南 简介一套基于Java Web的个人博客网站源码专为软件工程期末大作业设计也适合Java Web初学者巩固Servlet、JSP与MySQL整合开发。项目实现了博客发布、文章管理、评论互动等典型功能前端采用HTML、CSS、JavaScript后端使用Servlet与JSP数据存储依赖MySQL整体技术栈清晰便于课程设计或毕设参考。压缩包共866个文件大小14.53MB包含21个Java源文件、14个JSP页面、392个JS脚本、116个CSS样式、3个SQL数据库脚本以及一份PDF介绍文档目录结构完整从源码到数据库脚本一应俱全。此外还附有编译后的class文件与war包可直接导入IDE运行或部署至Tomcat方便对照学习项目分层与JDBC封装思路。已有63人学习下载适合需要对个人博客系统进行完整复现与二次开发的在校学生。1. 一个 Java Web 个人博客项目能拿来做什么如果你现在手上有一个带数据库脚本和 PDF 说明的 Java Web 个人博客源码包大概率是软件工程课程设计或期末大作业的产物。这类项目的典型构成是 JSP Servlet MySQL外加一份写好的设计文档功能上覆盖用户注册登录、文章发布、分类浏览、评论留言这些博客系统的基本盘。它的价值不在代码量而在“完整”从前端页面到后台数据库一条链路是通的这恰好是软件工程课设评分时最看重的东西。这篇博客就按我自己拿到这类源码包后的处理顺序来讲先搭环境把项目跑起来再读数据库脚本理清表结构然后顺着一次文章发布的请求把 MVC 链路过一遍最后做几个能在答辩时加分的改造。全程不依赖这套源码内部的具体命名你手头那个包无论是 SSM 还是纯 Servlet 版本思路都通用。适合正在做软件工程或数据库课程设计的人也适合想快速上手 Java Web 老项目的人。2. 把 Java Web 博客源码跑起来先过环境关2.1 JDK、Tomcat、MySQL 版本怎么配最稳拿到源码包先别急着打开 IDE先把版本对齐。Java Web 老项目最常见的翻车点就是版本不兼容JDK 太新导致编译报错Tomcat 版本和 Servlet API 对不上MySQL 8 的驱动和旧连接串不匹配。建议按下表先确认环境组件推荐版本说明JDK1.8 或 11大多数课设源码基于 JDK 8 编写用 17 有时会遇到sun.misc相关报错Tomcat8.5 或 9.0对应 Servlet 3.1 / 4.0兼容 JSP 2.3MySQL5.7 或 8.0注意驱动名5.7 用com.mysql.jdbc.Driver8.0 用com.mysql.cj.jdbc.DriverIDEA2021 以上任意版本社区版即可不用破解企业版我一般会先建一个空的test.jsp放到 Tomcat 的 webapps 下确认 Tomcat 本身能出页面再导入项目。这样能区分“环境坏了”和“项目坏了”两类问题不然报错时容易两头查。2.2 导入 IDEA 后的目录结构判断打开源码包后先看它是不是 Maven 工程。如果根目录有pom.xml直接用 IDEA 的 Open 选中该文件导入如果只有WebContent或web目录加一堆.java源码就是传统 Web 工程需要手动配置。传统工程导入后的标准动作# 项目导入 IDEA 后打开 File - Project Structure # 1. Project SDK 选 1.8 # 2. Modules - 点 号选 Web设置 Web Resource Directory 指向 WebContent/web # 3. Artifacts - 点 号选 Web Application: Exploded # 4. 把 Tomcat 的 servlet-api.jar 加到 Module 的 Dependencies配置完成后在 IDEA 里新建 Tomcat 运行配置Deployment 选项卡把 Artifact 加进去Application Context 最好改成/blog或和项目名一致。很多人卡在这一步页面能打开但所有链接 404多半是 Application Context 配的和源码里写的访问路径不一致。提示如果源码里有web.xml优先看它里面的servlet-mapping配置这决定了 URL 长什么样也决定了 Artifact 该怎么配。2.3 Tomcat 中 JSP 编译后的 Java 类去哪看JSP 第一次被访问时才编译成 Servlet这是很多课设答辩时被问到的问题。JSP 编译后的_jsp.java和_jsp.class存放在 Tomcat 的work/Catalina/localhost/应用名/org/apache/jsp/目录下。想确认自己的 JSP 有没有编译成功或想排查 JSP 里的语法错误最直接的办法是浏览器访问一次页面后去这个目录看产物# 假设 Tomcat 安装在 /opt/tomcat9 cd /opt/tomcat9/work/Catalina/localhost/blog/org/apache/jsp/ ls -la # 能看到 index_jsp.java 和 index_jsp.class 就说明编译通过如果页面上报 500 错误但日志不清楚直接打开index_jsp.java看第几行抛异常比看 Tomcat 日志更快。还有一个更省事的方法在 JSP 页面顶部临时加一句% page isErrorPagetrue %配合exception.printStackTrace(response.getWriter())把异常打到页面上看清楚后再删掉。3. 数据库脚本与博客表结构先读懂再改3.1 导入 .sql 文件的完整流程源码包里通常带一个.sql文件可能是建库脚本也可能是全量备份。先打开文件看头部注释确认是CREATE DATABASE还是CREATE TABLE再决定导入方式。推荐用命令行导入不依赖客户端工具# 登录 MySQL mysql -u root -p # 创建数据库字符集用 utf8mb4 避免文章内容里的 emoji 变成问号 CREATE DATABASE IF NOT EXISTS blog_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 退出后用重定向导入 mysql -u root -p blog_db /path/to/blog.sql导入后验证表是否齐全USE blog_db; SHOW TABLES; -- 正常能看到 user、article、comment、category 这类表如果你习惯用图形化工具Navicat 里右键数据库选“运行 SQL 文件”DBeaver 里用Execute Script。但不管用哪种导入后建议看一遍表数量和报错信息很多SQL 文件导入失败的案例都是因为字符集不一致比如文件里写的是latin1数据库建的是utf8mb4导入中文时数据丢失。3.2 核心表字段设计与关联关系个人博客系统的表结构是数据库课程设计的高频考点。最基础的六张表如下表名关键字段作用userid, username, password, nickname, avatar用户信息articleid, user_id, title, content, category_id, create_time, view_count文章主体categoryid, name, description文章分类tagid, name标签article_tagarticle_id, tag_id文章与标签多对多关联表commentid, article_id, user_id, content, create_time评论一个容易在答辩中被追问的设计点article表里只存category_id分类详情通过关联查询获取而不是把分类名冗余在文章表里。原因是分类名一改所有引用它的文章都要跟着更新违背第三范式。但浏览量view_count是故意冗余在文章表里的因为每次访问都要统计单独建表会让一次普通的文章详情查询变成两次插入性能上不划算。-- 典型的文章详情查询语句多表联查一次拿到全部分类信息 SELECT a.id, a.title, a.content, a.create_time, a.view_count, c.name AS category_name, u.username AS author FROM article a JOIN category c ON a.category_id c.id JOIN user u ON a.user_id u.id WHERE a.id 1;3.3 数据库连接配置的参数调整JDBC 连接串里的参数是最容易被忽略但也是最好提分的点。常见的连接池配置有两种DBCP 的dbcp.properties或 C3P0 的c3p0-config.xml源码包里一般放在src目录下。核心参数就三个jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/blog_db?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai jdbc.usernameroot jdbc.password123456serverTimezoneAsia/Shanghai是针对 MySQL 8.0 的必配参数不加会报时间区域错误。useSSLfalse是针对本地开发的生产环境建议开 SSL。characterEncodingutf8要和数据库字符集一致否则中文乱码。如果是 MySQL 5.7驱动换成com.mysql.jdbc.Driver即可。4. MVC 分层与登录、文章发布的请求链路4.1 一次请求从前端到数据库的完整路径个人博客系统的代码结构通常按 MVC 分层这也是软件工程设计文档里必须画的那张图。一个典型请求的流转顺序是JSP 页面发起表单提交或 AJAX 请求web.xml中配置的servlet-mapping把请求路由到对应 ServletServlet 调用 Service 层处理业务逻辑比如校验登录状态、组装数据Service 调用 DAO 层也叫 Mapper执行 SQLDAO 返回结果Service 处理后交回 ServletServlet 把数据塞进request或session转发给 JSP 渲染展示以“用户发布文章”为例前端表单的 action 通常指向文章的保存路径原始 Servlet 的 doPost 方法核心逻辑如下4.2 文章发布的服务端核心代码// ArticleSaveServlet.java - doPost 方法简化版 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(UTF-8); // 1. 从 session 中判断是否登录 User user (User) request.getSession().getAttribute(loginUser); if (user null) { response.sendRedirect(login.jsp); return; } // 2. 收集表单参数 String title request.getParameter(title); String content request.getParameter(content); String categoryId request.getParameter(categoryId); // 3. 参数校验 - 不通过就回写错误提示不再走后续流程 if (title null || title.length() 0) { request.setAttribute(error, 文章标题不能为空); request.getRequestDispatcher(articleEdit.jsp).forward(request, response); return; } // 4. 组装对象并调 Service Article article new Article(); article.setTitle(title); article.setContent(content); article.setUserId(user.getId()); article.setCategoryId(Integer.parseInt(categoryId)); ArticleService service new ArticleService(); int articleId service.addArticle(article); // 5. 跳转到新文章详情页 response.sendRedirect(articleDetail?id articleId); }这段代码里有两个值得在答辩中主动讲的点。第一登录校验放在业务处理之前杜绝未登录用户直接 POST 请求绕过页面写入数据这是一种最基本的权限控制。第二setCharacterEncoding(UTF-8)必须在读取任何参数之前调用放在后面会失效很多中文乱码问题就是这一行的位置不对。4.3 DAO 层 SQL 写法与分页参数DAO 层的增删改查是数据库课程设计评分时的重点。文章列表页通常要做分页核心在于拼接 LIMIT 子句时防止 SQL 注入。public ListArticle findPage(int pageNum, int pageSize) { String sql SELECT id, title, create_time, view_count, (SELECT username FROM user WHERE id article.user_id) AS author FROM article ORDER BY create_time DESC LIMIT ?, ?; // 使用 PreparedStatement 的占位符而不是拼接字符串 PreparedStatement ps conn.prepareStatement(sql); ps.setInt(1, (pageNum - 1) * pageSize); ps.setInt(2, pageSize); ResultSet rs ps.executeQuery(); // 遍历结果集组装 ListArticle }LIMIT ?, ?的两个参数第一个是偏移量第二个是每页条数。计算偏移量的公式是(当前页码 - 1) * 每页条数这是分页查询的核心。注意第一页的偏移量是 0所以pageNum - 1必须写在setInt里由 JDBC 传参千万不能直接在 SQL 字符串里拼${pageNum}否则就是教科书级的 SQL 注入漏洞。提示查看源码里是否所有 SQL 都用PreparedStatement如果发现Statement加字符串拼接的写法在答辩前改掉这一条比多加一个功能更能体现工程素质。5. 答辩前最值得做的四个改造5.1 加一个站内搜索功能绝大多数个人博客源码包只有一个按分类浏览的列表页搜索引擎优化和站内搜索是两个提分项。最简单的搜索功能是在文章列表页加一个关键词输入框DAO 层多写一个方法public ListArticle searchByKeyword(String keyword) { String sql SELECT id, title, create_time FROM article WHERE title LIKE ? OR content LIKE ? ORDER BY create_time DESC; PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, % keyword %); ps.setString(2, % keyword %); // 执行查询并返回结果 }注意LIKE关键字这里用的是?预编译传参%符号拼在参数值里而不是拼进 SQL 字符串这样既不会注入也能正常模糊匹配。前端可以放在导航栏右上角搜索页复用文章列表的展示逻辑改造量不大但是功能闭环完整。5.2 把数据库密码改成配置文件管理课设项目的数据库密码通常直接硬编码在 DAO 工具类里老师一眼就能看到。抽到配置文件里是软件工程设计文档里“配置管理”这一节的内容。做法是新建一个db.properties把 3.3 节那些连接参数全放进去然后在工具类中用资源加载方式读取。public class DBUtil { private static String url; private static String username; private static String password; static { try { Properties props new Properties(); // 从 classpath 读配置文件 InputStream in DBUtil.class.getClassLoader() .getResourceAsStream(db.properties); props.load(in); Class.forName(props.getProperty(jdbc.driver)); url props.getProperty(jdbc.url); username props.getProperty(jdbc.username); password props.getProperty(jdbc.password); } catch (Exception e) { throw new ExceptionInInitializerError(e); } } }用getResourceAsStream而不是new FileInputStream(db.properties)的原因在于Web 应用部署后文件路径不在工作目录下通配路径法容易报 FileNotFoundclasspath 方式则无论开发环境还是部署环境都能正确加载。这个改动每次连接数据库都会触发静态块加载性能上与原来无异。5.3 给文章内容补一个 HTML 转义工具个人博客系统最常见的漏洞是 XSS。用户在评论框输入scriptalert(xss)/script如果服务端直接存库再原样输出所有访问者的浏览器都会执行这段脚本。在 Servlet 里加一个静态转义方法public static String escapeHtml(String input) { if (input null) return ; StringBuffer sb new StringBuffer(); for (int i 0; i input.length(); i) { char c input.charAt(i); switch (c) { case : sb.append(lt;); break; case : sb.append(gt;); break; case : sb.append(quot;); break; case \: sb.append(#39;); break; case : sb.append(amp;); break; default: sb.append(c); } } return sb.toString(); }评论和文章标题输出前都调一遍这个方法输入的 HTML 就只会以纯文本形式显示脚本不再执行。课设评分时你把“转义防止 XSS”写进文档里比写出一个复杂炫酷的前端页面更对软件工程课程设计的胃口。5.4 把项目打包成 WAR 交付文档要求提交源码老师不一定有本地环境。这时候把项目打成一个 WAR 包放到 Tomcat 的webapps目录下自动解压运行是最省事的交付方式。IDEA 里操作路径# 菜单 Build - Build Artifacts - 选择 war 包类型 # 构建完成后在 target 或 out 目录下找到 .war 文件 # 将 war 包拷贝到 Tomcat 的 webapps 目录 cp blog.war /opt/tomcat9/webapps/ # 启动 Tomcat 后会自动解压WAR 包名字就是访问路径例如blog.war对应的地址是http://localhost:8080/blog/。注意放在 webapps 下的 WAR 包解压后旧目录可能会残留重复部署时要先删掉旧文件夹。这一步也顺便验证了你的项目在“非 IDEA 环境”下能否独立运行很多源码在 IDE 里跑得通、换到 Tomcat 手动部署就报缺包早晚要处理。6. 部署后如何确认 JSP 编译与数据库连接都正常项目跑起来后别急着点功能先做三个验证十分钟内能确认系统健康度。第一步是看 JSP 编译产物访问首页后检查 Tomcat 的 work 目录下是否生成了对应的_jsp.java。第二步是看日志文件logs/localhost.yyyy-MM-dd.log里如果出现数据库连接失败或类加载异常基本就是配置问题。第三步是直接开浏览器开发者工具看网络面板里关键请求的状态码是否 200。这里提供一个更高效的检查手段写一个临时 JSP用一行代码验证数据库连通性完了就删。% page importjava.sql.* % % Connection conn null; try { Class.forName(com.mysql.cj.jdbc.Driver); conn DriverManager.getConnection( jdbc:mysql://localhost:3306/blog_db?useSSLfalseserverTimezoneAsia/Shanghai, root, 你的密码); out.println(DB connection OK); } catch (Exception e) { out.println(DB connection FAILED: e.getMessage()); } finally { if (conn ! null) conn.close(); } %访问这个页面看到DB connection OK说明驱动、连接串、账号密码、端口四个环节全部正常。如果失败按e.getMessage()的内容分情况处理Access denied就是密码错了Communications link failure是 MySQL 没启动或端口不对Unknown database是库名写错ClassNotFoundException是驱动 jar 没放进WEB-INF/lib。这类排错步骤在交付时写进 PDF 的“系统部署”章节评委照着操作就能跑通也算文档质量的加分项。最后说一个邮件沟通之外的偏方把你在 2.3 节查到的_jsp.java文件内容和 3.1 节导入成功的建表语句截图放进文档附录等价于替老师完成了一半验收工作。源码包的价值在于跑通不在于体积大小。这个项目能完整跑通再谈改造比多写三千行无用代码更能让你过关。本文还有配套的精品资源点击获取
返回列表