1. *面向对象设计
在前端开发中,我采用了面向对象的设计理念。通过定义多个类和接口,实现了代码的模块化和复用。我主要设计了用户类(User)、聊天界面类(TalkView)、消息类(Message)等,它们之间通过继承、实现接口等方式进行交互,共同构成了整个前端系统的核心框架。
2. *聊天界面、用户界面的建立:
我使用了HTML、CSS和JavaScript等技术来构建聊天界面和用户界面。聊天界面主要包括聊天窗口、输入框、表情选择等组件;用户界面则包含了登录、注册、好友列表等页面。在实现过程中,我遇到了界面布局、交互效果等难点,通过学习和参考多个开源项目和教程,我成功解决了这些问题。
3. *消息发送与接收功能
我通过WebSocket技术实现了消息的实时发送与接收。用户可以在聊天窗口中输入文字,点击发送按钮后,消息将被发送到后端服务器,并由服务器转发给目标用户。同时,用户也可以实时接收到来自其他用户的消息,并在聊天窗口中显示出来。在实现过程中,我遇到了WebSocket连接建立、消息格式定义等难点,通过查阅文档和调试代码,我成功解决了这些问题。
4. 与后端服务器的数据交互
我通过MySQL的相关技术实现了与后端服务器的数据交互。当用户进行登录、注册、添加好友等操作时,前端会将请求发送到后端服务器,服务器处理请求后返回结果给前端。前端再根据返回的结果更新界面或执行相应的操作。
-
数据库读写部分
创建数据访问对象 (DAO) 来封装数据库读写操作,提供一个抽象层来与数据库交互。提高代码的可维护性和可测试性。
单例模式:
- 实例变量:private static volatile PropertiesUtil propertiesUtil = null;
- 确保只有一个实例PropertiesUtil。
- volatile关键字确保propertiesUtil所有线程都可以看到更改。
- 构造函数:private PropertiesUtil()
- 私有构造函数可防止其他类的实例化。
- 初始化properties对象并从文件加载属性。
- getInstance方法:public static PropertiesUtil getInstance()
- 返回 的单个实例PropertiesUtil。
- 使用双重检查锁定来确保线程安全的延迟初始化。
属性加载:
- 属性对象:private Properties properties;
- 存储属性文件中的键值对。
- loadProperties方法:private void loadProperties()
- 从 加载属性com/mouse/config.properties。
- 使用 try-with-resources 来确保InputStream正确关闭。
- 如果找不到文件或无法加载,则会引发运行时异常。
getValue 方法:public String getValue(String key)
- 从属性中检索与给定键关联的值。
JDBCUtil
该类提供使用 JDBC 获取数据库连接的实用方法。它从PropertiesUtil
类中检索数据库连接详细信息。
详细说明:
- 数据库连接详细信息:
- URL、用户、密码:
private static final String URL, USER, PASSWORD;
- 使用检索数据库连接详细信息
PropertiesUtil
。
- 使用检索数据库连接详细信息
- 静态块:
static { ... }
- 此块确保在加载类时初始化这些值。
- getConnection 方法:
public static Connection getConnection()
- 用于
DriverManager.getConnection
使用提供的 URL、用户和密码建立与数据库的连接。 SQLException
如果连接尝试失败则抛出。
综合功能
- 初始化:
PropertiesUtil
初始化一次并用于加载配置属性。JDBCUtil
从 检索数据库连接详细信息PropertiesUtil
。
- 用法:
- 当
JDBCUtil.getConnection()
被调用时,它使用属性文件中的 URL、用户和密码建立与数据库的连接。
概括
- PropertiesUtil:处理从文件加载和访问配置属性,使用 Singleton 模式来确保线程安全访问。
- JDBCUtil:提供一种使用所加载的属性来获取数据库连接的方法
PropertiesUtil
。
package com.aizhi.dao;
import com.aizhi.po.User;
import com.aizhi.util.JDBCUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class UserDao {
public User login(String username,String pwd){
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
User user = null;
try{
//获取数据库连接
connection = JDBCUtil.getJDBCUtil().getConnection();
//准备数据库语句
StringBuffer stringBuffer = new StringBuffer(" select id,user_name,pwd,real_name from user where user_name=? and pwd=? ");
preparedStatement = connection.prepareStatement(stringBuffer.toString());
preparedStatement.setString(1,username);
preparedStatement.setString(2,pwd);
//执行sql
resultSet = preparedStatement.executeQuery();
//遍历信息
if (resultSet.next()){
user = new User();
user.setId(resultSet.getInt("id"));
user.setUsername(resultSet.getString("user_name"));
user.setPwd(resultSet.getString("pwd"));
user.setRealname(resultSet.getString("real_name"));
}
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.getJDBCUtil().closeConnection(resultSet,preparedStatement,connection);
}
return user;
}
/**
* user信息存入数据库的方法
* @param user
* @return
*/
public void insertUser(User user){
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try{
//获取数据库连接
connection = JDBCUtil.getJDBCUtil().getConnection();
//准备数据库语句
StringBuffer stringBuffer = new StringBuffer(" insert into user(user_name,pwd,real_name) value(?,?,?)");
preparedStatement = connection.prepareStatement(stringBuffer.toString());
preparedStatement.setString(1,user.getUsername());
preparedStatement.setString(2,user.getPwd());
preparedStatement.setString(3,user.getRealname());
//执行sql
preparedStatement.executeUpdate();
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.getJDBCUtil().closeConnection(resultSet,preparedStatement,connection);
}
}
/**
* 根据username获取user信息,看是否已经存在
* @param username
* @return
*/
public User getByUsername(String username){
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
User user = null;
try{
//获取数据库连接
connection = JDBCUtil.getJDBCUtil().getConnection();
//准备数据库语句
StringBuffer stringBuffer = new StringBuffer(" select id,user_name,pwd,real_name from user where user_name=? ");
preparedStatement = connection.prepareStatement(stringBuffer.toString());
preparedStatement.setString(1,username);
//执行sql
resultSet = preparedStatement.executeQuery();
//遍历信息
if (resultSet.next()){
user = new User();
user.setId(resultSet.getInt("id"));
user.setUsername(resultSet.getString("user_name"));
user.setPwd(resultSet.getString("pwd"));
user.setRealname(resultSet.getString("real_name"));
}
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.getJDBCUtil().closeConnection(resultSet,preparedStatement,connection);
}
return user;
}
/**
* 获取数据库里面的用户信息
* @return
*/
public List<User> getUsers(){
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
List<User> users = null;
try{
//获取数据库连接
connection = JDBCUtil.getJDBCUtil().getConnection();
//准备数据库语句
StringBuffer stringBuffer = new StringBuffer(" select id,user_name,pwd,real_name from user ");
preparedStatement = connection.prepareStatement(stringBuffer.toString());
//执行sql
resultSet = preparedStatement.executeQuery();
//容器生成
users = new ArrayList<>();
//遍历信息
while(resultSet.next()){
User user = new User();
user.setId(resultSet.getInt("id"));
user.setUsername(resultSet.getString("user_name"));
user.setPwd(resultSet.getString("pwd"));
user.setRealname(resultSet.getString("real_name"));
users.add(user);
}
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.getJDBCUtil().closeConnection(resultSet,preparedStatement,connection);
}
return users;
}
package com.aizhi.dao;
import com.aizhi.common.Message;
import com.aizhi.po.User;
import com.aizhi.util.JDBCUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class MessageDao {
/**
* 聊天信息存入数据库的方法
* @param message
* @return
*/
public void insertMessage(Message message){
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try{
//获取数据库连接
connection = JDBCUtil.getJDBCUtil().getConnection();
//准备数据库语句
StringBuffer stringBuffer = new StringBuffer(" insert into message(user_name,friend_name,is_read,content) value(?,?,?,?)");
preparedStatement = connection.prepareStatement(stringBuffer.toString());
preparedStatement.setString(1,message.getUserName());
preparedStatement.setString(2,message.getFriendName());
preparedStatement.setInt(3,message.getIsRead());
preparedStatement.setString(4,message.getContent());
//执行sql
preparedStatement.executeUpdate();
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.getJDBCUtil().closeConnection(resultSet,preparedStatement,connection);
}
}
/**
* 更新消息的状态为已读
* @param message
*/
public void updateMessageState(Message message){
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try{
//获取数据库连接
connection = JDBCUtil.getJDBCUtil().getConnection();
//准备数据库语句
StringBuffer stringBuffer = new StringBuffer(" update message set is_read=1 where user_name=? and friend_name=? ");
preparedStatement = connection.prepareStatement(stringBuffer.toString());
preparedStatement.setString(1,message.getUserName());
preparedStatement.setString(2,message.getFriendName());
//执行sql
preparedStatement.executeUpdate();
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.getJDBCUtil().closeConnection(resultSet,preparedStatement,connection);
}
}
/**
* 获取数据库里面的用户的留言信息
* @return
*/
public List<Message> getMessages(String userName,String friendName){
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
List<Message> messages = null;
try{
//获取数据库连接
connection = JDBCUtil.getJDBCUtil().getConnection();
//准备数据库语句
StringBuffer stringBuffer = new StringBuffer(" select user_name,friend_name,content from message where is_read=0 and user_name=? and friend_name=? ");
preparedStatement = connection.prepareStatement(stringBuffer.toString());
preparedStatement.setString(1,userName);
preparedStatement.setString(2,friendName);
//执行sql
resultSet = preparedStatement.executeQuery();
//容器生成
messages = new ArrayList<>();
//遍历信息
while(resultSet.next()){
Message message = new Message();
message.setUserName(resultSet.getString("user_name"));
message.setFriendName(resultSet.getString("friend_name"));
message.setContent(resultSet.getString("content"));
messages.add(message);
}
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.getJDBCUtil().closeConnection(resultSet,preparedStatement,connection);
}
return messages;
}
}
package com.aizhi.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCUtil {
private static JDBCUtil jDBCUtil = null;
/**
* 确保工具类只会被new一次
*/
private JDBCUtil(){
}
//获取工具类的方法
public static JDBCUtil getJDBCUtil(){
if(jDBCUtil==null){
jDBCUtil = new JDBCUtil();
}
return jDBCUtil;
}
static{
try{
Class.forName("com.mysql.jdbc.Driver");
}catch (Exception e){
e.printStackTrace();
}
}
//获取数据库连接
public Connection getConnection() throws Exception{
return DriverManager.getConnection(PropertiesUtil.getPropertiesUtil().getValue("url"),PropertiesUtil.getPropertiesUtil().getValue("username"),PropertiesUtil.getPropertiesUtil().getValue("pwd"));
}
//关闭数据库连接
public void closeConnection(ResultSet resultSet, Statement statement,Connection connection){
try{
if(resultSet!=null){
resultSet.close();
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(statement!=null){
statement.close();
}
}catch (Exception e){
e.printStackTrace();
}
finally {
try {
if(connection!=null){
connection.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
package com.aizhi.util;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesUtil {
//单例模式
private static PropertiesUtil propertiesUtil = null;
//读取配置文件使用
private Properties properties;
private PropertiesUtil(){
properties = new Properties();
InputStream inputStream = PropertiesUtil.class.getClassLoader().getResourceAsStream("com/aizhi/config.properties");
//将配置文件加载到Properties里面
try{
properties.load(inputStream);
}catch(Exception e){
e.printStackTrace();
}
}
public static PropertiesUtil getPropertiesUtil(){
if(propertiesUtil==null){
propertiesUtil = new PropertiesUtil();
}
return propertiesUtil;
}
public String getValue(String key){
return properties.getProperty(key);
}
}
-
建立客户端与服务器之间的实时通信通道,以支持消息的即时传输。
服务器端使用 Java 的 ServerSocket 来监听指定的端口,等待客户端的连接请求。一旦客户端连接成功,服务器为该连接创建一个新的 Socket 对象,并启动一个线程或使用线程池来处理与该客户端的通信。通过读取和写入 Socket 的输入输出流来实现消息的收发。客户端同样使用 Socket 连接到服务器的指定端口,并发送登录请求、消息等数据。
3.将用户的注册信息、登录状态等存储到数据库中,并支持用户信息的查询和。更新。
使用 MySQL 或类似的关系型数据库管理用户信息。注册时,将新用户的用户名和经过哈希处理的密码存储到数据库中。登录时,验证用户提供的用户名和密码是否与数据库中存储的匹配。
4.存储用户之间的聊天消息,并支持消息的检索和查询。
创建一个消息表(如 messages)来存储用户之间的聊天消息。当用户发送消息时,将消息内容、发送者和接收者的信息存储到数据库中。查询时,可以根据发送者和接收者的信息来检索消息记录,以显示历史消息或实现离线消息的发送。