ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

JavaWeb个人博客管理系统源码:从架构拆解到部署运行全攻略

JavaWeb个人博客管理系统源码:从架构拆解到部署运行全攻略 简介基于JavaWeb的个人博客管理系统源码面向正在学习Servlet、JSP与MVC开发的初学者及需要完成课程设计的在校生以完整项目演示博客平台从用户认证、文章管理到评论交互的落地实现。压缩包共7154个文件、约54.01MB除Java源码、class字节码和JSP页面外还包含3716张PNG图片、1200余个JS脚本、745个HTML页面及CSS/SCSS样式并配有SQL数据库脚本与配置文件覆盖前端展示、后端逻辑与部署所需的主要构件。已有2357人学习下载项目目录结构清晰包含用户登录注册、文章增删改查、分类管理、评论回复等典型模块可直接导入IDE运行也适合对照源码梳理JavaWeb经典分层架构。对于想快速上手传统ServletJSP开发模式的开发者是一份兼具参考与实战价值的课程设计资料。1. JavaWeb个人博客管理系统源码到底解决谁的诉求又到了交课程设计和毕业设计的季节很多人搜来搜去最后落在这一个标题上Javaweb个人博客管理系统源码。这东西说白了就是一个典型的 JavaWeb 全栈小项目——前台给别人看文章、按分类找内容、发评论后台给自己发文章、管分类、审评论数据老老实实存在 MySQL 里。标题里带着“源码”意味着你要的不是一篇《从零搭建博客》的教程而是一个能直接导入 IDEA、能跑起来、能改造成自己作品的完整工程。它最擅长解决两类诉求一是课程设计或毕业设计需要一个能演示、能答辩、能讲清楚原理的项目二是刚学完 Servlet、JSP、JDBC想用一个完整案例把这条技术链路串起来。但它的边界也明确不追求高并发、不做前后端分离UI 通常比较朴素核心价值在于把 JavaWeb 的经典链路完整走一遍。拿到源码之后你要做的事就三件看懂它、跑通它、把它改得不那么像模板。2. 技术选型与数据模型为什么这套博客源码长这样2.1 JSPServlet还是Spring Boot看清源码骨架再决定要不要这类标题下的源码包十有八九是 Servlet JSP MySQL 的结构骨架看着老但足够把 JavaWeb 课设要讲的技术点讲全。拿到手先判型看工程根目录有没有 pom.xml有说明是 Maven 工程依赖可以自动拉没有则多半是普通 Web 工程jar 包全躺在 WEB-INF/lib 里。再找入口有 WEB-INF/web.xml 并配置了一堆 servlet-mapping或者类上直接标了 WebServlet就是传统 Servlet 风格如果看到带 main 方法的启动类那是 Spring Boot 工程依赖管理、打包方式、运行环境完全是另一套逻辑。这两种骨架的区别直接决定你后续的改造工作量。为什么课设和毕设这么爱做 Servlet JSP核心原因是你答辩时要回答“一次 HTTP 请求是怎么从浏览器走到数据库再回页面的”这个问题。Servlet 生命周期、Request/Response、Session、Filter、JDBC 的 Connection 和 PreparedStatement都是 Spring Boot 帮你封装好的黑匣子碰上爱追问细节的老师容易被问倒。所以拿到源码先别嫌弃它老先对照自己交的报告看这套骨架能不能把技术点讲完整。如果你对照黑马那套 JavaWeb 笔记做复习会发现这套源码里几乎所有包都能在笔记里找到对应概念这反而是好事。至于要不要换成 Spring Boot如果你的题目明确是“基于 Spring Boot 的博客系统”那找源码时直接找标题带 Spring Boot 的版本如果题目就是“JavaWeb 个人博客”Servlet JSP 更顺理成章。最怕的是源码里混用了 Spring 全家桶又只用了部分接口那种结构最难改建议换一套干净的纯 Servlet 工程。2.2 表结构设计一个博客系统最少需要几张表个人博客的数据模型非常典型一对多加自关联。我一般建议核心表控制在五张左右用户表、文章表、分类表、评论表、友链表。非要加标签系统就再多一张文章标签关联表。表设计得越多后期改起来越容易在 JOIN 里绕晕课设阶段没必要。用户表至少要有 user_id、username、password、role、create_timepassword 必须是加密后的密文明文存密码是硬伤。文章表至少要有 title、content、category_id、author_id、view_count、status、create_time、update_timestatus 用 TINYINT 存草稿/发布/删除比直接 delete 记录安全。分类表就是 category_id 加 category_name 两个字段。评论表是重点comment_id、article_id、user_id、content、parent_id、create_timeparent_id 自关联本表的 comment_id回复别人的评论就挂在父评论底下一张表就能表达无限层级。友链表字段最简单link_id 加 link_name 加 link_url做前台底部互链。近几年来参考的建库脚本常见写法是CREATE TABLE blog_article ( article_id INT NOT NULL AUTO_INCREMENT COMMENT 文章ID, title VARCHAR(200) NOT NULL COMMENT 标题, content LONGTEXT NOT NULL COMMENT 正文, category_id INT DEFAULT NULL COMMENT 所属分类, author_id INT DEFAULT NULL COMMENT 作者ID, view_count INT DEFAULT 0 COMMENT 浏览数, status TINYINT DEFAULT 1 COMMENT 1发布 0草稿, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (article_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;两个关键参数在这里值得专门说。ENGINE 选 InnoDB课设阶段确实用不到复杂事务但 MyISAM 在并发写和异常断电时容易出表损坏没必要为省一点性能埋雷。CHARSET 选 utf8mb4 而不是 utf8是因为 utf8 存不了 emoji博客编辑器一旦支持表情评论里出现一个 emoji 就会抛 Incorrect string value这个错很隐蔽排查起来特别玄学。字段注释 COMMENT 也值得保留写课设文档时对着注释导出表结构说明能省一大块时间。建表还有一个取舍外键。我的习惯是在数据库层面只保留逻辑外键靠程序保证 article_id 和 parent_id 必须存在不加物理 FOREIGN KEY。原因很现实二次开发时一旦外键约束卡住删除文章会引发一串连环报错课设阶段用程序控制引用关系比数据库硬约束灵活得多。这个取舍在小项目里完全够用答辩也不会被挑毛病。2.3 MVC分层与请求流转一篇文章发布出去要过几道门拿到源码后我会先看一条最短链路用户在前台填了一篇新文章点发布到页面重新刷出这篇文章中间要过哪些文件。合格的源码必然这样走JSP 页面把表单 post 给 ArticleServletServlet 只做参数接收和视图跳转业务规则放在 ArticleServiceArticleDao 负责拼 SQL 执行 JDBC成功之后重定向到列表页列表页用 JSTL 的 c:forEach 循环渲染。每个包的位置也有规律JSP 放在 webapp 目录里面看不到 JDBC 代码Servlet 在 controller 包只做“取参数、调服务、定跳转”三件事Service 放业务规则比如草稿审核、评论层级校验Dao 只写 SQL 和结果集封装。判断源码质量最粗暴的标准就是打开每个 JSP 搜 import java.sql只要 JSP 里有 SQL 和 JDBC说明分层是摆设后期改起来会很痛苦。Servlet 层的编码细节也必须提。常见写法是 doPost 第一行先写 request.setCharacterEncoding(UTF-8)再 getParameter。有些老源码只写了 doGet 逻辑表单却用 methodpost 提交所有参数全是 null这类翻车事件在后面的排查章节会细讲。另外 WebServlet(/article/add) 必须和表单 action 里的路径一致一个叫 /addArticle 一个叫 /add对不上就直接 404。这些小细节比框架本身更容易让人翻车。3. 在IDEA里把源码跑通数据库导入、jdbc配置与Tomcat启动3.1 导入IDEA与初始化数据库先确认库里有没有脚本拿到源码的第一件事不是双击打开工程而是先打开压缩包里的 README 或 sql 目录确认有没有建库脚本。一套能正常交付的源码必须带一个 blog.sql 或 init.sql里面包含建库、建表、初始数据三件套没有的话大概率是残缺包连导入都省了直接换一套。这是看源码多年的血泪经验没有初始数据的项目跑起来后你连一条能展示的文章都找不到整个演示现场都会变得很尴尬。用 Navicat 或者命令行执行初始化常见做法是直接在 MySQL 命令行分两步走CREATE DATABASE IF NOT EXISTS blog DEFAULT CHARACTER SET utf8mb4; USE blog; SOURCE /项目路径/sql/blog.sql逻辑说明先建库再导表。DEFAULT CHARACTER SET utf8mb4 这一句很关键它决定整个库的默认字符集避免导表时因会话字符集不一致而乱码或中断。SOURCE 路径里的斜杠在 Windows 上也要写成 /不要写反斜杠这是命令行导入最常见的小坑。执行完刷新数据库确认表都进去了顺便看一眼初始数据里有没有 admin 账号——后面登录后台要用它而且注意 password 字段应该是密文而不是明文。IDEA 里导入工程File → New → Project from Existing Sources选中源码根目录。如果根目录有 pom.xml选择 import as Maven project等右侧 Maven 面板里的依赖刷新完如果是普通 Web 工程直接作为 IDEA 工程打开。打开后第一件事是检查 Project StructureProject 里的 SDK 选 Java 1.8Modules 里确认 src 被标记为 sources如果工程里有 web 目录确认它被识别成 Web 模块且 web.xml 路径正确。这几项配置直接决定后面 Tomcat 能否一键启动是 IDEA 运行 JavaWeb 项目配置里最容易出问题的地方。3.2 修改数据库连接参数三个必改项把库建好之后就要改连接配置。源码里的连接信息一般放在 src 根目录的 jdbc.properties 或 db.properties也有的放在 WEB-INF/classes 下。不管放在哪里核心都是一份 properties 文件把参数替换成本地环境即可jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/blog?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue jdbc.usernameroot jdbc.password你的本机密码配置项常见错误正确做法与原因jdbc.drivercom.mysql.jdbc.DriverMySQL 8 的驱动类名是 com.mysql.cj.jdbc.Driver老写法在 8.0 驱动下直接 ClassNotFoundExceptionjdbc.url缺 serverTimezone 或缺 allowPublicKeyRetrievalMySQL 8 必须带时区和公钥获取参数否则报时区错误或 Public Key Retrieval 错误jdbc.password带引号或首尾多空格properties 文件里密码是明文直写任何额外字符都会被当成密码本身这三个必改项背后各有讲究。jdbc.driver 是驱动类全限定名MySQL 8 的驱动启用了新类名旧类名只是为了兼容而保留报错日志对新手极不友好。jdbc.url 里的 serverTimezoneAsia/Shanghai 解决 MySQL 8 的时区判断allowPublicKeyRetrievaltrue 配合 useSSLfalse 解决 MySQL 8 默认认证插件导致的连接被拒如果是 MySQL 5.7allowPublicKeyRetrieval 可以删掉但 characterEncodingutf8 一定不要删它负责告诉驱动按 UTF-8 传字符串少了它中文就乱。jdbc.username 和 jdbc.password 不要带引号properties 文件没有引号语法。另外提醒一句如果源码把连接信息硬编码在 DBUtil.java 里而不是 properties 文件那就要改 Java 文件优点是少一层文件读取缺点是复用性差属于架构不合但课设能用的状态。改完之后顺手在 IDEA 里建一个快速测试类用 DriverManager.getConnection(url, user, pass) 试连一次能连上再启动 Tomcat。这一步能把“数据库问题”和“Web 服务问题”两个变量剥离开排查效率立刻翻倍。3.3 配置Tomcat并启动验证控制台日志会告诉你答案配置 TomcatRun → Edit Configurations → 左上角加号 → Tomcat Server → Local。Server 选项卡里把 Application server 指向本机 Tomcat 安装目录Deployment 选项卡点加号把当前 Module 的 war exploded 包挂上去Application context 设为 /blog。这样访问地址就是 http://localhost:8080/blog/index.jsp。启动前做两个预检动作第一确认 8080 端口没被占Windows 上可以用 netstat -ano | findstr 8080 看一眼第二盯住控制台启动日志查有没有异常堆栈尤其看有没有 java.net.BindException 和 ClassNotFoundException。日志最后出现 INFO: Deployment ... has finished才算真正部署成功。这个日志窗口是黑匣子唯一的窥视口出问题先看它别急着翻页面。启动完成后在浏览器访问首页正常的话前台文章列表就出来了如果 404先访问 http://localhost:8080 确认 Tomcat 本身活着再用命令行验证curl -I http://localhost:8080/blog/index.jsp返回 200 说明上下文路径正确返回 404 说明 Application context 和实际访问路径对不上。常见做法是回到 Deployment 页面把 URL 里的路径和设置的 context 对齐。IDEA 不会因为 artifact 改名就自动同步 context path我在这上面栽过好几次属于典型的 IDE 黑匣子行为。4. 核心模块源码拆解登录鉴权、文章分页、评论树4.1 登录与Session鉴权Filter把未登录请求挡在门外个人博客管理后台必须有登录拦截核心组件是 Session 加 Filter。常见流程是登录表单提交到 LoginServlet校验通过后把 user 对象存进 Session再写一个 Filter 拦截 /admin/ 前缀的请求Session 里有用户就放行没有就重定向到登录页。WebFilter(/admin/*) public class LoginFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; HttpServletResponse response (HttpServletResponse) resp; Object user request.getSession().getAttribute(loginUser); if (user ! null) { chain.doFilter(req, resp); } else { response.sendRedirect(request.getContextPath() /login.jsp); } } }逻辑说明Filter 是 JavaWeb 标准拦截组件不需要额外引入依赖。核心代码三行——getSession().getAttribute(loginUser) 负责取登录态chain.doFilter 放行表示已登录sendRedirect 把未登录用户送回登录页。参数上最需要注意的是 WebFilter 的 url 模式必须写 /admin/* 而不是 /admin因为 /admin 只能匹配这一个精确路径拦不住 /admin/list.jsp 这种子页面。判断一套源码登录是否严密额外看两点。第一Session 的 key 是否全局统一LoginServlet 放进去的 key 和 Filter 里取出来的 key 必须是同一个中途改过一次名字后台所有请求会瞬间全部重定向到登录页而且只在运行期出现极难定位。第二后台 JSP 页面有没有做二次判断做得稳的项目会在每个后台 JSP 顶部再判一次 ${sessionScope.loginUser} 是否为空防止有人绕过 Filter 直接访问 JSP 路径。双保险虽然代码丑一点但确实堵得住漏洞。还要提醒密码问题。很多课程设计源码把密码明文存数据库登录查询直接 select * from user where username? and password?。这种写法能跑但安全底线几乎为零组内同学用 SQL 注入就能直接登进后台。拿到源码后至少做一层 MD5盐或者 BCrypt 改造把密码换成密文存储。改动不复杂答辩提分效果却非常明显。4.2 文章分页查询Dao层SQL与Servlet分页参数博客前台列表永远不会一页塞下全部文章分页查询是必须写好的核心方法。常见做法是 MySQL 的 LIMIT 加 OFFSET配合 PreparedStatement 绑定参数public ListArticle queryPage(int pageNum, int pageSize) { String sql SELECT * FROM blog_article WHERE status1 ORDER BY create_time DESC LIMIT ? OFFSET ?; try (PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, pageSize); ps.setInt(2, (pageNum - 1) * pageSize); ResultSet rs ps.executeQuery(); // 遍历 ResultSet把每行字段封装成 Article 对象加入 List省略 } catch (SQLException e) { e.printStackTrace(); } return list; }两个参数位直接决定分页结果。LIMIT 后面的第一个 ? 是 pageSize表示一页多少条OFFSET 后面的 ? 是偏移量计算公式是 (pageNum - 1) * pageSize。pageSize 取 10 时第一页是 LIMIT 10 OFFSET 0第二页是 LIMIT 10 OFFSET 10语义清晰。注意 pageNum 如果从 JSP 表单传来前端传第 0 页会导致 OFFSET 为负MySQL 直接报错所以 Servlet 层要做 Math.max(1, pageNum) 的下限保护这个细节加到代码注释里也不为过。页面上还涉及总页数计算。想拿总数就得先执行 SELECT COUNT(*) FROM blog_article WHERE status1然后 totalPage (total pageSize - 1) / pageSize。这个公式是求上取整避免了最后一条记录因为整除边界被吞掉。有些源码写成 total / pageSize结果是最后一页原有的一两条记录凭空消失答辩时一翻页就露馅。分页参数在 JSP 里的来回传值也经常被忽略。点击“下一页”时 URL 必须带着 pageNum 和 pageSize 继续传给 Servlet如果 Servlet 只从 request.getParameter 读 pageNum 而不读 pageSize每页条数会在翻页后重置成默认值。参数闭环做齐之后分页逻辑才算真正自洽。4.3 评论回复自关联表的递归加载与XSS过滤评论回复是个人博客里最容易写出精致感也最容易埋雷的模块。表结构上 parent_id 自关联本表每一条评论都可以被无限回复。展示的时候常见做法是把全量评论查出来后在内存里递归组装成树public void buildCommentTree(ListComment all, ListComment result, long parentId, int depth) { for (Comment c : all) { if (c.getParentId() parentId) { c.setLevel(depth); result.add(c); buildCommentTree(all, result, c.getCommentId(), depth 1); } } }逻辑说明all 是按文章一次性查出的全部评论result 是组装后的有序列表parentId 从 0 开始表示顶级评论每找到一个子评论就把它加入 result同时用当前评论的 commentId 作为新的 parentId 继续递归。depth 是一个展示参数页面拿到 level 后乘以固定像素做缩进视觉上形成层级。这个方案在评论量不大的博客里完全够用但有两个硬伤一是数据里不能出现循环引用比如两条评论互相把对方设为 parent递归会当场栈溢出二是全量查询在评论量极大时内存和响应时间都不理想课设阶段一般碰不到这个量级不用提前优化。XSS 是评论模块躲不开的问题。用户评论的 content 回到页面时如果原样输出任何访客都能在当前页面执行脚本。最轻量的防御是在 Service 层做转义把 转成 再入库或者输出时用 JSP 的 c:out 配合 escapeXml 属性。再进一步是写一个 HtmlFilter 工具类在评论入库前过滤 script、iframe 等标签。这套改造前后不复杂属于一行就能演示的安全加固写进课设报告反而让老师觉得你确实关注过生产环境的问题。5. 常见问题排查JavaWeb博客源码跑不起来的五个坑5.1 端口8080被占用Tomcat起不来的第一个元凶现象IDEA 控制台启动 Tomcat 时立刻抛 java.net.BindException: Port 8080 already in use浏览器访问 localhost:8080 却打开了完全不相关的页面。原因8080 是 Tomcat 默认端口本机有其他服务占了它。常见占用者包括之前调试没关干净的另一个 Tomcat 实例、Oracle 自带服务以及一些软件内置的 Web 服务。有时只是上一次调试的进程没完全退出IDEA 的 Run 面板里还挂着旧实例。解决优先改端口而不是杀进程这样不干扰其他程序。打开 Tomcat 安装目录 conf/server.xml找到 Connector 节点把 port8080 改成 8081同时回到 IDEA 的 Run Configuration把 HTTP port 也改成 8081。两处必须同时改只改一处会出现 Tomcat 实际端口和 IDEA 展示端口错位日志显示成功但浏览器照样 404。改完访问地址也跟着换成 8081这个细节最容易忘。5.2 MySQL 8连接报Public Key Retrieval错误现象项目启动正常但一登录或一查文章就抛 SQLNonTransientConnectionException报错信息里有 Public Key Retrieval is not allowed for user。原因MySQL 8 默认认证插件是 caching_sha2_password驱动第一次连接时要从服务端拉取 RSA 公钥来加密密码传输如果 JDBC URL 里没有显式允许这个动作连接就被中断。这本质是客户端与服务端安全握手失败不是账号密码错误。解决回到 jdbc.properties 或 DBUtil.java 里的连接串在末尾补上 allowPublicKeyRetrievaltrueuseSSLfalse然后重启问题就消失。注意补了之后如果还报 Access denied for user那才是用户名密码或权限问题不要和公钥问题混为一谈。MySQL 5.7 用户不需要这个参数但网上很多教程直接把它贴在 5.7 配置里也不影响因为 mysql_native_password 认证用不到 RSA 公钥拉取。5.3 页面中文全部乱码三层编码统一才是治本现象文章标题、分类名、评论全部变成问号或“锟斤拷”这类乱码Tomcat 控制台日志里的中文也花掉。原因字符集在三个环节里至少断了一个。第一个环节是数据库连接串缺少 characterEncodingutf8 时驱动会按服务器默认字符集传参第二个环节是 JSP 页面本身的 pageEncoding 和 contentType 不是 UTF-8第三个环节是 Servlet 接收 POST 参数前没调 request.setCharacterEncoding。任何一环断了最终落在页面上就是乱码。解决把三个环节一次校齐。数据库连接串加 useUnicodetruecharacterEncodingutf8每个 JSP 头部 pageEncoding 改成 UTF-8contentType 的 charset 也写 UTF-8然后在 Filter 里统一加 request.setCharacterEncoding(UTF-8) 和 response.setCharacterEncoding(UTF-8)。放 Filter 而不是每个 Servlet能覆盖全部请求最省事。改完重启先刷新库里旧的乱码数据再测试新增数据确保新数据不乱码才算解决。5.4 404不是路径的锅context path与部署结构双查现象Tomcat 启动正常日志没有异常堆栈但访问后台地址一律 404前台首页偶尔也 404。原因最常见是 context path 问题。IDEA 里 Artifact 的 Application context 设成 /blog但页面跳转写的是 /admin/list.jsp少了 /blog 前缀请求落到 Tomcat 根上下文自然找不到资源。第二种常见原因是部署结构不对JSP 文件在 Artifact 的 Output Layout 里没被包含进去或者 WEB-INF 下的 web.xml 没被正确加载。解决先看 404 报错的完整 URL把 context path 和实际路径对一眼跳转代码统一用 request.getContextPath() 拼前缀写死的路径一律不留。再进 Project Structure → Artifacts查 Output Layout 里有没有把 webapp/WebContent 目录挂进去web.xml 是否在 WEB-INF 下。这两个动作做完绝大多数 404 能当场定位。少数情况是 IDEA 缓存没刷新点 Build → Rebuild Project 再重启 Tomcat 就好。5.5 JSP页面取不到值JSTL缺失和驼峰映射都要看现象数据库里明明有文章Servlet 也执行到了页面上的列表却是空的或者 ${article.title} 输出空白。原因一是 JSTL 标签库的 jar 包缺失。页面用了 c:forEachweb.xml 也声明了 taglib但 WEB-INF/lib 下没有 jstl.jar 和 standard.jarJSTL 标签全部失效。二是数据封装时字段名对不上。MySQL 表字段习惯用下划线分隔article_nameJavaBean 属性习惯用驼峰articleName如果 DAO 里的 ResultSet 映射没有写别名或自动映射属性取不到值页面自然空白。解决先补 JSTL 依赖把 jstl.jar 和 standard.jar 放进 WEB-INF/libMaven 工程则在 pom.xml 加 jstl 依赖。再看 DAO 的映射代码每次 rs.getXxx 后 new 对象时setter 的参数名要和 Java 属性一致。页面空白但没异常时优先查这两处比在 JSP 里逐行加调试输出要快得多。6. 源码拿到手之后先做三步验证再决定怎么二次开发6.1 先核对功能清单别被“完整系统”的说明迷惑拿到任何一套源码第一关是核对而不是信任。把“个人博客管理系统”拆成功能清单前台能看文章列表、文章详情、分类筛选、发表评论后台能登录、发文章、改文章、删文章、管理分类和评论数据库带可复用的初始化脚本。对着清单逐项点一遍缺哪块就在课设文档里补哪块。半小时的核对能避免一个尴尬场景你精心改了一下午答辩时才发现这套源码本来就没有删除评论的功能。6.2 快速审查数据访问层和用户表安全和质量一眼看穿接手源码后我会做一次不编译的静态审查。重点看三处DAO 层拼 SQL 是不是全程 PreparedStatement如果看到字符串直接拼参数就该重写用户表的 password 字段是不是明文是明文就加盐哈希再入库表里有没有 create_time 和 update_time没有的话后期想做“近 30 天发文趋势”会很痛苦。这三条改起来不算重活却能明显提升整套源码的可靠度。6.3 三个可落地的二次开发方向想让它更像自己的作品我推荐三个改动方向。一是给文章加标签建一张标签表和一张文章标签关联表前台做一个标签云难度低、展示效果好是答辩里拿得出手的增量功能。二是把正文编辑区从 textarea 升级成轻量级富文本编辑器注意保存时做 HTML 标签白名单过滤别把安全又丢了。三是加一个“热门文章”列表SQL 就是按 view_count 倒序取 10 条改动极小首页视觉丰富度立刻提升。三个里选一个做深就好别贪多。我的习惯是拿到源码先完整跑通再手动重建一遍建库脚本确认每一步都能独立复现之后才敢动手改。靠运气跑起来的项目大概率在演示前两天出幺蛾子。希望这篇笔记能让你少踩几个坑把时间留给真正想做的改动。本文还有配套的精品资源点击获取
返回列表