Java作业——Swing+网络编程+JDBC实现登陆和群聊功能

一、介绍

1. UDP是一种无连接的传输协议。进行数据传输时,首先需要将要传输的数据定义成数据报(Datagram),在数据报中指明数据所要到达的Socket(主机地址和端口号),然后再将数据报发送出去。
JDBC是一种用于执行sql语句的JavaAPI,由一组用java编写的类和接口组成,它可以做三件事:1.与数据库建立连接;2.发送sql语句;3.处理结果;

二、使用步骤

1.导入jar包

mysql-connector-java-8.0.23.jar
gson-2.8.5.jar//用来转换成JSON数据格式

2.连接数据库和编写JDBC工具类

mysql数据库连接的配置文件:jdbc.properties

user=root
password=*********//换成自己的密码
url=jdbc:mysql://localhost:3306/temp?serverTimezone=UTC
driverClass=com.mysql.cj.jdbc.Driver//驱动类

JDBC工具类

public class JDBCUtils {
    public static Connection getConnection(){
        InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
        Properties pros = new Properties();
        Connection conn = null;
        try {
            pros.load(is);
            String user = pros.getProperty("user");
            String password = pros.getProperty("password");
            String url = pros.getProperty("url");
            String driverClass = pros.getProperty("driverClass");

            Class.forName(driverClass);
            conn = DriverManager.getConnection(url,user,password);
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return conn;
    }
    public static void closeResourse(Connection conn,PreparedStatement ps,ResultSet rs) {
        try {
            if(ps!=null)
                ps.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(conn!=null)
                conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(rs!=null)
                rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static boolean findUser(String name, String password){
        Connection conn = getConnection();
        PreparedStatement ps = null;
        String sql = "select upassword from user where uname = ?";
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(sql);
            ps.setString(1,name);
            rs = ps.executeQuery();
            while(rs.next()){
                String pw = rs.getString("upassword");
                if(pw.equals(password)){
                    return true;
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            closeResourse(conn,ps,rs);
        }
        return false;
    }
    public static void addUser(String name,String password){
        Connection conn = getConnection();
        PreparedStatement ps =null;
        String sql = "insert into user value (?,?)";
        try {
            ps = conn.prepareStatement(sql);
            ps.setString(1,name);
            ps.setString(2,password);
            ps.execute();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            closeResourse(conn,ps,null);
        }
    }
}

另外,需要在数据库创建一个user表,示例如下:
在这里插入图片描述

3.注册界面

public class Register extends JFrame implements ActionListener {
    private JPanel panel = new JPanel();
    private JLabel userLabel = new JLabel("User:");     // 创建UserJLabel
    private JTextField userText = new JTextField();           // 获取登录名
    private JLabel passLabel = new JLabel("Password:");       // 创建PassJLabel
    private JPasswordField passText = new JPasswordField(20); //密码框隐藏
    private JButton loginButton = new JButton("login");       // 创建登录按钮
    private JButton registerButton = new JButton("register");
    public Register() {
        //设置窗体的位置及大小
        this.setTitle("欢迎");
        this.setSize(300, 200);
        this.setLocationRelativeTo(null);     //在屏幕中居中显示
        this.add(panel);                                      // 添加面板
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  // 设置X号后关闭
        panel.setLayout(null);  //设置布局为 null

        // 创建 UserJLabel
        userLabel.setBounds(30, 30, 80, 25);
        panel.add(userLabel);
        // 创建文本域用于用户输入
        userText.setBounds(105, 30, 165, 25);
        panel.add(userText);

        // 创建PassJLabel
        passLabel.setBounds(30, 60, 80, 25);
        panel.add(passLabel);
        // 密码输入框隐藏
        passText.setBounds(105, 60, 165, 25);
        panel.add(passText);
        // 创建登录按钮
        loginButton.setBounds(25, 100, 80, 25);
        panel.add(loginButton);
        loginButton.addActionListener(this);
        registerButton.setBounds(190, 100, 80, 25);
        panel.add(registerButton);
        registerButton.addActionListener(this);
        this.setVisible(true); //设置窗体可见
    }

    public void loginFunc(){
        String userName = userText.getText();
        String passWord = new String(passText.getPassword());
        if (JDBCUtils.findUser(userName, passWord) == true) {
            //关闭当前界面
            this.dispose();
            //打开聊天界面
            new ClientActivity(userName);
        }else{
            JOptionPane.showMessageDialog(this,"登录失败!",
                    "Fail",JOptionPane.INFORMATION_MESSAGE);
        }
    }

    public void registerFunc(){
        String userName = userText.getText();
        String passWord = new String(passText.getPassword());
        if(userName==""&&passWord==""){
            JOptionPane.showMessageDialog(this, "用户名或密码为空",
                    "Fail", JOptionPane.ERROR_MESSAGE);
        }
        else if (JDBCUtils.findUser(userName, passWord) == true) {
            JOptionPane.showMessageDialog(this, "注册失败!用户已存在",
                    "Fail", JOptionPane.ERROR_MESSAGE);
        } else {
            JDBCUtils.addUser(userName, passWord);
            JOptionPane.showMessageDialog(this, "注册成功!",
                    "Fail", JOptionPane.INFORMATION_MESSAGE);
        }
    }
    @Override
    public void actionPerformed(ActionEvent actionEvent) {//登陆或注册
        Object source = actionEvent.getSource();
        if(source == loginButton){
            this.loginFunc();
        }else if(source == registerButton){
            this.registerFunc();
        }
    }
}

3.用户聊天界面

public class ClientActivity extends JFrame{

    private String name;
    private JTextField textField;
    private DatagramSocket socket;
    private InetAddress ip;
    private JTextArea textArea;
    public ClientActivity(String name) {
        super("聊天客户端:"+name);
        this.name=name;
        setSize(500, 500);
        getContentPane().setLayout(null);
        initLayout();
        initUdp();
        show();
    }

    private void initLayout() {
        JButton sendBtn = new JButton("发送");
        sendBtn.addActionListener(e -> {
            String msg=textField.getText();
            sendMessage(msg);
            textField.setText("");
        });
        sendBtn.setBounds(366, 419, 97, 23);
        getContentPane().add(sendBtn);

        textField = new JTextField();
        textField.setBounds(10, 419, 346, 23);
        getContentPane().add(textField);
        textField.setColumns(10);
        textArea = new JTextArea();
        textArea.setBounds(10, 0, 466, 365);
        getContentPane().add(textArea);
    }
    private void initUdp() {
        MyService.loginGroups(this);
        try {
            socket=new DatagramSocket();
            ip=InetAddress.getByName("127.0.0.1");
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

    }
    public void pushMessage(MessageBean bean) {
        textArea.append(bean.getName()+":"+bean.getContent()+"\n");//打印用户名和信息
    }
    private void sendMessage(String msg) {
        MessageBean bean=new MessageBean();
        bean.setName(name);
        bean.setContent(msg);
        Gson gson=new Gson();
        String json=gson.toJson(bean);//转换为json格式
        byte[] bytes=json.getBytes();
        DatagramPacket datagramPacket=new DatagramPacket(bytes, bytes.length,ip,MyService.PORT);
        try {
            socket.send(datagramPacket);//发送报文
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

4.服务端

public class MyService extends Thread{

    public static int PORT=10005;
    private static DatagramSocket socket;
    private static ArrayList<ClientActivity> mList=new ArrayList<>();
    public MyService() {
        try {
            socket=new DatagramSocket(PORT);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
    public static void loginGroups(ClientActivity clientActivity) {
        if(clientActivity==null)
            return;
        mList.add(clientActivity);
    }

    private void receiveMessage() {
        byte[] buf=new byte[1024];
        DatagramPacket datagramPacket=new DatagramPacket(buf, buf.length);
        while(true) {
            try {
                socket.receive(datagramPacket);//阻塞当前系统的报文,直到有一个报文到达socket
                String msg=new String(datagramPacket.getData(),0,datagramPacket.getLength());
                Gson gson=new Gson();
                MessageBean bean=gson.fromJson(msg, MessageBean.class);
                for(ClientActivity clientActivity:mList) {
                    //发送数据给每一个客户端
                    clientActivity.pushMessage(bean);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void run() {
        receiveMessage();
    }
}

5.消息类

public class MessageBean {
    private String name;
//    private String password;//暂时用不到密码
    private String content;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
//    public String getPassword() {
//        return password;
//    }
//    public void setPassword(String password) {
//        this.password = password;
//    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
}

6.程序主入口

public class Main {
    public static void main(String[] args) {
        new Register();
        new Register();
        new Register();//这里可以创建多个用户
        MyService myService=new MyService();
        myService.start();//服务端多线程接受用户的消息
    }
}

附上运行截图:

在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值