当前位置: 首页 > news >正文

基于Java+MySQL+Servlet的留言系统开发全解析

本系统基于Java Web技术栈开发,采用前后端分离架构,后端通过Servlet实现业务逻辑,前端使用HTML/CSS/JavaScript构建交互界面。本文将详细解析系统设计思路、技术实现与核心代码,助您快速掌握留言系统开发精髓。


一、项目简介

本留言系统主要实现用户注册登录、留言发布/编辑/删除、留言列表展示等核心功能,技术架构包含:

  • 后端:Servlet 3.1 + MySQL 5.0 + Tomcat 8

  • 前端:HTML5 + CSS3 + AJAX

  • 构建工具:Maven 3.6

  • 数据交互:JSON格式通信

系统演示地址:登录页


二、核心功能与页面展示

2.1 功能模块

模块功能描述技术实现
用户管理登录/退出Servlet会话管理 + MySQL用户表存储
留言发布Markdown格式输入与实时预览SimpleMDE编辑器集成 + Servlet文件上传处理
留言管理列表展示/编辑/删除AJAX异步加载 + DOM动态渲染
权限控制用户操作鉴权Filter拦截器 + Session状态验证

2.2 页面效果

  1. 登录页

    • 表单验证与错误提示

    • 记住密码功能(Cookie存储)

  2. 留言列表页

    • 分页加载(每页10条)

    • 实时排序(按时间/热度)

  3. 留言编辑页

    • Markdown与富文本双模式切换


三、关键技术解析

3.1 前后端交互模式

技术对比 110
交互方式优势适用场景
表单提交开发简单,兼容性好传统页面跳转场景
AJAX局部刷新,用户体验佳实时交互场景
WebSocket双向实时通信在线聊天等高实时性场景

四、数据库设计与实现

4.1 表结构设计

-- 一般对于建表的 sql 都会单独搞个 .sql 文件来保存.
-- 后续程序可能需要在不同的主机上部署. 部署的时候就需要在对应的主机上把数据库也给创建好.
-- 把建表 sql 保存好, 方便在不同的机器上进行建库建表.
drop database java107_blog_system;create database java107_blog_system charset utf8mb4;use java107_blog_system;drop table if exists blog;
create table blog (blogId int primary key auto_increment,title varchar(128),content varchar(4096),userId int,postTime datetime
);drop table if exists user;
create table user (userId int primary key auto_increment,username varchar(50) unique,password varchar(50)
);insert into user values(null, 'wangying', '030807'), (null, 'chenbo', '216039');insert into blog values(null, '我的第一条留言', '这是第一条留言的正文', 1, '2025-05-18 16:12:52');
insert into blog values(null, '我的第二条留言', '这是第二条留言的正文', 1, '2023-05-17 12:52:25');

4.2 数据库连接池

封装DBUtil类实现连接复用:

/** 通过这个类, 封装数据库的连接操作.*/
public class DBUtil {// 这个类中要提供 DataSource. DataSource 对于一个项目来说, 有一个就行了. (单例)private static volatile DataSource dataSource = null;private static DataSource getDataSource() {if (dataSource == null) {synchronized (DBUtil.class) {if (dataSource == null) {dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java107_blog_system?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("");}}}return dataSource;}public static Connection getConnection() throws SQLException {return getDataSource().getConnection();}public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) {if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (statement != null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}

五、核心功能实现

5.1 Servlet消息处理

/** 通过这个类, 来实现一些后端提供的接口*/
@WebServlet("/blog")
public class BlogServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 从 query string 中查询一下看是否有 blogId. 如果有就认为是查询指定博客; 如果没有就是查询所有博客.BlogDao blogDao = new BlogDao();String blogId = req.getParameter("blogId");if (blogId == null) {List<Blog> blogs = blogDao.selectAll();String respString = objectMapper.writeValueAsString(blogs);resp.setContentType("application/json;charset=utf8");resp.getWriter().write(respString);} else {Blog blog = blogDao.selectOne(Integer.parseInt(blogId));String respString = objectMapper.writeValueAsString(blog);resp.setContentType("application/json;charset=utf8");resp.getWriter().write(respString);}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf8");// 1. 先从请求中拿到 标题 和 正文.String title = req.getParameter("title");String content = req.getParameter("content");if (title == null || title.equals("") || content == null || content.equals("")) {String html = "<h3>title 或者 content 为空! 新增博客失败!</h3>";resp.setContentType("text/html; charset=utf8");resp.getWriter().write(html);return;}// 2. 从会话中拿到作者的 idHttpSession session = req.getSession(false);if (session == null) {String html = "<h3>当前用户未登录! 新增博客失败!</h3>";resp.setContentType("text/html; charset=utf8");resp.getWriter().write(html);return;}User user = (User) session.getAttribute("user");if (user == null) {String html = "<h3>当前用户未登录! 新增博客失败!</h3>";resp.setContentType("text/html; charset=utf8");resp.getWriter().write(html);return;}// 3. 构造 Blog 对象.Blog blog = new Blog();blog.setUserId(user.getUserId());blog.setTitle(title);blog.setContent(content);blog.setPostTime(new Timestamp(System.currentTimeMillis()));// 4. 插入 blog 对象到数据库中BlogDao blogDao = new BlogDao();blogDao.insert(blog);// 5. 跳转到博客列表页resp.sendRedirect("blog_list.html");}
}

5.2 前端AJAX交互

// 加载留言列表
function loadMessages(page = 1) {fetch(`/message?page=${page}`).then(res => res.json()).then(data => renderMessages(data)).catch(err => showError('加载失败'));
}// 提交留言
document.getElementById('msg-form').addEventListener('submit', e => {e.preventDefault();const content = editor.value();fetch('/message', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({content})}).then(() => {editor.value('');loadMessages();});
});

六、项目部署与优化

6.1 Maven依赖配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>BlogSystem</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version></dependency><!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.0</version></dependency></dependencies><packaging>war</packaging><build><finalName>java107_blog_system</finalName></build>
</project>

6.2 性能优化策略

  1. 缓存机制:使用Redis缓存热点留言数据

  2. 异步处理:耗时操作(如邮件通知)放入线程池

  3. SQL优化:为create_time字段添加索引

  4. 前端优化:实现虚拟滚动加载长列表


七、项目总结与扩展

本系统完整实现了基础留言功能,具备以下扩展方向:

  1. 社交功能扩展:添加点赞/评论/分享功能

  2. 内容安全:集成文本敏感词过滤

  3. 多媒体支持:支持图片/视频附件上传

  4. 微服务改造:拆分为用户服务/消息服务等独立模块

开发过程中需特别注意:

  • 使用PreparedStatement防止SQL注入

  • XSS过滤保障内容安全

  • 定期备份数据库(可通过crontab实现)9

完整源码已托管至Github:phaseless (phaselessX) - Gitee.com
欢迎访问在线演示系统体验功能,期待您的Star与贡献!

上述博客介绍不够完整,完整源代码在gitee中!!!

http://www.xdnf.cn/news/517231.html

相关文章:

  • 电子电路:怎么理解电子在导体中的热运动?
  • C++数组详解:一维和多维数组的定义、初始化、访问与遍历
  • 算法优化——以“LCR 080. 组合”为例
  • React Native打包报错: Task :react-native-picker:verifyReleaseResources FAILE
  • IIS入门指南:原理、部署与实战
  • 电动车仪表上的数字怎么来的,想知道吗?
  • leetcode3546. 等和矩阵分割 I- medium
  • uniapp中的easycom工作机制
  • Flask快速入门和问答项目源码
  • ​在 ASP.NET 中,HTTP 处理程序(HttpHandler)是处理 HTTP 请求的核心组件​
  • 【Bluedroid】蓝牙HID DEVICE 报告发送与电源管理源码解析
  • Python 中 if 和 else 基础知识的详解和使用
  • 中级统计师-统计学基础知识-第四章 假设检验
  • 【老马】离线版金融敏感信息加解密组件开源项目 encryption-local
  • python打卡day29
  • spark数据处理练习题详解【下】
  • 【simulink】IEEE33节点系统潮流分析模型
  • 2025年全国青少年信息素养大赛C++小学全年级初赛试题
  • MyBatis框架(入门)
  • 【java多线程】线程间通信-利用wait和notify轮流按序打印奇数和偶数
  • 一文读懂-嵌入式Ubuntu平台
  • 基于Bootstrap 的网页html css 登录页制作成品
  • C++学习:六个月从基础到就业——C++17:if/switch初始化语句
  • MATLAB中的Switch语句讲解
  • LabVIEW双音信号互调失真测量
  • CSS 浮动(Float)及其应用
  • AUTOSAR图解==>AUTOSAR_SRS_TTCAN
  • CPU、核心、进程、线程、协程的定义及关系
  • 基于DeepSeek API构建带记忆的对话系统:技术实现详解
  • 网络的知识的一些概念