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;
        }
    }

}

运行结果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java线程池详细解读

    目录 1.线程池 1.1 线程池概念 1.2 线程池的实现 2.StringBuffer类 面试题:请解释String.StringBuffer.StringBuilder的区别? 3.Runtime类 面试题:什么叫gc?如何处理 4.System类 面试题:请解释final.finally.finalize的区别? 5.对象克隆 6.Date类 6.1 日期处理类-Date类 6.2 日期格式化-SimpleDateFormat类(核心) 7. 数字操作类-Math类 7.1 随机数-Ran

  • Day12基础不牢地动山摇-Java基础

    目录 1.多线程 1.1 多线程的基本概念 1.2 多线程的实现 1.3 继承Thread类实现多线程 1.4 Runnable接口实现多线程 1.5 Thread类和Runnable接口实现多线程的区别 1.6 线程的操作状态 1.7 Callable实现多线程 1.8 线程命名和取得 1.9 线程的休眠 1.10 线程的优先级 1.11 线程的同步与死锁 1.12 死锁 综合案例 1.解决数据错位问题:依靠同步解决 2.解决数据的重复设置和重复取出 面试题:请解释sleep()和wait()

  • java课程设计做一个多人聊天室(socket+多线程)

    目录 课设要求 相关知识点 1.服务端能够看到所有在线用户 2.服务端能够强制用户下线 3.客户端能够看到所有在线用户 4.客户端要求能够向某个用户发送消息 5.运用JDBC实现持久化存储用户信息 6.使用JSONObject对象封装数据 7.使用Maven构建管理项目 类图 项目框架 核心代码 1.maven配置文件pom.xml 2.服务器端Server.java 4.客户端注册界面Register.java 5.客户端聊天界面Chat.java 6.用户实体User.java 7.JDBC

  • java线程池详解及代码介绍

    目录 一.线程池简介 二.四种常见的线程池详解 三.缓冲队列BlockingQueue和自定义线程池ThreadPoolExecutor 总结 一.线程池简介 线程池的概念 线程池就是首先创建一些线程,它们的集合称为线程池,使用线程池可以很好的提高性能,线程池在系统启动时既创建大量空闲的线程,程序将一个任务传给线程池.线程池就会启动一条线程来执行这个任务,执行结束后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务. 线程池的工作机制 在线程池的编程模式下,任务是提交给整个

  • Java 线程的优先级(setPriority)案例详解

    线程可以划分优先级,优先级高的线程得到的CPU资源比较多,也就是CPU优先执行优先级高的线程对象中的任务. 设置线程优先级有助于帮助线程规划器确定下一次选中哪一个线程优先执行. java中优先级分为1-10个级别 线程优先级的继承特性 例如a线程启迪b线程,则b线程的优先级与a的一样. 代码说话:(很简单) public class MyThread1 extends Thread { @Override public void run() { System.out.println("MyThr

  • Java创建线程及配合使用Lambda方式

    目录 一.创建线程三种方式 1.1 继承Thread类创建线程类 1.2 通过Runnable接口创建线程类 使用Lambda表达式 1.3 通过Callable和Future创建线程 使用Lambda表达式 二.创建线程的三种方式的对比 2.1 实现Runnable.Callable接口的方式创建多线程 2.2 继承Thread类的方式创建多线程 2.3 Runnable和Callable的区别 一.创建线程三种方式 1.1 继承Thread类创建线程类 定义Thread类的子类,并重写该类的

  • Java httpClient连接池支持多线程高并发的实现

    当采用HttpClient httpClient = HttpClients.createDefault() 实例化的时候.会导致Address already in use的异常. 信息: I/O exception (java.net.BindException) caught when processing request to {}->http://**.**.**.** Address already in use: connect 十一月 22, 2018 5:02:13 下午 or

  • java实现多人聊天工具(socket+多线程)

    大一下学期的java期末课程设计:java实现多人聊天工具,分享一下 课设要求 多人聊天工具 服务器要求1:能够看到所有在线用户(25%) 服务器要求2:能够强制用户下线(25%) 客户端要求1:能够看到所有在线用户(25%) 客户端要求2:能够向某个用户发送消息(25%) 相关知识点 1.服务端能够看到所有在线用户 服务端继承了JFrame,实现可视化,通过socket实现服务端与客户端的连接,服务端每接收一个连接,把传进来的用户名和对应的socket连接封装成一个User对象,把User对象

  • Java实现多人聊天室的原理与源码

    多人聊天室原理图 源码 工具类: 该类用于关闭各种流. public class CloseUtil { public static void CloseAll(Closeable... closeable){ for(Closeable c:closeable){ if (c != null) { try { c.close(); } catch (IOException e) { e.printStackTrace(); } } } } } 服务器: 服务器端创建一个serverSocket

  • java实现多人聊天室可视化

    编写一个 Java 应用程序,实现图形界面多人聊天室(多线程实现),要求聊天室窗口标题是 “欢迎使用 XXX 聊天室应用”,其中 XXX 是自己的班级姓名学号,如“软件 171 张三 1234”. 客户端 import java.awt.BorderLayout; import java.awt.Container; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.Actio

  • java UDP实现一个聊天工具的示例代码

    题目: 假设Tom和Jerry利用Java UDP进行聊天,请为他们编写程序.具体如下: (1).Tom和Jerry聊天的双方都应该具有发送端和接收端: (2).利用DatagramSocket与DatagramPacket: (3).实现 java.lang.Runnable类,重写 run()方法. 学过计网的都知道,利用三元组(ip地址,协议,端口)就可以标识网络的进程了. 而进行通信我们直接运用socket就可以了,首先需要知道是socket是什么,这部分可以参考这个大佬写的博客. ht

  • Java实现多人聊天室(含界面)

    本文实例为大家分享了Java实现多人聊天室的具体代码,供大家参考,具体内容如下 先说,记录本人的学习过程,当笔记了 多人聊天室分为 1.服务器 ①.while循环 (guanbo) 每连接一个用户就记录一个用户的属性.②.定义一个存储用户的类( MySocket )③.接收信息( ServerThread )并发给每一位用户不需要再次发给自己 2.客户机 ①.线程 ( Clithr )接收数据添加到文本框.②.Swing(kefuduang)做界面. 代码如下: 先客户机吧简单点 import

  • Unity实现简单的多人聊天工具

    本文实例为大家分享了Unity实现多人聊天工具的具体代码,供大家参考,具体内容如下 代码1 : 服务端代码 using UnityEngine; using System.Net.Sockets; using System.Net; using System.Threading; public class ChatServer : MonoBehaviour {        // 设置连接端口        const int portNo = 500;        string m_Ser

  • java socket实现聊天室 java实现多人聊天功能

    用java socket做一个聊天室,实现多人聊天的功能.看了极客学院的视频后跟着敲的.(1DAY) 服务端: 1. 先写服务端的类MyServerSocket,里面放一个监听线程,一启动就好 2. 实现服务端监听类ServerListener.java,用accept来监听,一旦有客户端连上,生成新的socket,就新建个线程实例ChatSocket.启动线程后就把线程交给ChatManager管理 3. 在ChatSocket中实现从客户端读取内容,把读取到的内容发给集合内所有的客户端 4.

  • Java实现简单QQ聊天工具

    Java实现简单的类似QQ聊天工具,供大家参考,具体内容如下 所使用到的知识点: java socket编程之TCP协议 java Swing 简单的java多线程 运行截图: 服务器端实现: package tcp_server; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.

  • java实现多人聊天对话室

    使用ServerSocket和Socket实现服务器端和客户端的Socket通信. 了解完socket通信步骤后可以发现本实验需要写两个类:Server和Client,并且要先运行Server再运行Client. 先构造服务器端 import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Sock

随机推荐