0%

Java-39-搭建一个简易的用户登录系统

项目实现要求

  • 编写客户端和服务器代码,要求客户端和服务器进行对象的传输交流。
  • 要求服务器支持同时多个客户端访问。
  • 并且客户端能够使用多个账号进行登录。
  • 客户端和服务器接收到对方的请求时,都给予对方响应内容。
  • 密码输入错误后支持用户重新输入。

项目思考

  1. 首先要想去验证用户登录,就需要去构建一个用户类,这个用户类有账号和密码两个属性,为了方便验证登录效果(即比对账号和密码)还需要去重写equals方法。同时为了使得这个对象能够被序列化和反序列化,还需要去实现Serializable接口。
  2. 服务器想要支持多个客户端访问,就需要使用到多线程技术。
  3. 想要获取用户输入的账号和密码,还需要使用到Scanner类中的next()方法。
  4. 客户端想要实现多个账号进行登录,就需要提前将账号和密码信息填入到本地文件。

项目实现

本地账号文件user.txt

1
2
3
4
5
zhangsan-123456
lisi-321654
wangwu-888888
zhaoliu-666666

用户类User:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.tipdm.demo7;

import java.io.Serializable;
import java.util.Objects;

public class User implements Serializable {
private String userAccount;
private String userPassword;

public User() {
}

public User(String userAccount, String userPassword) {
this.userAccount = userAccount;
this.userPassword = userPassword;
}

@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(userAccount, user.userAccount) && Objects.equals(userPassword, user.userPassword);
}

@Override
public int hashCode() {
return Objects.hash(userAccount, userPassword);
}

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

public String getUserAccount() {
return userAccount;
}

public void setUserAccount(String userAccount) {
this.userAccount = userAccount;
}

public String getUserPassword() {
return userPassword;
}

public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
}

用户功能类UserService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.tipdm.demo7;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class UserService {
public boolean checkLogin(User user){
boolean login_flag = false;
List<User> allUser = getAllUser();
for (User currUser:
allUser) {
if (user.equals(currUser)){
login_flag = true;
break;
}
}
return login_flag;
}

public List<User> getAllUser(){
List <User> allUser = new ArrayList<>();
File file = new File("day10-code\\user.txt");
try {
BufferedReader br = new BufferedReader(new FileReader(file));
while (true){
String str = br.readLine();
if (str == null){
break;
}
String[] data = str.split("-");
User user = new User(data[0], data[1]);
allUser.add(user);
}

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

客户端类TestClient

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.tipdm.demo7;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class TestClient {
public static void main(String[] args) {
while (true) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入用户名:");
String account = scanner.next();
System.out.print("请输入密码:");
String password = scanner.next();
User user = new User(account, password);

try {
Socket socket = new Socket("localhost", 7878);
ObjectOutputStream oo = new ObjectOutputStream(socket.getOutputStream());
oo.writeObject(user);
oo.flush();
socket.shutdownOutput();

BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = br.readLine();
System.out.println("你好服务器,这里是客户端,我收到了你的响应信息。我登录请求状态是:" + str);
br.close();
socket.close();
if (str.equals("true")){
System.out.println("登录成功!");
break;
}
System.out.println("===== 登录失败,请重新登录!=====");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

服务器线程类ServerThread

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.tipdm.demo7;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class ServerThread extends Thread{
private Socket socket;

public ServerThread() {
}

public ServerThread(Socket socket) {
this.socket = socket;
}

@Override
public void run() {
try {
ObjectInputStream oi = new ObjectInputStream(this.socket.getInputStream());
User user = (User) oi.readObject();
UserService us = new UserService();
boolean login_glag = us.checkLogin(user);
if (login_glag){
System.out.println(user.getUserAccount() + "登录成功");
}else {
System.out.println(user.getUserAccount() + "登录失败");
}
this.socket.shutdownInput();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream()));
bw.write("" + login_glag);
bw.flush();
bw.close();
this.socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

服务器类TestServer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.tipdm.demo7;

import java.net.ServerSocket;
import java.net.Socket;

public class TestServer {
public static void main(String[] args) {
System.out.println("====== 登录测试 =====");
try {
ServerSocket serverSocket = new ServerSocket(7878);
while (true){
Socket socket = serverSocket.accept();
ServerThread serverThread = new ServerThread(socket);
serverThread.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

测试效果

  • 启动服务器

image-20230622215630581

  • 启动客户端

image-20230622215644273

  • 接下来输入一个错误的账号和密码

image-20230622215718676

  • 登录失败,并且让用户重新登录,服务器也会打印登录失败信息。

image-20230622215850618

  • 解析来输入一个正确的账号和密码

image-20230622215920499

  • 客户端登录成功,正常退出程序。服务器端打印登录成功信息。

image-20230622215952974

  • 接下来演示登录其他账号。

    • 客户端

    image-20230622220023257

    • 服务器

    image-20230622220146063

多账号登录测试成功,完成需求。

-------------本文结束感谢您的阅读-------------