java仿QQ程序

1. *面向对象设计

在前端开发中,我采用了面向对象的设计理念。通过定义多个类和接口,实现了代码的模块化和复用。我主要设计了用户类(User)、聊天界面类(TalkView)、消息类(Message)等,它们之间通过继承、实现接口等方式进行交互,共同构成了整个前端系统的核心框架。

 

2. *聊天界面、用户界面的建立:

我使用了HTML、CSS和JavaScript等技术来构建聊天界面和用户界面。聊天界面主要包括聊天窗口、输入框、表情选择等组件;用户界面则包含了登录、注册、好友列表等页面。在实现过程中,我遇到了界面布局、交互效果等难点,通过学习和参考多个开源项目和教程,我成功解决了这些问题。

3. *消息发送与接收功能

我通过WebSocket技术实现了消息的实时发送与接收。用户可以在聊天窗口中输入文字,点击发送按钮后,消息将被发送到后端服务器,并由服务器转发给目标用户。同时,用户也可以实时接收到来自其他用户的消息,并在聊天窗口中显示出来。在实现过程中,我遇到了WebSocket连接建立、消息格式定义等难点,通过查阅文档和调试代码,我成功解决了这些问题。

 

 

 

 

 

 

 

 

4. 与后端服务器的数据交互

我通过MySQL的相关技术实现了与后端服务器的数据交互。当用户进行登录、注册、添加好友等操作时,前端会将请求发送到后端服务器,服务器处理请求后返回结果给前端。前端再根据返回的结果更新界面或执行相应的操作。

  1. 数据库读写部分                                                                                                                                      

创建数据访问对象 (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类中检索数据库连接详细信息。
详细说明:
  1. 数据库连接详细信息
  • URL、用户、密码private static final String URL, USER, PASSWORD;
    • 使用检索数据库连接详细信息PropertiesUtil
  • 静态块static { ... }
    • 此块确保在加载类时初始化这些值。
  1. getConnection 方法public static Connection getConnection()
  • 用于DriverManager.getConnection使用提供的 URL、用户和密码建立与数据库的连接。
  • SQLException如果连接尝试失败则抛出。

综合功能

  1. 初始化
  • PropertiesUtil初始化一次并用于加载配置属性。
  • JDBCUtil从 检索数据库连接详细信息PropertiesUtil
  1. 用法
  • 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);
    }

}
  1. 建立客户端与服务器之间的实时通信通道,以支持消息的即时传输。

服务器端使用 Java 的 ServerSocket 来监听指定的端口,等待客户端的连接请求。一旦客户端连接成功,服务器为该连接创建一个新的 Socket 对象,并启动一个线程或使用线程池来处理与该客户端的通信。通过读取和写入 Socket 的输入输出流来实现消息的收发。客户端同样使用 Socket 连接到服务器的指定端口,并发送登录请求、消息等数据。

3.将用户的注册信息、登录状态等存储到数据库中,并支持用户信息的查询和。更新。

使用 MySQL 或类似的关系型数据库管理用户信息。注册时,将新用户的用户名和经过哈希处理的密码存储到数据库中。登录时,验证用户提供的用户名和密码是否与数据库中存储的匹配。

4.存储用户之间的聊天消息,并支持消息的检索和查询。

创建一个消息表(如 messages)来存储用户之间的聊天消息。当用户发送消息时,将消息内容、发送者和接收者的信息存储到数据库中。查询时,可以根据发送者和接收者的信息来检索消息记录,以显示历史消息或实现离线消息的发送。

运行效果截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值