基于 Java Swing + MySQL C/S 即时通讯聊天系统完整开发记录
项目贡献说明:个人负责模块
本项目为三人小组协作完成,本人独立负责以下核心模块的完整开发与交付:
| 负责模块 | 具体内容 |
|---|---|
| 分层架构设计 | 独立完成整体三层架构(Model-DAO-通信层)的搭建与模块边界划分 |
| Model 实体层 | 独立设计并实现全部 5 个核心实体类及统一序列化协议 |
| DAO 数据访问层 | 独立编写所有数据库操作类,覆盖用户、好友、群组、消息全流程 SQL |
| Util 工具类 | 独立封装头像处理、文件传输、时间格式化三类通用工具 |
| 通信协议定义 | 独立设计 ChatMessage 作为统一网络传输载体,定义全部业务指令常量 |
组内分工:Swing 客户端界面设计与交互逻辑由其他两位成员负责,本人专注于后端数据层、通信层与工具层的开发,双方通过明确定义的接口进行联调对接。数据库表结构设计、网络传输协议定义均由本人独立完成。
一、整体项目分层架构设计
项目采用经典三层架构,各层职责清晰分离:
model 实体模型层:纯数据载体,实现
Serializable支持 TCP 对象传输;dao 数据访问层:封装所有 MySQL 增删改查,统一连接管理与资源释放;
util 通用工具层:提取头像、文件、时间等公共逻辑,消除重复代码;
通信层:以
ChatMessage对象作为客户端与服务端唯一交互协议。
二、Model 实体层
所有实体对应数据库表结构,兼顾网络序列化与 Swing 界面渲染需求。
User 用户实体
头像字段使用
ImageIcon直接适配界面;多构造器重载,适配注册、登录、好友列表不同场景;
头像为空时自动生成默认头像,避免界面空白。
Group 群组实体
对应
groups群组表,存储群 ID、群名、群主、简介、成员数量、创建时间;重写
equals()、hashCode(),仅通过群唯一 ID 判断对象相等,集合去重;toString直接返回群名称,Swing 下拉框、列表控件可直接渲染。
Message 消息实体
统一封装私聊、群聊消息数据:消息 ID、发送人、接收人、群 ID、内容、消息类型、撤回标记、撤回时间。
groupId为null代表私聊,存在数值代表群聊,一套实体兼容两种聊天场景;重载构造方法,快速创建普通文本私聊、群聊消息。
FriendRequest 好友申请实体
对应
friend_requests申请表,记录申请人、接收人、申请留言、状态(待处理 / 同意 / 拒绝); 新建申请时默认状态pending,自动填充当前系统时间戳。
ChatMessage 通信数据包
户端与服务端交互的统一传输对象,是整个网络通信核心:
内置静态常量区分全部业务指令:登录、登出、私聊、群聊、文件传输、消息撤回、心跳包、用户状态同步;
统一字段承载发送人、接收人、群 ID、文本内容、文件二进制、文件名、文件大小;
扩展
Map<String,Object> extra存储零散自定义参数,无需频繁修改实体类即可扩展新功能;实现序列化,TCP 流直接传输对象,无需手动拼接 JSON / 字符串,简化网络解析逻辑
三、DAO 数据访问层
所有数据库操作统一放在 dao 包,不掺杂界面、业务逻辑,单独封装资源关闭逻辑,杜绝连接泄漏。开发迭代顺序为先搭建基础 DAO 骨架,再逐步完善各业务 DAO 与时间戳工具配套逻辑。
DBConnection
全局唯一 JDBC 连接管理类:
静态代码块加载配置文件,自动读取驱动、数据库地址、账号密码;
封装静态方法
getConnection()获取连接,提供closeAll()统一关闭Connection、Statement、ResultSet;类加载时一次性加载驱动,项目全局复用连接配置。
UserDAO
操作
users用户表,覆盖账号全流程功能: 注册新增用户、用户名密码登录校验、按 ID / 用户名查询用户、修改用户名 / 密码、更新在线状态、查询全部在线用户、校验用户名是否重复; 内置私有工具extractUser,自动将查询结果集ResultSet转为User实体,自动读取头像二进制数据。
FriendshipDAO
操作
friendships好友关系表、friend_requests申请表:获取用户全部好友列表,支持好友置顶排序;
双向好友校验、添加双向好友记录、删除双向好友;
置顶 / 取消置顶好友,双向同步置顶标识与置顶时间;
发送好友申请,新增待处理申请记录。
GroupDAO
操作
groups群组表、group_members群成员关联表: 创建群组并获取自增群 ID、添加群成员、查询当前用户所有加入群组、查询群组完整详情、获取群内全部成员、校验用户是否在群内; SQL 采用多表联查,一次性查询群主名称、统计群成员数量,减少多次数据库 IO。
MessageDAO
区分私聊表
messages、群聊表group_messages分开管理:保存文字、图片、文件私聊 / 群聊消息;
查询两人历史私聊记录、群组历史消息;
消息撤回功能:仅发送人可操作,修改
is_deleted标记并记录撤回时间;提供查询两人最新一条消息接口,用于好友列表展示聊天预览。
四、Util 工具类
将三处以上重复使用的逻辑统一封装。
ImageUtil
专门处理用户头像转换与默认头像生成:
重载
createDefaultAvatar(),支持 40px 默认尺寸、自定义尺寸生成圆形头像;根据用户名哈希值生成专属随机背景色,头像中间展示用户名首字母;
提供双向转换:
bytesToImageIcon()二进制转界面头像、imageIconToBytes()头像转字节数组; 适配数据库存储二进制头像、Swing 界面渲染双向需求。
FileUtil
处理文件本地存储、读取、系统打开操作:
文件大小限制 100MB,超大文件直接抛出异常拦截;
本地文件读取为字节数组,用于 TCP 网络传输;
接收文件自动用 UUID 重命名,存入本地下载目录,避免同名文件覆盖;
工具方法:判断是否为图片、截取文件后缀、格式化字节为 KB/MB/GB;
兼容 Windows/Mac/Linux 系统,调用系统程序直接打开本地文件。
DateUtil
针对聊天界面两套友好时间格式,优化用户视觉体验:
formatTime()聊天窗口完整时间:刚刚、X 分钟前、当天时分、昨天、星期、完整年月日;formatListTime()侧边好友 / 群列表简略时间:仅显示时分、昨天、星期、月日,界面更简洁。
五、开发亮点
分层清晰:严格分离 Model-DAO-工具,可维护性强;
单一通信协议:
ChatMessage承载所有交互,解析逻辑极简;工具类复用:三个工具类覆盖头像、文件、时间核心场景,业务层零重复;
合理数据库设计:双向好友关联、群成员分表、置顶与撤回支持;
体验细节:默认头像、相对时间、文件大小格式化,提升客户端观感;
资源安全管理:连接与流统一释放,无内存泄漏。
六、待优化方向
| 问题 | 后续方案 |
|---|---|
| 密码明文存储 | 引入 MD5+盐加密 |
| 大文件一次性读入内存 | 改为分片上传 |
| 无数据库连接池 | 引入 HikariCP |
| 离线用户收不到历史消息 | 新增离线消息表,上线后推送 |