Java多线程+网络编程登录验证管理实例

该博客介绍了一个使用Java实现的多线程网络编程登录管理系统。用户分为管理员和普通用户,服务器端采用多线程处理登录请求。用户通过客户端发送登录信息,服务器验证后返回登录结果。代码包括Bean、ResponseBody、User、Dao、View、Controller各层的实现,并展示了客户端和服务器端的交互过程。
摘要由CSDN通过智能技术生成

Java多线程+网络编程登录管理实例

用户包含管理员和普通用户两个角色进行测试。
假定:管理员用户名:admin,密码:abc 普通用户名:user 密码:123

  • 用户从客户端发起登录请求,客户端将数据传递到服务器端,由服务器做验证。服务器端保存用户数据。用户登录成功提示登录成功,并显示功能模块,登录失败提示:用户名或密码不正确。
  • 在服务器端启用多线程模式,要求:每一个用户发送登录请求到服务器后,服务器端就分配一个线程去处理这个请求。以实现服务器端多线程模式下的用户登录。

代码实现:

Bean层

1、RequestBody类请求体继承Serializable:

/**
 * 请求体
 */
public class RequestBody implements Serializable {
    public static final String LOGIN = "login";//登陆的功能模块
    private static final long serialVersionUID = -1593966669454243804L;
    private String cmd;//需要操作的功能
    private User user;//操作的对象

    public String getCmd() {
        return cmd;
    }

    public void setCmd(String cmd) {
        this.cmd = cmd;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

ResponseBody类响应体继承Serializable

/**
 * 响应体
 */
public class ResponseBody implements Serializable {

    private static final long serialVersionUID = -6315166158520343036L;

    private int result;//响应的结果

    private String status;//响应的状态
    private boolean ok;//是否登陆成功的状态

    public int getResult() {
        return result;
    }

    public void setResult(int result) {
        this.result = result;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public boolean isOk() {
        return ok;
    }

    public void setOk(boolean ok) {
        this.ok = ok;
    }
}

User登录者类

public class User implements Serializable {

    private static final long serialVersionUID = 3646073779387514873L;

    private String username,password;//登陆的用户的用户名和密码

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

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

    //两个对象是否重复
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(username, user.username) &&
                Objects.equals(password, user.password);
    }

    @Override
    public int hashCode() {
        return Objects.hash(username, password);
    }
}

Dao层

UserDao类数据层

public class UserDao {

    public static final int ADMIN_SUCCESS = 1;//管理员
    public static final int USER_SUCCESS = 2;//普通用户
    public static final int LOGIN_FAIL = 3;//退出

    private HashMap<User, Integer> map = new HashMap<>();//存放是管理员还是用户的
    //初始化集合中的信息
    {
        map.put(new User("admin", "abc"), ADMIN_SUCCESS);
        map.put(new User("user", "123"), USER_SUCCESS);
    }
    //登陆的方法
    public int login(User user) {
        System.out.println(user);
        Integer loginResult = map.get(user);//通过键获取对应的值
        System.out.println(loginResult);//输出键对应的值
        return loginResult == null ? LOGIN_FAIL : loginResult;//输出对应的管理员和用户的选择的编号
    }
}

View层

Views类视图层,展示菜单以及键值输入等提示信息

public class Views {
    //输入的变量的对象
    private Scanner sc = new Scanner(System.in);
    //简单的提示信息
    public void welcome() {
        System.out.println("欢迎使用网络版-快递e栈");
    }
    //选择的变量
    public void showMainMenu() {
        System.out.println("请选择:1.登录,2.离开");
    }
    //选择对应的编号
    public int inputKey(int max) {
        int num = 1;
        System.out.println("请输入1~" + max + "的数字:");
        String str = sc.nextLine();
        try {
            num = Integer.parseInt(str);
        } catch (NumberFormatException e) {

        }
        //输入的数字是否是1到max之间的
        if (num < 1 || num > max) {
            num = inputKey(max);//如果不是的话,重新调用方法,在重新输入一次
        }
        return num;//在1到max之间的,就直接返回对应的数字

    }
    //简单的提示信息
    public void bye() {
        System.out.println("谢谢使用,再见!");
    }

    //输入的对应的用户名和密码
    public User inputUser() {

        String username = inputStr("请输入用户名:");
        String password = inputStr("请输入密码:");
        return new User(username, password);//返回user对象
    }
    //输入的字符串的信息
    private String inputStr(String cmd) {
        System.out.println(cmd);
        return sc.nextLine();
    }
    //提示登陆失败的信息
    public void loginFail() {
        System.out.println("登录失败!");
    }
}

Controller层

Client类客户端

public class Client {

    public int login(User user) throws IOException, ClassNotFoundException {
        //创建客户端端,一个是连接的ip地址,一个是端口号
        Socket socket=new Socket("127.0.0.1",12345);
        //创建请求的对象
        RequestBody body=new RequestBody();
        //设置请求的功能模块
        body.setCmd(RequestBody.LOGIN);
        body.setUser(user);//设置输入的信息
        //写入请求的对象,和请求的内容
        writeRequest(socket, body);
        //设置响应的对象
        ResponseBody responseBody = getResponseBody(socket);
        socket.close();//释放客户端资源
        return responseBody.getResult();//获取响应的内容
    }
    //获取响应体
    private ResponseBody getResponseBody(Socket socket) throws IOException, ClassNotFoundException {
        ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
        return (ResponseBody) ois.readObject();
    }

    private void writeRequest(Socket socket, RequestBody body) throws IOException {
        ObjectOutputStream oos=new ObjectOutputStream(socket.getOutputStream());
        oos.writeObject(body);
    }
}

Server服务器端

public class Server {
    //数据的操作
    private static UserDao userDao=new UserDao();
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //创建服务器对象。端口号一定要和客户端的端口号一致
        ServerSocket ss=new ServerSocket(12345);
        while (true) {
            //获取客户端连接对象
            Socket socket = ss.accept();
            //创建一个多线程
            new Thread(() -> {
                try {
                    //执行响应的登陆的模块
                    handleSocket(socket);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }).start();//开启线程
        }
    }

    private static void handleSocket(Socket socket) throws IOException, ClassNotFoundException {
        //获取一下请求的内容
        RequestBody requestBody = getRequestBody(socket);
       // 判断请求的内容是不是对应的模块
        switch (requestBody.getCmd()){
            case RequestBody.LOGIN:
                loginUser(socket,requestBody);
//                case ....
                break;
        }
    }
    //登陆方法
    private static void loginUser(Socket socket,RequestBody requestBody) throws IOException {
       //获取请求的user对象
        User user = requestBody.getUser();
        //管理员还是用户
        int result=userDao.login(user);
        //创建响应的内容对象
        ResponseBody body=new ResponseBody();
        //设置响应的结果 管理员还是客户端
        body.setResult(result);
        //写入对象
        writeResponse(socket, body);

    }
    //写响应的内
    private static void writeResponse(Socket socket, ResponseBody body) throws IOException {
        ObjectOutputStream oos=new ObjectOutputStream(socket.getOutputStream());
        oos.writeObject(body);
    }

    private static RequestBody getRequestBody(Socket socket) throws IOException, ClassNotFoundException {
        ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
        return (RequestBody) ois.readObject();
    }
}

Main

public class Main {
    //整个程序的流程控制
    static Views v = new Views();
    static Client c = new Client();

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        v.welcome();
        //1.登录2.离开
        boolean flag = true;
        while (flag) {
            v.showMainMenu();
            int key = v.inputKey(2);
            switch (key) {
                case 1:
                    loginUser();
                    break;
                case 2:
                    v.bye();
                    flag = false;
                    break;
            }
        }
    }

    private static void loginUser() throws IOException, ClassNotFoundException {
        User user = v.inputUser();//获取输入的用户对象
        int login = c.login(user);//通过对象判断管理员还是用户
        switch (login) {
            case UserDao
                    .ADMIN_SUCCESS:
                adminLoop();
                break;
            case UserDao.USER_SUCCESS:
                userLoop();
                break;
            case UserDao.LOGIN_FAIL:
                    v.loginFail();
                break;
        }
    }

    private static void userLoop() {
        System.out.println("用户的操作");
    }

    private static void adminLoop() {
        System.out.println("管理员操作");
    }
}

测试结果:

  • Main客户端:
欢迎使用网络版-快递e栈
请选择:1.登录,2.离开
请输入1~2的数字:
1
请输入用户名:
admin
请输入密码:
abc
管理员操作
请选择:1.登录,2.离开
请输入1~2的数字:
1
请输入用户名:
user
请输入密码:
123
用户的操作

  • Server服务器端
User{username='admin', password='abc'}
1
User{username='user', password='123'}
2

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

12点前就睡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值