一、功能模块设计与实现思路
本项目基于 Swing 和 JDBC 实现了一个简易 QQ 聊天系统,核心模块包括:
- 用户认证模块:登录(
LoginFrame
)与注册(RegistrationForm
)界面 - 聊天交互模块:主聊天窗口(
ChatWindow
)与好友列表管理 - 数据持久层:MySQL 数据库连接与用户 / 聊天记录存储
- 网络通信层:Socket 长连接实现消息收发
二、关键技术问题与解决方案
1. 数据库连接与安全设计
问题:初始版本直接使用明文存储密码,存在安全隐患
解决方案:
- 采用
JPasswordField
替代普通文本框,避免密码在内存中以明文形式存在 - 注册时添加密码加密逻辑(可扩展为
BCrypt
或SHA-256
哈希) - 使用
try-with-resources
自动释放数据库资源,避免连接泄漏
java
// 注册时密码处理优化示例(原代码基础上扩展)
String hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
pstmt.setString(2, hashedPassword);
数据库操作优化点:
- 注册时自动创建用户专属聊天表,通过 DDL 语句动态生成
- 使用
PreparedStatement
预编译 SQL 防止注入攻击 - 好友列表加载时通过
SELECT username FROM student WHERE username!= ?
过滤当前用户
2. 界面布局与用户体验优化
问题:LoginFrame
使用null
布局,在不同分辨率下适配性差
解决方案:
- 混合使用
GridBagLayout
(如注册界面)和JSplitPane
(聊天窗口) - 为组件设置相对尺寸和
setPreferredSize
,减少硬编码坐标 - 添加密码显示 / 隐藏功能(通过
setEchoChar
动态切换)
java
// 密码显示控制逻辑
showPasswordCheckBox.addItemListener(e -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
passwordField.setEchoChar((char) 0);
} else {
passwordField.setEchoChar('*');
}
});
交互优化:
- 注册时实时验证密码一致性,避免提交后才提示错误
- 聊天窗口添加好友在线状态标识(绿色圆点),通过
FriendListCellRenderer
自定义绘制 - 消息发送按钮添加鼠标悬停效果(颜色变化),提升交互反馈
3. 网络通信与线程管理
问题:Socket 连接未处理断线重连,可能导致消息丢失
解决方案:
- 使用独立线程处理服务器消息接收,避免阻塞 UI 线程
- 采用
CopyOnWriteArrayList
存储聊天记录,保证线程安全 - 添加
finalize
方法确保资源释放,但更推荐显式调用disconnect
方法
java
// 线程安全的聊天记录存储
private List<String> chatHistory = new CopyOnWriteArrayList<>();
通信协议设计:
- 私聊消息格式:
/pm 接收者 消息内容
- 在线状态通知:
在线用户状态:用户1:在线,用户2:离线
- 通过
processMessage
方法解析不同类型的消息并分发处理
三、代码优化与可维护性改进
1. 架构层面优化
- 模块化拆分:将数据库操作封装为
DBUtil
工具类,网络通信封装为ChatClient
类 - 接口抽象:定义
MessageService
接口分离业务逻辑与实现 - 资源管理:使用连接池(如 HikariCP)替代原生 JDBC 连接,提升数据库性能
2. 性能与安全增强
优化点 | 原代码问题 | 改进方案 |
---|---|---|
密码存储安全 | 明文存储 | 增加BCrypt 哈希加密 |
数据库连接性能 | 每次操作新建连接 | 集成 HikariCP 连接池 |
界面响应速度 | 消息处理阻塞 UI 线程 | 使用SwingWorker 处理耗时操作 |
SQL 注入风险 | 未预编译动态 SQL | 统一使用PreparedStatement |
3. 代码可读性改进
- 添加方法级 Javadoc 注释,说明参数、返回值和异常
- 抽取重复代码为工具方法,如
validateInput
输入验证 - 常量统一管理,如将颜色定义为
static final
成员变量
java
// 优化后的常量定义
private static final Color PRIMARY_COLOR = new Color(52, 152, 219);
private static final String DB_URL = "jdbc:mysql://localhost:3306/students?";
四、开发过程中的典型挑战与应对
-
界面布局适配问题
- 挑战:
null
布局在不同屏幕缩放比例下显示错乱 - 解决:混合使用
GridBagLayout
和BorderLayout
,配合setResizeable(true)
允许窗口缩放
- 挑战:
-
多线程数据同步
- 挑战:Socket 接收线程与 UI 线程同时操作聊天记录
- 解决:使用
SwingUtilities.invokeLater
确保 UI 更新在 EDT 线程执行
-
数据库表结构设计
- 挑战:动态为每个用户创建聊天表导致表数量激增
- 改进方向:合并为单表,通过
sender
和receiver
字段区分会话,添加复合索引提升查询效率
五、后续可扩展功能
- 群聊功能:扩展消息协议支持群组标识
- 文件传输:基于 Socket 实现二进制文件传输模块
- 消息加密:添加 AES 或 RSA 加密保证通信安全
- 离线消息:服务器存储离线消息,上线时批量推送
- UI 美化:集成 Nimbus 外观或第三方 UI 库(如 JFoenix)提升视觉效果