java實現多人聊天工具(socket+多線程)

大一下學期的java期末課程設計:java實現多人聊天工具,分享一下

課設要求

多人聊天工具

  • 服務器要求1:能夠看到所有在線用戶(25%)
  • 服務器要求2:能夠強制用戶下線(25%)
  • 客戶端要求1:能夠看到所有在線用戶(25%)
  • 客戶端要求2:能夠向某個用戶發送消息(25%)

相關知識點

1.服務端能夠看到所有在線用戶

服務端繼承瞭JFrame,實現可視化,通過socket實現服務端與客戶端的連接,服務端每接收一個連接,把傳進來的用戶名和對應的socket連接封裝成一個User對象,把User對象存進一個ArrayList的用戶列表並把User對象通過取用戶名方法取得用戶名存進一個ArrayList的用戶名列表,添加一個JPanel組件,將ArrayList中的內容通過循環顯示JPanel中並佈局在窗體的右邊,在每當有人上線或者下線,刷新JPanel組件。

2.服務端能夠強制用戶下線

創建一個佈局在窗體的下方的JPanel,在此JPanel中分別添加JLabel用於顯示提示文字,添加JTextField用於獲取服務端想要強制用戶下線的ID,添加JButton用於綁定強制用戶下線的事件監聽,事件監聽中將獲取的JTextField的內容與用戶名列表進行逐一匹配,匹配上則創建JSON格式的鍵值對對象,通過用戶列表循環廣播告知其他用戶,並在用戶列表和用戶名列表中分別刪除該用戶信息。

3.客戶端能夠看到所有在線用戶

客戶端繼承瞭JFrame,實現可視化,添加瞭一個佈局在窗口右邊的JPanel,把從服務端接收到的用戶名列表中的信息放進去。

4.客戶端要求能夠向某個用戶發送消息

客戶端私發消息通過在消息後面加入-和目標用戶名,傳給服務端,服務端截取目標用戶名,在用戶名列表中判斷是否存在此人,有則判斷是否是私發,私發則向目標用戶發送消息,沒有則向全部用戶發送消息。

5.運用JDBC實現持久化存儲用戶信息

數據庫連接池運用瞭阿裡巴巴的durid,定義一個JDBCUtils類,提供靜態代碼塊加載配置文件,初始化連接池對象,通過Spring框架的JDBCTemplate對象進行sql語句的執行,在UserDao中提供瞭登錄和註冊方法,登錄方法運用queryForObject方法進行登錄查詢,如果查到返回一個User對象,查不到則返回空,註冊方法直接插入新記錄,此處建表語句中把用戶名設置成瞭主鍵,保證瞭用戶名的唯一性,註冊失敗有警告彈窗提示。
這裡加瞭一個ChatTest類用於繞過數據庫賬號校驗,可以直接進入客戶端進行連接。

6.使用JSONObject對象封裝數據

在數據的傳輸中運用瞭鍵值對的形式進行傳輸,客戶端傳輸給服務端的數據包中,通過判斷private鍵的值來確認是否私發,通過username鍵告知服務端客戶端的用戶名,通過msg鍵傳輸具體消息,服務端傳輸給客戶端的數據包中,通過判斷user_list鍵的值來確認在線用戶及人數

7.使用Maven構建管理項目

項目中運用到瞭JDBC相關內容和JSONObject對象,導入瞭一些依賴jar包,其中倉庫和配置文件都是用的idea默認配置。

類圖

項目框架

核心代碼

1.maven配置文件pom.xml

<?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>MyChat</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>15</maven.compiler.source>
        <maven.compiler.target>15</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.45</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.6</version>
        </dependency>
    </dependencies>

</project>

2.服務器端Server.java

import java.awt.image.BufferedImage;
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import net.sf.json.JSONObject;


//繼承JFrame實現可視化
public class Server extends JFrame{

    //用戶列表,用於存放連接上的用戶信息
    ArrayList<User> user_list = new ArrayList<>();
    //用戶名列表,用於顯示已連接上的用戶
    ArrayList<String> username_list = new ArrayList<>();

    //消息顯示區域
    JTextArea show_area = new JTextArea();
    //用戶名顯示區域
    JTextArea show_user = new JTextArea(10, 10);

    //socket的數據輸出流
    DataOutputStream outputStream = null;
    //socket的數據輸入流
    DataInputStream inputStream = null;

    //從主函數裡面開啟服務端
    public static void main(String[] args) {
        new Server();
    }

    //構造函數
    public Server() {

        //設置流式佈局
        setLayout(new BorderLayout());
        //VERTICAL_SCROLLBAR_AS_NEEDED設置垂直滾動條需要時出現
        //HORIZONTAL_SCROLLBAR_NEVER設置水平滾動條不出現
        //創建信息顯示區的畫佈並添加到show_area
        JScrollPane panel = new JScrollPane(show_area,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        //設置信息顯示區標題
        panel.setBorder(new TitledBorder("信息顯示區"));
        //佈局到中央
        add(panel,BorderLayout.CENTER);
        //設置信息顯示區為不可編輯
        show_area.setEditable(false);


        //創建用於顯示用戶的畫佈
        final JPanel panel_east = new JPanel();
        //添加流式佈局
        panel_east.setLayout(new BorderLayout());
        //設置標題
        panel_east.setBorder(new TitledBorder("在線用戶"));
        //在用戶顯示區添加show_uesr
        panel_east.add(new JScrollPane(show_user), BorderLayout.CENTER);
        //設置用戶顯示區域為不可編輯
        show_user.setEditable(false);
        //將顯示用戶的畫佈添加到整體佈局的右側
        add(panel_east, BorderLayout.EAST);

        //創建關於踢下線用戶的畫佈
        final JPanel panel_south = new JPanel();
        //創建標簽
        JLabel label = new JLabel("輸入要踢下線用戶的ID");
        //創建輸入框
        JTextField out_area = new JTextField(40);
        //創建踢下線按鈕
        JButton out_btn = new JButton("踢下線");
        //依次添加進畫佈
        panel_south.add(label);
        panel_south.add(out_area);
        panel_south.add(out_btn);
        //將踢下線用戶的畫佈添加到整體佈局的下側
        add(panel_south,BorderLayout.SOUTH);

        //設置踢下線按鈕的監聽
        out_btn.addActionListener(e -> {
            try {
                //用於存儲踢下線用戶的名字
                String out_username;
                //從輸入框中獲取踢下線用戶名
                out_username = out_area.getText().trim();
                //用於判斷蓋用戶是否被踢下線
                boolean is_out=false;
                //遍歷用戶列表依次判斷
                for (int i = 0; i < user_list.size(); i++){
                    //比較用戶名,相同則踢下線
                    if(user_list.get(i).getUsername().equals(out_username)){
                        //獲取被踢下線用戶對象
                        User out_user = user_list.get(i);
                        //使用json封裝將要傳遞的數據
                        JSONObject data = new JSONObject();
                        //封裝全體用戶名,廣播至所有用戶
                        data.put("user_list", username_list);
                        //廣播的信息內容
                        data.put("msg", out_user.getUsername() + "被管理員踢出\n");
                        //服務端消息顯示區顯示相應信息
                        show_area.append(out_user.getUsername() + "被你踢出\n");
                        //依次遍歷用戶列表
                        for (User value : user_list) {
                            try {
                                //獲取每個用戶列表的socket連接
                                outputStream = new DataOutputStream(value.getSocket().getOutputStream());
                                //傳遞信息
                                outputStream.writeUTF(data.toString());
                            } catch (IOException ex) {
                                ex.printStackTrace();
                            }
                        }
                        //將被踢用戶移出用戶列表
                        user_list.remove(i);
                        //將被踢用戶移出用戶名列表
                        username_list.remove(out_user.getUsername());
                        //刷新在線人數
                        show_user.setText("人數有 " + username_list.size() + " 人\n");
                        //刷新在線用戶
                        for (String s : username_list) {
                            show_user.append(s + "\n");
                        }
                        //判斷踢出成功
                        is_out=true;
                        break;
                    }

                }
                //根據是否踢出成功彈出相應提示
                if(is_out){
                    JOptionPane.showMessageDialog(null,"踢下線成功","提示",
                            JOptionPane.WARNING_MESSAGE);
                }
                if(!is_out){
                    JOptionPane.showMessageDialog(null,"不存在用戶","提示",
                            JOptionPane.WARNING_MESSAGE);
                }
                //重置輸入框
                out_area.setText("");
            } catch(Exception ex) {
                ex.printStackTrace();
            }
        });

        //設置該窗口名
        setTitle("服務器 ");
        //引入圖片
        BufferedImage img;
        try {
            //根據圖片名引入圖片
            img = ImageIO.read(Server.class.getResource("/a.jpg"));
            //設置其為該窗體logo
            setIconImage(img);
        } catch (IOException exception) {
            exception.printStackTrace();
        }
        //設置窗體大小
        setSize(700, 700);
        //設置窗體位置可移動
        setLocationRelativeTo(null);
        //設置窗體關閉方式
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //設置窗體可見
        setVisible(true);

        //socket連接相關代碼
        try {
            //開啟socket服務器,綁定端口11111
            ServerSocket serverSocket = new ServerSocket(11111);
            //信息顯示區打印服務器啟動時間
            show_area.append("服務器啟動時間 " + new Date() + "\n");
            //持續接收連接
            while (true) {
                //接收連接
                Socket socket = serverSocket.accept();
                //創建用戶對象
                User user = new User();
                //判斷是否連接上
                if (socket != null) {
                    //獲取輸入流
                    inputStream = new DataInputStream(socket.getInputStream());
                    //讀取輸入流
                    String json = inputStream.readUTF();
                    //創建信息對象
                    JSONObject data = JSONObject.fromObject(json);
                    //信息顯示區打印用戶上線
                    show_area.append("用戶 " + data.getString("username") + " 在" + new Date() + "登陸系統"+"\n");
                    //創建新用戶
                    user = new User();
                    //存儲socket對象
                    user.setSocket(socket);
                    //獲取輸入流用戶名
                    user.setUsername(data.getString("username"));
                    //添加進用戶列表
                    user_list.add(user);
                    //添加進用戶名列表
                    username_list.add(data.getString("username"));

                    //刷新在線人數
                    show_user.setText("人數有 " + username_list.size() + " 人\n");
                    //刷新在線用戶
                    for (String s : username_list) {
                        show_user.append(s + "\n");
                    }

                }

                //封裝信息對象
                JSONObject online = new JSONObject();
                //設置接收信息對象
                online.put("user_list", username_list);
                //設置信息內容
                online.put("msg", user.getUsername() + "上線瞭");
                //依次遍歷,將信息廣播給所有在線用戶
                for (User value : user_list) {
                    //獲取輸出流
                    outputStream = new DataOutputStream(value.getSocket().getOutputStream());
                    //給所有用戶輸出上線信息
                    outputStream.writeUTF(online.toString());
                }

                //開啟新線程,持續接收該socket信息
                new Thread(new ServerThread(socket)).start();

            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    //線程代碼
    class ServerThread implements Runnable {
        //存放全局變量socket
        private final Socket socket;

        //構造函數,初始化socket
        public ServerThread(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                //獲取輸入流
                DataInputStream inputStream = new DataInputStream(socket.getInputStream());
                //持續接收信息
                while (true) {
                    //獲取傳遞進來的信息
                    String json = inputStream.readUTF();
                    //封裝成json格式
                    JSONObject data = JSONObject.fromObject(json);

                    //通過json裡面的private判斷是否私發
                    boolean is_private = false;
                    //私發處理
                    for (int i = 0; i < user_list.size(); i++) {
                        //找到私發對象
                        if (user_list.get(i).getUsername().equals(data.getString("private"))) {
                            //構建私發信息內容
                            String msg = data.getString("time") +"\n" + data.getString("username")
                                    + " 給你發瞭一條私密消息,其它用戶看不到" + "\n"  + data.getString("msg");
                            //用該方法指定對象發送信息
                            send_msg(i, msg);

                            //將發送成功反饋給原用戶
                            for (int j = 0; j < user_list.size(); j++) {
                                //找到發信息用戶
                                if(user_list.get(j).getUsername().equals(data.getString("username"))){
                                    //構建反饋信息內容
                                    String msg2 = data.getString("time")+"\n你成功向"+user_list.get(i).getUsername()
                                            +"發送瞭一條私密消息\n" +data.getString("msg");
                                    //用該方法指定對象發送信息
                                    send_msg(j,msg2);
                                }
                            }
                            //將該操作打印到服務器監視窗
                            show_area.append(data.getString("username") +data.getString("time")+ "私發給"
                                    + data.getString("private") + ":\n" + data.getString("msg") + "\n");
                            //判斷是私發
                            is_private = true;
                            break;
                        }
                    }
                    //非私發的情況
                    if (!is_private) {
                        //構建信息內容
                        String msg = data.getString("username") + " " + data.getString("time") + ":\n"
                                + data.getString("msg");
                        //添加到服務器顯示
                        show_area.append(msg + "\n");
                        //依次發給所有在線用戶
                        for (int i = 0; i < user_list.size(); ) {
                            send_msg(i, msg);
                            i++;
                        }
                    }

                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        //發送信息給指定用戶的方法
        public void send_msg(int i, String msg) {
            //構建對象
            JSONObject data = new JSONObject();
            //封裝信息
            data.put("user_list", username_list);
            data.put("msg", msg);
            //獲取目標對象
            User user = user_list.get(i);
            try {
                //獲取輸出流
                outputStream = new DataOutputStream(user.getSocket().getOutputStream());
                //寫信息
                outputStream.writeUTF(data.toString());
            } catch (IOException e) {
                //如果沒有找到,則說明該用戶已經下線
                User out_user = user_list.get(i);
                //重復刪除操作
                user_list.remove(i);
                username_list.remove(out_user.getUsername());
                //重新構建信息
                JSONObject out = new JSONObject();
                out.put("user_list", username_list);
                out.put("msg", out_user.getUsername() + "下線瞭\n");
                //將其下線通知廣播給所有用戶
                for (User value : user_list) {
                    try {
                        outputStream = new DataOutputStream(value.getSocket().getOutputStream());
                        outputStream.writeUTF(out.toString());
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }

        }
    }


}

代碼太多瞭,懶得註釋瞭,大傢應該看得懂

3.客戶端登錄界面Client.java

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.io.IOException;


public class Client extends JFrame{


    public static void main(String[] args) {
        new Client();
    }

    public Client(){
        setTitle("登陸界面");
        BufferedImage img;
        try {
            img = ImageIO.read(Server.class.getResource("/a.jpg"));
            setIconImage(img);
        } catch (IOException exception) {
            exception.printStackTrace();
        }
        setLayout(null);
        setSize(500,500);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLayout(null);
        setResizable(false);

        JLabel username_label = new JLabel("用戶名");
        username_label.setBounds(60,100,100,50);
        add(username_label);

        JLabel password_label = new JLabel("密碼");
        password_label.setBounds(60,200,100,50);
        add(password_label);

        JTextField username_field = new JTextField();
        username_field.setBounds(110,100,300,50);
        add(username_field);

        JPasswordField password_field = new JPasswordField();
        password_field.setBounds(110,200,300,50);
        add(password_field);

        JButton login = new JButton("登陸");
        login.setBounds(130,300,100,50);
        add(login);
        JButton register = new JButton("註冊");
        register.setBounds(280,300,100,50);
        add(register);

        setVisible(true);


        login.addActionListener(e -> {
            String username = username_field.getText();
            String password = String.valueOf(password_field.getPassword());
            if(username.length()!=0 && password.length()!=0){
                User user = new User();
                user.setUsername(username);
                user.setPassword(password);
                UserDao dao = new UserDao();
                User u = dao.login(user);
                if(u!=null){
                    setVisible(false);
                    new Chat(username);
                }else{
                    JOptionPane.showMessageDialog(null,"登錄失敗,賬號或密碼錯誤","提示",
                        JOptionPane.WARNING_MESSAGE);
                }
            }else {
                JOptionPane.showMessageDialog(null,"登錄失敗,賬號或密碼不能為空","提示",
                        JOptionPane.WARNING_MESSAGE);
            }
        });

        register.addActionListener(e -> {
            setVisible(false);
            new Register();
        });
    }

}

4.客戶端註冊界面Register.java

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.io.IOException;


public class Register extends JFrame {
    public Register(){
        setTitle("註冊界面");
        BufferedImage img;
        try {
            img = ImageIO.read(Server.class.getResource("/a.jpg"));
            this.setIconImage(img);
        } catch (IOException exception) {
            exception.printStackTrace();
        }
        setLayout(null);
        setSize(500,500);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLayout(null);
        setResizable(false);

        JLabel username_label = new JLabel("用戶名");
        username_label.setBounds(60,50,100,50);
        add(username_label);

        JLabel password_label = new JLabel("密碼");
        password_label.setBounds(60,150,100,50);
        add(password_label);

        JLabel password_label2 = new JLabel("請再次輸入密碼");
        password_label2.setBounds(20,250,100,50);
        add(password_label2);

        JTextField username_field = new JTextField();
        username_field.setBounds(110,50,300,50);
        add(username_field);

        JPasswordField password_field = new JPasswordField();
        password_field.setBounds(110,150,300,50);
        add(password_field);

        JPasswordField password_field2 = new JPasswordField();
        password_field2.setBounds(110,250,300,50);
        add(password_field2);


        JButton register_success = new JButton("註冊");
        register_success.setBounds(130,350,100,50);
        add(register_success);

        JButton back = new JButton("返回");
        back.setBounds(280,350,100,50);
        add(back);

        setVisible(true);


        register_success.addActionListener(e -> {
            String username = username_field.getText();
            String password = String.valueOf(password_field.getPassword());
            String password2 = String.valueOf(password_field2.getPassword());
            System.out.println(password);
            System.out.println(password2);
            if(username.length()==0 || password.length()==0){
                JOptionPane.showMessageDialog(null,"註冊失敗,賬號或密碼不能為空","提示",
                        JOptionPane.WARNING_MESSAGE);
            }else if (!password.equals(password2)) {
                JOptionPane.showMessageDialog(null,"註冊失敗,前後密碼不匹配","提示",
                        JOptionPane.WARNING_MESSAGE);
            }else{
                System.out.println();
                System.out.println(password);
                User user = new User();
                user.setUsername(username);
                user.setPassword(password);
                UserDao dao = new UserDao();
                int flag = dao.register(user);
                if(flag!=0){
                    JOptionPane.showMessageDialog(null,"註冊成功,歡迎您登錄","提示",
                            JOptionPane.WARNING_MESSAGE);

                }else{
                    //建表語句中設置瞭user為主鍵,重復則建表失敗
                    JOptionPane.showMessageDialog(null,"註冊失敗,賬號已經存在","提示",
                            JOptionPane.WARNING_MESSAGE);
                }
            }
        });

        back.addActionListener(e ->{
           setVisible(false);
           new Client();
        });


    }

}

5.客戶端聊天界面Chat.java

import java.awt.image.BufferedImage;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class Chat extends JFrame{

    JTextArea show_area = new JTextArea();
    JTextArea show_user = new JTextArea(10, 10);
    DataOutputStream outputStream;
    DataInputStream inputStream;
    String username;
    ArrayList<String> username_list = new ArrayList<>();
    boolean is_stop = false;

    public Chat(final String username) {
        this.username = username;
        
        final JPanel panel_south = new JPanel();
        panel_south.setLayout(new BorderLayout());
        panel_south.setBorder(new TitledBorder("寫消息區,若私聊,在內容後添加(-用戶名)"));
        JTextField send_area = new JTextField(40);
        panel_south.add(send_area, BorderLayout.CENTER);
        JButton send_btn = new JButton("發送");
        panel_south.add(send_btn,BorderLayout.EAST);
        add(panel_south, BorderLayout.SOUTH);

        send_btn.addActionListener(e -> {
            try {

                if (is_stop) {
                    show_area.append("你已被踢出,不能發送消息\n");
                    JOptionPane.showMessageDialog(null,"你已被踢出,不能發送消息,進程已經關閉","提示",
                            JOptionPane.WARNING_MESSAGE);
                    System.exit(0);
                } else {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String time = sdf.format(new Date());

                    String msg = send_area.getText().trim();

                    if (!msg.equals("")) {
                        String[] msg1 = msg.split("-");
                        JSONObject data = new JSONObject();
                        data.put("username", username);
                        data.put("msg", msg1[0]);
                        data.put("time", time);

                        try {
                            data.put("private", msg1[1]);

                        } catch (ArrayIndexOutOfBoundsException e1) {
                            data.put("private", "");
                        }
                        outputStream.writeUTF(data.toString());
                    }
                }
                send_area.setText("");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        });

        JScrollPane panel = new JScrollPane(show_area,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        panel.setBorder(new TitledBorder("信息顯示區"));
        add(panel,BorderLayout.CENTER);
        show_area.setEditable(false);
        
        final JPanel panel_east = new JPanel();
        panel_east.setLayout(new BorderLayout());
        panel_east.setBorder(new TitledBorder("在線用戶"));
        panel_east.add(new JScrollPane(show_user), BorderLayout.CENTER);
        show_user.setEditable(false);
        add(panel_east, BorderLayout.EAST);

        setTitle("用戶  " + username);
        BufferedImage img;
        try {
            img = ImageIO.read(Server.class.getResource("/a.jpg"));
            this.setIconImage(img);
        } catch (IOException exception) {
            exception.printStackTrace();
        }
        setSize(500, 500);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

        JSONObject data = new JSONObject();
        data.put("username", username);
        data.put("msg", null);

        try {
            Socket socket = new Socket("127.0.0.1", 11111);
            inputStream = new DataInputStream(socket.getInputStream());
            outputStream = new DataOutputStream(socket.getOutputStream());
            outputStream.writeUTF(data.toString());
            new Thread(new Read()).start();
        } catch (IOException e) {
            show_area.append("服務器無響應");
            JOptionPane.showMessageDialog(null,"服務器無響應","提示",
                    JOptionPane.WARNING_MESSAGE);
        }
    }

    public class Read implements Runnable {
        @Override
        public void run() {
            try {
                while (true) {
                    String json = inputStream.readUTF();
                    JSONObject data = JSONObject.fromObject(json);
                    String msg = data.getString("msg");
                    if (msg.contains("踢出") && msg.contains(username)) {
                        is_stop = true;
                        show_area.append(username + ",你已經被踢出群聊\n");
                        JOptionPane.showMessageDialog(null,"你已經被踢出群聊","提示",
                                JOptionPane.WARNING_MESSAGE);
                        System.exit(0);
                    } else {
                        show_area.append(msg + "\n");
                        show_area.selectAll();
                        username_list.clear();
                        JSONArray jsonArray = data.getJSONArray("user_list");
                        for (Object o : jsonArray) {
                            username_list.add(o.toString());
                        }
                        show_user.setText("人數有 " + jsonArray.size() + " 人\n");
                        for (String s : username_list) {
                            show_user.append(s + "\n");
                        }
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

6.用戶實體User.java

import java.net.Socket;

public class User {
    private String username;
    private String password;
    private Socket socket;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }
}

7.JDBC工具類

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.util.Properties;

public class JDBCUtils {
    private static DataSource ds;

    static {
        try {
            Properties pro = new Properties();
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            pro.load(is);
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    public static DataSource getDataSource(){
        return ds;
    }


}

8.UserDao.java連接數據庫

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

 

public class UserDao {
    private final JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());


    public User login(User login_user) {
        try {
            //編寫sql
            String sql = "select * from user where username = ? and password = ?";

            User user = template.queryForObject(sql,
                    new BeanPropertyRowMapper<User>(User.class),
                    login_user.getUsername(), login_user.getPassword());
            return user;
        } catch (DataAccessException e) {
            e.printStackTrace();
            return null;
        }
    }

    public int register(User register_user) {
        try {
            String sql = "insert into user values (null ,?,?)";
            int count = template.update(sql,register_user.getUsername(),register_user.getPassword());
            return count;
        } catch (DataAccessException e) {
            e.printStackTrace();
            return 0;
        }
    }

}

運行結果

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: