TCP服务器和客户端学生管理系统(第一天)
一,工具类(util包中)第二天有补充
1.1 资源管理close工具类
package com.qfedu.student.system.client.util;
import java.io.Closeable;
import java.io.IOException;
/**
* 资源管理Close工具类
*
* @author Anonymous 2020/3/17 14:33
*/
public class CloseUtil {
/**
* 可以调用close方法的类都可以使用
*
* @param res 不定长参数Closeable接口实现类,处理资源关闭问题
*/
public static void closeAll(Closeable... res) {
for (Closeable re : res) {
try {
if (re != null) {
re.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
1.2 Json数据格式操作工具类
package com.qfedu.student.system.client.util;
import com.alibaba.fastjson.JSON;
import com.qfedu.student.system.client.entity.Student;
import java.util.List;
/**
* Json数据格式操作工具类
*
*
* 服务器和客户端直接的数据交互方式
* 3. 解析Json格式数据 ==> Object
* 4. Object ==> 转换为Json格式数据
* 5. 解析Json格式数据 ==> List<Object>
* 6. List<Object> ==> 转换为Json格式数据
*
* @author Anonymous 2020/3/17 11:31
*/
public class JsonUtil {
/**
* Json字符串转换成对应Student类对象
*
* @param jsonString Json格式字符串
* @return Student类对象
*/
public static Student jsonToStudent(String jsonString) {
return JSON.parseObject(jsonString, Student.class);
}
/**
* Student类对象转换成Json格式字符串
*
* @param student Student类对象数据
* @return 符合Json格式的String类型字符串
*/
public static String studentToJson(Student student) {
return JSON.toJSONString(student);
}
/**
* Json格式字符串转换成保存Student类型的List集合
*
* @param jsonString Json格式字符串
* @return 保存Student类型List集合
*/
public static List<Student> jsonToStudentList(String jsonString) {
return JSON.parseArray(jsonString, Student.class);
}
/**
* 保存Student类型的List集合转换成一个Json格式字符串
*
* @param list 保存Student类型的List集合
* @return Json格式字符串
*/
public static String studentListToJson(List<Student> list) {
return JSON.toJSONString(list);
}
}
二,Student实体类(entity包中)
严格按照JavaBean规范实现
1. 所有成员变量全部私有化
2. 必须提供一个无参数构造方法
3. 完成对应成员变量的setter和getter
4. 这里建议使用【包装类】
代码演示
package com.qfedu.student.system.client.entity;
/**
* Student实体类,要求符合JavaBean规范
* 对象关系映射(Object Relational Mapping) ORM
* Object Java中的任何一个对象 保存映射到对应的 数据保存 ==> 文件 XML JSON Database
*
* @author Anonymous 2020/3/17 10:00
*/
public class Student {
private Integer id;
private String name;
private Boolean gender;
private Integer age;
private Integer mathScore;
private Integer chnScore;
private Integer engScore;
private Integer totalScore;
private Integer rank;
public Student() {
}
public Student(Integer id, String name, Boolean gender, Integer age, Integer mathScore, Integer chnScore, Integer engScore, Integer totalScore, Integer rank) {
this.id = id;
this.name = name;
this.gender = gender;
this.age = age;
this.mathScore = mathScore;
this.chnScore = chnScore;
this.engScore = engScore;
this.totalScore = totalScore;
this.rank = rank;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getGender() {
return gender;
}
public void setGender(Boolean gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getMathScore() {
return mathScore;
}
public void setMathScore(Integer mathScore) {
this.mathScore = mathScore;
}
public Integer getChnScore() {
return chnScore;
}
public void setChnScore(Integer chnScore) {
this.chnScore = chnScore;
}
public Integer getEngScore() {
return engScore;
}
public void setEngScore(Integer engScore) {
this.engScore = engScore;
}
public Integer getTotalScore() {
return totalScore;
}
public void setTotalScore(Integer totalScore) {
this.totalScore = totalScore;
}
public Integer getRank() {
return rank;
}
public void setRank(Integer rank) {
this.rank = rank;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", gender=" + gender +
", age=" + age +
", mathScore=" + mathScore +
", chnScore=" + chnScore +
", engScore=" + engScore +
", totalScore=" + totalScore +
", rank=" + rank +
'}';
}
}
三,服务端(server包中)
3.1 保存对应路径对应地址(anno包中)
package com.qfedu.student.system.server.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Anonymous 2020/3/17 11:36
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface FilePathAnnotation {
/**
* 保存文件路径对应地址
*
* @return String保存文件路径地址
*/
String filePath();
}
3.2 使用ArrayList存储对应的Student信息,完成增删改查操作(dao包中)
package com.qfedu.student.system.server.dao;
import com.qfedu.student.system.server.entity.Student;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;
/**
* 使用ArrayList存储对应的Student信息,完成CRUD操作
*
* 【单例模式引入】
* 整个服务器代码中保存操作数据内容是StudentDao,要求有且只有一个类对象,
* 保障数据操作的安全性!!!使用单例模式【懒汉,饿汉你随便】
*
* @author Anonymous 2020/3/17 10:00
*/
public class StudentDao {
/**
* 保存所有学生信息的ArrayList集合
*/
private ArrayList<Student> allStudents = null;
/**
* 保存StudentDao创建的空间首地址
*/
private static StudentDao studentDao = null;
/**
* 私有化构造方法
*/
private StudentDao() {
allStudents = new ArrayList<>();
}
/**
* 获取当前StudentDao类对象的静态方法
*
* @return StudentDao类对象,并且是一个单例对象
*/
public synchronized static StudentDao getInstance() {
if (null == studentDao) {
studentDao = new StudentDao();
}
return studentDao;
}
/**
* 添加Student类对象到ArrayList中
*
* @param student Student类对象
* @return 添加成功返回true,否则返回false
*/
public boolean add(Student student) {
return allStudents.add(student);
}
/**
* 根据指定ID删除对应的Student类对象
*
* @param id 指定的ID
* @return 删除操作成功返回Student类型对象,操作失败返回null
*/
public Student remove(Integer id) {
int index = getIndexById(id);
Student stu = null;
if (index > -1) {
stu = allStudents.remove(index);
}
return stu;
}
/**
* 根据指定的ID获取对应的Student类对象
*
* @param id 指定ID号
* @return 返回对应Student类对象,如果没有找到,返回null
*/
public Student getStudentById(Integer id) {
int index = getIndexById(id);
Student stu = null;
if (index > -1) {
stu = allStudents.get(index);
}
return stu;
}
/**
* 修改对应ID的Student类对象
*
* @param id 指定的ID号
* @param student 客户端修改数据之后发送的Student类对象
*/
public void modifyStudent(Integer id, Student student) {
int index = getIndexById(id);
allStudents.set(index, student);
}
/**
* 根据Comparator函数式接口规范的要求排序Student数据,返回值是排序完成的Student
* 数组,用户客户端展示
*
* @param comparator Comparator函数式接口
* @return 排序完成的Student数组
*/
public Student[] sortUsingCompara(Comparator<Student> comparator) {
Student[] students = new Student[allStudents.size()];
// 从ArrayList中取出所有的Student对象,保存到Student数组中
for (int i = 0; i < students.length; i++) {
students[i] = allStudents.get(i);
}
// Arrays工具类,调用sort方法吗,排序Student数组,使用Comparator函数式接口
// 完成排序规则的约束
Arrays.sort(students, comparator);
// 排序完成的数组返回到方法之外,用户客户端展示
return students;
}
/**
* 过滤方法,使用函数式接口Predicate对象,使用test方法约束过滤条件
* 返回值是List集合,里面存储的是符合要求的Student对象
*
* @param predicate Predicate函数式接口作为过滤条件
* @return 如果过滤之后存在结果,返回List<Student>集合,
* 如果没有任何数据,返回null
*/
public List<Student> filter(Predicate<Student> predicate) {
ArrayList<Student> list = new ArrayList<>();
// 遍历整个ArrayList,过滤条件
for (Student student : allStudents) {
// 使用Predicate函数式接口中的test方法,做过滤条件
if (predicate.test(student)) {
list.add(student);
}
}
return list.size() > 0 ? list : null;
}
/**
* 类内私有化方法,获取指定ID对应的下标位置
*
* @param id 指定ID号
* @return 对应当前ID Student类对象所处的下标位置,没有找到返回-1
*/
private int getIndexById(Integer id) {
int index = -1;
for (int i = 0; i < allStudents.size(); i++) {
if (id.equals(allStudents.get(i).getId())) {
index = i;
break;
}
}
return index;
}
/**
* 返回当前StudentDao中保存数据ArrayList对象
*
* @return 保存所有Student数据的ArrayList对象
*/
public ArrayList<Student> getAllStudents() {
return allStudents;
}
}
四,客户端(client包中)
4.1 客户端控制层 客户端功能 <> 数据交互 <> 服务器(controller包中)第二天有补充
package com.qfedu.student.system.client.controller;
import com.qfedu.student.system.client.service.ClientService;
import com.qfedu.student.system.client.tcp.ClientTcp;
/**
* 客户端控制层
* 客户端功能 <==> 数据交互 <==> 服务器
*
* @author Anonymous 2020/3/17 15:23
*/
public clas*s ClientController {
private ClientService service = new ClientService();
/**
* 客户端Add方法
*/
public void addStudent() {
// 从客户端功能中呼气一个Student数据对应的JsonString
String studentJsonString = service.getStudent();
// 服务器执行的方法 addStudent方法 String
// 服务器端 addStudent(String jsonString)
// addStudent:{"age":16,"chnScore":100,"engScore":100,"gender":false,"id":1,"mathScore":100,"name":"骚磊","rank":1,"totalScore":300}
String message = "addStudent:" + studentJsonString;
ClientTcp.Send(message);
}
public void removeStudent() {
int id = 0;
String message = "deleteByteId:" + id;
ClientTcp.Send(message);
}
}
4.2 客户端TCP(tcp包中)第二天有补充
package com.qfedu.student.system.client.tcp;
/**
* @author Anonymous 2020/3/17 10:01
*/
public class ClientTcp {
public static String receive() {
return "";
}
public static void Send(String jsonString) {
}
}
4.3 客户端可以执行的操作(service包中)第二天有补充
package com.qfedu.student.system.client.service;
import com.qfedu.student.system.client.entity.Student;
import com.qfedu.student.system.client.util.JsonUtil;
import java.util.List;
import java.util.Scanner;
/**
* 客户端可以执行的操作
*
* @author Anonymous 2020/3/17 15:55
*/
public class ClientService {
private static Scanner sc = new Scanner(System.in);
/**
* 添加学生信息,到服务器
*
* @return Student数据对应的Json格式字符串
*/
public String getStudent() {
System.out.println("请输入学生的姓名:");
String name = sc.nextLine();
System.out.println("请输入学生的年龄:");
Integer age = sc.nextInt();
System.out.println("请输入学生的性别 男 或者 女:");
Boolean gender = sc.nextLine().charAt(0) != '男';
System.out.println("请输入学生的语文成绩:");
Integer chnScore = sc.nextInt();
System.out.println("请输入学生的数学成绩:");
Integer mathScore = sc.nextInt();
System.out.println("请输入学生的英语成绩:");
Integer engScore = sc.nextInt();
Integer totalScore = chnScore + mathScore + engScore;
Student student = new Student(0, name, gender, age, mathScore, chnScore, engScore, totalScore, 0);
return JsonUtil.studentToJson(student);
}
/**
* 展示Json格式数据对应的保存Student数据List集合,
* 可以用到展示所有学生,排序结果,过滤数据结果
*
* @param jsonString 包含所有学生数据的Json格式字符串
*/
public void showStudentList(String jsonString) {
List<Student> students = JsonUtil.jsonToStudentList(jsonString);
for (Student student : students) {
System.out.println(student);
}
}
/**
* 展示指定学生信息
*
* @param jsonString Json格式字符串
*/
public void showStudent(String jsonString) {
Student student = JsonUtil.jsonToStudent(jsonString);
System.out.println(student);
}
/**
* 修改指定学生信息
*
* @param jsonString 对应Json格式字符串
* @return 修改之后的学生信息Json格式字符串
*/
public String modifyStudent(String jsonString) {
// 转换成对应的Student类型
Student student = JsonUtil.jsonToStudent(jsonString);
int choose = 0;
boolean flag = false;
while (true) {
System.out.println("ID: " + student.getId() + " Name: " + student.getName());
System.out.println("Age: " + student.getAge() + " Gender: " + (student.getGender() ? "女" : "男"));
System.out.println("chnScore: " + student.getChnScore() + " mathScore: " + student.getMathScore());
System.out.println("engScore: " + student.getEngScore() + " TotalScore: " + student.getTotalScore());
System.out.println("Rank: " + student.getRank());
System.out.println("1. 修改学生姓名:");
System.out.println("2. 修改学生年龄:");
System.out.println("3. 修改学生性别:");
System.out.println("4. 修改学生语文成绩:");
System.out.println("5. 修改学生数学成绩:");
System.out.println("6. 修改学生英语成绩:");
System.out.println("7. 退出");
choose = sc.nextInt();
sc.nextLine();
switch (choose) {
case 1:
System.out.println("请输入学生的名字:");
String name = sc.nextLine();
student.setName(name);
break;
case 2:
System.out.println("请输入学生的年龄:");
Integer age = sc.nextInt();
student.setAge(age);
break;
case 3:
System.out.println("请输入学生的性别 男 或者 女:");
Boolean gender = sc.nextLine().charAt(0) != '男';
student.setGender(gender);
break;
case 4:
System.out.println("请输入学生的语文成绩:");
Integer chnScore = sc.nextInt();
// 修改总分,获取原总分 + 当前语文成绩 - 原语文成绩
student.setTotalScore(student.getTotalScore() + chnScore - student.getChnScore());
student.setChnScore(chnScore);
break;
case 5:
System.out.println("请输入学生的数学成绩:");
Integer mathScore = sc.nextInt();
student.setTotalScore(student.getTotalScore() + mathScore - student.getMathScore());
student.setMathScore(mathScore);
break;
case 6:
System.out.println("请输入学生的英语成绩:");
Integer engScore = sc.nextInt();
student.setTotalScore(student.getTotalScore() + engScore - student.getEngScore());
student.setEngScore(engScore);
break;
case 7:
flag = true;
break;
default:
System.out.println("选择错误");
break;
}
// 退出标记
if (flag) {
// 退出while true循环
break;
}
}
// 讲修改之后的Student信息,转换成一个Json格式字符串返回
return JsonUtil.studentToJson(student);
}
}