java在线聊天项目 客户端登陆窗口LoginDialog的注册用户功能

1.简介

 
  MongoDB是一个开源的,高性能无论模式的文档型数据库,非关系项目数据库。可用以代替传统的关系项目数据库或键/值存储方。

    主要特点

 
  (1)高性能:非关系型,无模式,使用外存映射

 
  (2)高可用:自动故障转移和副本集

 
  (3)水平扩展:分片能管数据分发及一个集群的条件遭受

    (4)支持多独存储引擎:WiredTiger
和MMAPv1 Storage Engine,可插拔,支持第三着引擎

 
  与MySQL相比
,也是起关系型和非关系型数据库间对比,主要发生以下两样:

 
  (1)非关系型,文档中没有联系,数据由包含,MySql有外键,连接查询等

 
  (2)不支持工作,但未表示不克用来管理非同小可数据(MySQL的MYISAM存储引擎也未支持事务…)

 
  (3)无模式,集合中之文档结构不固定,可以储存各式各样的文档,文档可以嵌套,存储数组等

 
  (4)没有说明,行之定义,与的相应的是集聚和文档

 点击下图注册按钮,出现挂号用户面板,把手机号和判断一致之密码添加到MySQL数据库中

2.文档

 
  MongoDB的成团不强制指定文档的组织,文档结构具有莫大的八面玲珑,不像关系数据库在插入数据时,必须先行凭定表的构造。

 
  MongoDB采用BSON类型文档存储,BSON是JSON的二进制表示,它包含重复多之数据类型。如下一个简短的文档:

    var mydoc = {

           _id:
ObjectId(“5099803df3f4948bd2f98391”),    ObjectId类型的性能

           name: { first: “Alan”, last:
“Turing” },            embedded嵌套文档

           birth: new Date(‘Jun 23,
1912’),                date日期类型

           death: new Date(‘Jun 07,
1954’),

           contribs: [ “Turing machine”,
“Turing test”, “Turingery” ],  array数组类型

           views :
NumberLong(1250000)                 NumberLong类型

    }

 
  文档的局限性
:每个文档最酷未可知跨越16M,对于电影,图片等特别文件MongoDB使用
GridFS 来开展分块存储。

 
  文档的性字段
凡是字符类型,并且分轻重缓急写,大多数MongoDB接口不支持性重名,不能够包含美元符号($),点(.),null
这些字符,每个文档都起”_id”为保存作            为一个主键字段。

 
  文档中好利用的数据类型如下表:

图片 1

 

图片 2

3.存储方

 
  MongoDB支持多囤引擎,这里主要介绍两种植,分别是MMAPv1和WiredTiger。主要由当下几单方面来描述,并作写副,操作日志,内存以

做事规律:

3.1 WiredTiger Storage Engine

    主要特色发生:

 
  (1)WiredTiger存储引擎是MongoDB3.2的默认存储引擎。

    (2)支持文档级别的并发。

 
  (3)快照和检查点,WT先将持有数据勾勒及一个快照中然后刷到磁盘数据文件,并把目前刷新的多寡作为数据文件被的一个检查点,可用来管数据的一致性和恢复
           
数据(也会看做恢复点),WT中列60秒或者journal文件大于2G会见安装一个检查点,将数据刷到磁盘。

    (4)Journal
操作日志,每50毫秒会记录每个检查点之间的保有修改操作,日志文件大小限制也100M,每创建新的文件会并之前的日记文件,在dbpath的目
           
下会起一个Journal的公文夹,日志文件命名吧WiredTigerLog.<sequence>。

 
  (5)内存以,WT默认使用内存的60%-1G要么1G

暨单机的软件不同,这个聊天的登录框不可知将报信息一直上加进数据库

3.2 MMAPv1 Storage Engine

 
  MMAPv1基于外存映射,擅长处理大量的读写及就地更新操作。是3.2之前版本的默认存储引擎。

    主要特征发生:

    (1)支持集级别的并发

 
  (2)Journal操作日志,每100毫秒就会写入journal files
一潮,每60秒持久化一潮数据文件data
files到磁盘,所以当一个mongod实例还没刷数据及磁盘,可              
 以用Journal进行数据恢复。在dbpath的目下会有一个Journal的文本夹,日志文件命名也j._<sequence>,文件超过1G晤创造新的。

    (3)Avoid Preallocation Lag for
MMAPv1  优先布置落后

 
  (4)内存以,MMAPv1会尽可能采取具有可用之内存作为缓存

而是应当把注册信息发送至服务器

4.权限

 
  MongoDB默认不开起来访问控制,单机可以应用—auth参数启用,集群使用keyfile方法启用。

    MongoDB中之用户权限:

 图片 3

当服务器收到至注册信息后,在服务端把报信息补充加进数据库

5.总结

   
MongoDB是一个分布式文件存储的数据库,由C++语言编写,旨在提供可扩大的大性能数据存储方案。

 
  采用无模式组织存储,集合好储存结构不同之文档,但一般要存储相同的结构;支持索引,可以于任意属性上成立目录,包括内嵌文档;丰富的查询语言和汇聚工具,支持复制与数据恢复,内置自动数据分片等功效。

    主要适用于以下状况:

    (1)
适合实时插入,更新与查询,高度可伸缩性

    (2) 缓存,性能大可看成缓存层

    (3)
适合数十或者数百贵服务器组成的数据库

 


 

首先,做连接数据库的预备

连续数据库需要一个总是数据库的驱动包
—— mysql-connector-java-5.1.7-bin.jar

要忘记倒入连接mysql数据库的保证,会现出java.lang.ClassNotFoundException:
com.mysql.jdbc.Driver问题

 

下载地址:链接: https://pan.baidu.com/s/1geBRqqn 密码: 8jxm

 

然后,把连接数据库的讲话做成工具类,方便调用

DBUtil类,负责连接已有的数据库sw_database(用DBUtil.getConn()方法)

      负责连接数据库后关门各种资源(用DBUtil.closeAll()方法)

package com.swift.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DBUtil {

    public static Connection getConn() {
        Connection conn=null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            String url="jdbc:mysql://localhost:3306/sw_database";
            String user="root";
            String password="root";
            conn=DriverManager.getConnection(url, user, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    public static void closeAll(Connection conn,PreparedStatement ps,ResultSet rs) {

        if(conn!=null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(ps!=null) {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(rs!=null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

 

继,需要把用户注册的音信补充加进数据库的sw_user表中

因此,再修一个工具类DBAdd,负责添加用户注册信息到表中(用DBAdd.add(User
user)方法)

 

package com.swift.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class DBAdd {

    public static void add(User user) {

        String phone = user.getUsername();
        String password = user.getPassword();

        Connection conn = DBUtil.getConn();
        PreparedStatement ps=null;
        try {
            ps = conn.prepareStatement("insert into sw_user(username,password) values(?,?)");
            ps.setString(1, phone);
            ps.setString(2, password);
            int count = ps.executeUpdate();
            if (count == 1) {
                System.out.println("用户添加成功");
            } else {
                System.out.println("用户添加失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.closeAll(conn, ps, null);
        }

    }

}

User类代码如下:负责用户信息的包

package com.swift.jdbc;

public class User {

    private int id;
    private String username;
    private String password;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    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 User(int id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }
    public User() {
        super();
    }
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
    }

}

 

随后,在LoginDialog登陆窗口“注册用户”按钮添加监听,当点击按钮则把消息发送给服务端

信发给服务端,需要树立及劳动端的连年,及倒闭窗口断开连接

连日后各自发送电话号码和证明好的密码

实际代码如下:

package com.swift.frame;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ConnectException;
import java.net.Socket;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.TitledBorder;

import com.swift.jdbc.DBAdd;
import com.swift.jdbc.DBUtil;
import com.swift.jdbc.User;
import com.swift.util.Center;

public class LoginDialog extends JDialog {

    private JPasswordField passwordField_2;
    private JPasswordField passwordField_1;
    private JTextField textField_2;
    private JTextField textField;

    Socket s;
    DataOutputStream dos;
    DataInputStream dis;

    public static void main(String args[]) {
        JFrame.setDefaultLookAndFeelDecorated(true);
        JDialog.setDefaultLookAndFeelDecorated(true);

        try {
            UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (ClassNotFoundException e1) {
            e1.printStackTrace();
        } catch (InstantiationException e1) {
            e1.printStackTrace();
        } catch (IllegalAccessException e1) {
            e1.printStackTrace();
        } catch (UnsupportedLookAndFeelException e1) {
            e1.printStackTrace();
        }

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    LoginDialog dialog = new LoginDialog();
                    dialog.addWindowListener(new WindowAdapter() {
                        public void windowClosing(WindowEvent e) {
                            System.exit(0);
                        }
                    });
                    dialog.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public LoginDialog() {
        super();
        setResizable(false);
        setTitle("在线聊天登录框");
        getContentPane().setLayout(null);
        setBounds(100, 100, 427, 301);// 注册时高度为578,不注册是301

        // 设置窗口居中
        this.setLocation(Center.getPoint(this.getSize()));

        final JButton button_1 = new JButton();
        button_1.setText("登录");
        button_1.setBounds(230, 222, 106, 36);
        getContentPane().add(button_1);

        final JTextField textField_1 = new JTextField();
        textField_1.setBounds(148, 90, 192, 42);
        getContentPane().add(textField_1);

        final JLabel label = new JLabel();
        label.setText("帐    号");
        label.setBounds(76, 102, 66, 18);
        getContentPane().add(label);

        final JLabel label_1 = new JLabel();
        label_1.setText("密    码");
        label_1.setBounds(76, 167, 66, 18);
        getContentPane().add(label_1);

        final JPasswordField passwordField = new JPasswordField();
        passwordField.setBounds(148, 155, 192, 42);
        getContentPane().add(passwordField);

        final JButton button = new JButton();
        button.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                if (LoginDialog.this.getHeight() == 301) {
                    LoginDialog.this.setSize(427, 578);
                } else {
                    LoginDialog.this.setSize(427, 301);
                }
                // 设置窗口不断居中
                LoginDialog.this.setLocation(Center.getPoint(LoginDialog.this.getSize()));
            }
        });
        button.setText("注册");
        button.setBounds(76, 222, 106, 36);
        getContentPane().add(button);

        final JPanel panel = new JPanel();
        panel.setLayout(null);
        panel.setBorder(new TitledBorder(null, "注册用户", TitledBorder.DEFAULT_JUSTIFICATION,
                TitledBorder.DEFAULT_POSITION, null, null));
        panel.setBounds(10, 278, 401, 226);
        getContentPane().add(panel);

        final JLabel label_2 = new JLabel();
        label_2.setBounds(44, 41, 65, 18);
        label_2.setText("手机号:");
        panel.add(label_2);

        textField = new JTextField();
        textField.setBounds(115, 35, 225, 30);
        panel.add(textField);

        final JButton button_2 = new JButton();
        button_2.setText("发送验证");
        button_2.setBounds(243, 75, 97, 30);
        panel.add(button_2);

        textField_2 = new JTextField();
        textField_2.setBounds(115, 104, 95, 30);
        panel.add(textField_2);

        final JLabel label_3 = new JLabel();
        label_3.setText("验证码:");
        label_3.setBounds(44, 110, 65, 18);
        panel.add(label_3);

        passwordField_1 = new JPasswordField();
        passwordField_1.setBounds(115, 143, 231, 30);
        panel.add(passwordField_1);

        passwordField_2 = new JPasswordField();
        passwordField_2.setBounds(115, 175, 231, 30);
        panel.add(passwordField_2);

        final JLabel label_4 = new JLabel();
        label_4.setText("密        码:");
        label_4.setBounds(44, 149, 65, 18);
        panel.add(label_4);

        final JLabel label_5 = new JLabel();
        label_5.setText("验证密码:");
        label_5.setBounds(44, 181, 65, 18);
        panel.add(label_5);

        final JButton button_3 = new JButton();
        button_3.setBounds(47, 510, 97, 30);
        getContentPane().add(button_3);
        button_3.setText("放弃");

        final JButton button_4 = new JButton();
        button_4.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {

                String phone = textField.getText();
                String password = null;
                String str1=new String(passwordField_1.getPassword()).trim();
                String str2=new String(passwordField_2.getPassword()).trim();

                if (str1.equals(str2)) {
                    password = new String(passwordField_2.getPassword()).trim();
                } else {
                    System.out.println("输入密码不一致...");
                    System.exit(0);
                }
                try {
                    dos.writeUTF(phone);
                    dos.writeUTF(password);
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        });

        button_4.setBounds(262, 510, 97, 30);
        getContentPane().add(button_4);
        button_4.setText("注册用户");

        connect();
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                disconnect();
            }
        });
    }

    public void connect() {
        try {
            s = new Socket("127.0.0.1", 8888);
            System.out.println("一个客户端登陆中....!");
            dos = new DataOutputStream(s.getOutputStream());
            dis = new DataInputStream(s.getInputStream());

        } catch (ConnectException e) {
            System.out.println("服务端异常.........");
            System.out.println("请确认服务端是否开启.........");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void disconnect() {
        try {
            if (dos != null)
                dos.close();
            if (s != null)
                s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

服务端要经受客户端上陆窗发来之手机号码和密码

下一场用信息由包改成User,通过DBAdd.add(user)添加进数据库

树一个LoginServer类,负责接信息和添加进数据库

切实代码如下:

package com.swift;


import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;

import com.swift.jdbc.DBAdd;
import com.swift.jdbc.User;

public class LoginServer {

    boolean started = false;
    ServerSocket ss = null;
    Socket s = null;

    public static void main(String[] args) {
        new LoginServer().fun();
    }

    private void fun() {
        try {
            ss = new ServerSocket(8888);
            started = true;
        } catch (BindException e) {
            System.out.println("端口使用中......");
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        try {
            while (started) {
                s = ss.accept();
                System.out.println("a client connected success");
                Client c = new Client(s);
                new Thread(c).start();
            }
        } catch (EOFException e) {
            System.out.println("client has closed.");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                ss.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    class Client implements Runnable {

        private Socket s;
        private DataInputStream dis;
        private DataOutputStream dos;
        private boolean connected = false;

        public Client(Socket s) {
            this.s = s;
            try {
                this.dis = new DataInputStream(s.getInputStream());
                this.dos = new DataOutputStream(s.getOutputStream());
                connected = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void run() {
            try {//注意:要包括while循环,如果try在while循环里,则出现socket closed异常
                while (connected) {
                    String phone = dis.readUTF();
                    String password = dis.readUTF();

                    System.out.println(phone);
                    System.out.println(password);

                    User user=new User(phone,password);
                    DBAdd.add(user);
                }
            } catch(SocketException e) {
                System.out.println("一个登陆窗已经关闭....");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                  if (s != null) {
                      try {
                          s.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
                if (dis != null) {
                    try {
                        dis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if(dos!=null) {
                    try {
                        dos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

        }

    }
}

效果图:

开辟多独登陆窗口,分别登记用户后关门,服务端提示信息如下:

图片 4

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注