Java - 快递管理系统的优化(把需要存储的数据都存储在服务器中)

快递管理系统 - 数据存储在服务器端

还记得之前的快递管理系统吗,现在把需要存储的数据都存储在服务器中,客户端后续只用来收集用户的操作,为了确保服务器能同时连接多个客户端,记得在服务器引入多线程技术。
代码:

1.Express类

这一个类生成对应的get/set方法,需要注意的就是实现可序列化接口(implements Serializable)、生成单独的单号(number)的eqauls()方法,因为后续的修改、删除快递操作是以单号未基础进行的

/**
 * @Author:彭德华
 * @Description:Express类
 * @Date Created in  2020-10-4 13:40
 * @Modified By:
 */
 public class Express implements Serializable {
    //取件码
    private int code;
    //单号
    private String number;
    //公司
    private String company;
    //电话号码
    private String phone;
    //柜子行列
    private int box;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Express1 express1 = (Express1) o;
        return Objects.equals(number, express1.number);
    }

    @Override
    public int hashCode() {
        return Objects.hash(number);
    }

    //构造方法
    public Express() {
    }
    public Express(int code, String number, String company, String phone,int box) {
        this.code = code;
        this.number = number;
        this.company = company;
        this.phone = phone;
        this.box = box;
    }

    public int getCode() {
        return code;
    }

    public String getNumber() {
        return number;
    }

    public String getCompany() {
        return company;
    }

    public String getPhone() {
        return phone;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public void setPhone(String phone){
        this.phone = phone;
    }

    public int getBox() {
        return box;
    }

    public void setBox(int y) {
        this.box = box;
    }

    @Override
    public String toString() {
        return "Express1{" +
                "code=" + code +
                ", number='" + number + '\'' +
                ", company='" + company + '\'' +
                ", phone='" + phone + '\'' +
                ", 快递在第"+ box +
                "号柜"+
                '}';
    }
}

2.Function类

这一类就是功能类,包括了程序使用到的大部分方法,是项目的核心类。需要注意的就是对在载入数据时(序列化技术)对文件的处理,载入数据详细分析我 这一篇博客有提到

/**
 * @Author:彭德华
 * @Description:Function类,实现增加、删除、查看、修改、取出的功能
 * @Date Created in  2020-10-4 13:52
 * @Modified By:
 */
public class Function extends Express {
    // 生成6位取件码
    // 需要传入快递信息的集合,用于判断该取件码是否存在,避免重复
    public int addCode(ArrayList<Express> arrayList) {
        Random random = new Random();
        int code = -1;
        // 判断是否有快递信息
        if (arrayList.size() > 0) {
            while (true) {
                // 随机六位取件码
                code = random.nextInt(900000) + 100000;
                for (Express e : arrayList) {
                    if (e.getCode() != code) {// 取件码不存在
                        //return直接结束addCode()方法
                        return code;
                    }
                }
            }
        }
        // 没有快递信息
        code = random.nextInt(900000) + 100000;
        return code;
    }

    // 设置快递柜号,范围1-100
    // 需要传入快递信息的集合,用于判断该柜号是否被占用,避免重复
    public int addBox(ArrayList<Express> arrayList) {
        Random random = new Random();
        int box;
        if (arrayList.size() > 0) {
            while (true) {
                box = random.nextInt(100) + 1;
                for (Express1 e : arrayList) {
                    if (e.getBox() != box) {
                        // 该位置无快递
                        return box;
                    }
                }
            }
        }
        box = random.nextInt(100) + 1;
        return box;
    }

    // 录入快递
    // 需要传入快递信息集合
    public ArrayList<Express> addExpress(ArrayList<Express> arrayList) {
        Scanner input = new Scanner(System.in);
        //全局使用.nextLine()接受数据,会避免输入后Enter键带来的bug
        System.out.println("输入快递公司");
        String company = input.nextLine();
        System.out.println("输入快递单号");
        String number = input.nextLine();
        System.out.println("输入手机号");
        String phone = input.nextLine();
        // 随机产生取件码,不能重复
        int code = addCode(arrayList);
        // 生成柜号,不能重复
        int box = addBox(arrayList);
        Express1 express = new Express(code,number,company,phone,box);
        arrayList.add(express);
        // 返回集合
        return arrayList;
    }

    //取出快递
    //需要传入取件码,用于查找快递
    public StringBuffer take(int code) throws IOException {
        StringBuffer text = new StringBuffer();
        Function m = new Function();
        ArrayList<Express> list= m.load();
        // 遍历查找需要取出的快递
        for (Express e : list) {
            if (e.getCode() == code){
                // 输出快递位置,和快递信息
                text.append(e.toString());
                // 删除快递
                list.remove(e);
                // 存储信息
                m.store(list);
                // 返回快递信息
                return text;
            }
        }
        return null;
    }

    // 删除快递
    // 需要传入快递单号,用于查找快递
    public StringBuffer delete(String number) throws IOException {
        StringBuffer text = new StringBuffer();
        Function m = new Function();
        ArrayList<Express> list= m.load();
        // 遍历查找需要取出的快递
        for (Express e : list) {
            if (e.getNumber().equals(number)){
                // 输出快递位置,和快递信息
                text.append(e.toString());
                // 删除快递
                list.remove(e);
                // 存储信息
                m.store(list);
                // 返回快递信息
                return text;
            }
        }
        return null;
    }

    //修改快递
    //需要传入快递单号,用于查找快递
    public StringBuffer change(String number) throws IOException {
        StringBuffer text = new StringBuffer();
        Function m = new Function();
        ArrayList<Express> list= m.load();
        // 遍历查找需要取出的快递
        for (Express e : list) {
            if (e.getNumber().equals(number)){
                // 输出快递位置,和快递信息
                text.append(e.toString());
                // 删除快递
                list.remove(e);
                // 存储信息
                m.store(list);
                // 返回快递信息
                return text;
            }
        }
        return null;
    }

    //载入数据
    //注意一定要避免载入错误
    public ArrayList<Express> load() throws IOException {
        ArrayList<Express> arrayList = new ArrayList<>();
        try {
            FileInputStream fis = new FileInputStream("d://eExpress");
            ObjectInputStream ois = new ObjectInputStream(fis);
            try(fis;ois){
                arrayList = (ArrayList<Express>) ois.readObject();
                System.out.println("载入数据成功");
            }catch (Exception e){
                System.out.println("载入数据失败");
            }
        }catch (FileNotFoundException f) {
            System.out.println("未找到文件");
        }catch (EOFException e){
            System.out.println("文件还未存储序列化对象");
        }
        return arrayList;
    }

    //存储数据
    public void store(ArrayList<Express> arrayList) throws IOException {
        FileOutputStream fos = new FileOutputStream("d://eExpress");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(arrayList);
        oos.close();
        fos.close();
        System.out.println("数据存储成功");
    }
}

3.Server服务器类

服务器与客户端的交互最重要的一点就是只能是一边输出一边接收,TCP程序在我这一篇博客有介绍。另外就是加入多线程技术,一个服务器可以承接无数的客户端,多线程的创建和一般用法这一篇博客有介绍

/**
 * @Author:彭德华
 * @Description:服务器端
 * @Date Created in  2020-10-4 13:51
 * @Modified By:
 */
public class Server {
    public static void main(String[] args) throws ClassNotFoundException, IOException {
        ServerSocket serverSocket = new ServerSocket(65534);
        Function m = new Function();
        // 等待连接
        System.out.println("服务器端已启动\n等待客户端连接...");

        //使用while循环保证可以连接多个客户端,无限等待连接客户端
        while (true) {
            Socket socket = serverSocket.accept();
            System.out.println("连接客户端成功");
            System.out.println("等待客户端请求.....");
            //引入多线程技术
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        ArrayList<Express> arrayList = new ArrayList<>();

                        // 创建输入输出流
                        InputStream is = socket.getInputStream();
                        OutputStream os = socket.getOutputStream();

                        ObjectInputStream ois = new ObjectInputStream(is);
                        ObjectOutputStream oos = new ObjectOutputStream(os);

                        BufferedReader br = new BufferedReader(new InputStreamReader(is));
                        PrintStream ps = new PrintStream(os);

                        w1:
                        while (true) {
                            // 获取用户输入选项
                            int choose = is.read();
                            arrayList = m.load();
                            // 功能选择
                            switch (choose) {
                                case 0://结束
                                    System.out.println("结束");
                                    break w1;
                                case 1: {// 录入快递
                                    System.out.println("进入录入快递功能");
                                    //把服务器端信息传入客户端
                                    oos.writeObject(arrayList);
                                    // 接收到一个集合形式的快递信息
                                    ArrayList<Express> list = (ArrayList<Express>) ois.readObject();
                                    m.store(list);
                                    break;
                                }
                                case 2: {// 取出快递
                                    System.out.println("进入取快递功能");
                                    // 读取客户端发出的String类型的取件码,读取其中的数字
                                    int code = Integer.parseInt(br.readLine());

                                    // 取出快递信息
                                    StringBuffer text = m.take(code);
                                    // 发送快递信息给客户端
                                    ps.println(text);
                                    break;
                                }
                                case 3: {//查看所有快递
                                    System.out.println("进入查看所有快递功能");
                                    // 发送快递集合信息 给客户端
                                    oos.writeObject(m.load());
                                    break;
                                }
                                case 4: {
                                    System.out.println("进入删除快递功能");
                                    //接受客户端输入的快递单号
                                    String number = br.readLine();
                                    //反馈信息
                                    ps.println(m.delete(number));
                                }
                                case 5: {
                                    ArrayList<Express> a = m.load();
                                    System.out.println("进入修改快递功能");
                                    //接受客户端输入的快递单号
                                    String number = br.readLine();
                                    boolean b = false;
                                    for (Express1 e : a) {
                                        if (e.getNumber().equals(number)) {
                                            b = true;
                                            ps.println(1);
                                            p:
                                            while (true) {
                                                String select = br.readLine();
                                                switch (select) {
                                                    case "0":
                                                        break p;
                                                    case "1": {
                                                        String num = br.readLine();
                                                        e.setNumber(num);
                                                        a.remove(e);
                                                        a.add(e);
                                                        oos.writeObject(e);
                                                        break;
                                                    }
                                                    case "2": {
                                                        String company = br.readLine();
                                                        e.setCompany(company);
                                                        a.remove(e);
                                                        a.add(e);
                                                        oos.writeObject(e);
                                                        break;
                                                    }
                                                    case "3": {
                                                        String phone = br.readLine();
                                                        e.setPhone(phone);
                                                        a.remove(e);
                                                        a.add(e);
                                                        oos.writeObject(e);
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    if (b == false) {
                                        ps.println((char[]) null);
                                    }
                                    m.store(a);
                                }
                                default:
                            }
                        }
                        // 在最后记得关闭连接
                        ois.close();
                        oos.close();
                    }catch (Exception e){
                        System.out.println("异常");
                    }
                }
            }).start();
        }
    }
}

4.Clients客户端类

连接服务器端,收发与服务器端匹配即可。

/**
 * @Author:彭德华
 * @Description:客户端,做到了只用于接受用户输入
 * @Date Created in  2020-10-4 13:52
 * @Modified By:
 */
class Clients {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Scanner input = new Scanner(System.in);
        Function m = new Function();
        // 传入本机地址和端口
        Socket socket = new Socket("127.0.0.1",65534);
        // 向服务器发送请求
        System.out.println("正在向服务器发送请求");
        //建立 输/入出流
        OutputStream os = socket.getOutputStream();
        InputStream is = socket.getInputStream();
        ObjectOutputStream oos = new ObjectOutputStream(os);
        ObjectInputStream ois = new ObjectInputStream(is);
        PrintStream ps = new PrintStream(os);
        BufferedReader br = new BufferedReader(new InputStreamReader(is));

        w1:
        while (true){
            System.out.println("0.结束\n1.录入快递\n2.取快递\n3.查看所有快递\n4.删除快递\n5.修改快递");
            int choose = Integer.parseInt(input.nextLine());
            // 将序号发给服务器,功能对应
            os.write(choose);
            switch (choose) {
                case 0://结束程序
                    break w1;
                case 1: {// 录入快递
                    ArrayList<Express> arrayList = (ArrayList<Express>) ois.readObject();
                    // 创建快递信息并将此信息发给服务器
                    oos.writeObject(m.addExpress(arrayList));
                    System.out.println("快递录入成功");
                    break;
                }
                case 2: {// 取出快递
                    System.out.println("输入取件码");
                    // 将取件码传给服务器
                    ps.println(input.nextLine());

                    // 读取服务器传过来的快递信息
                    String text = br.readLine();
                    if(text == null)
                        System.out.println("未找到指定快递,请重新操作");
                    else
                        System.out.println("快递信息为:"+text+"请取出");
                    break;
                }
                case 3: {//查看所有快递
                    ArrayList<Express> list = (ArrayList<Express>)ois.readObject();
                    // 遍历
                    for (Express1 e : list) {
                        System.out.println(e.toString());
                    }
                    break;
                }
                case 4:{
                    System.out.println("请输入需要删除快递的单号:");
                    String text = input.nextLine();
                    ps.println(text);
                    String s = br.readLine();
                    if(s != null)
                        System.out.println("快递:"+s+",已被删除");
                    else
                        System.out.println("未找到快递信息");
                }
                case 5:{
                    System.out.println("请输入需要修改的快递单号:");
                    String text = input.nextLine();
                    ps.println(text);
                    String s = br.readLine();
                    if(s != null){
                        p:
                        while(true) {
                            System.out.println("请输入需要修改的信息:\n1.单号\n2.公司\n3.电话号码\n0.退出");
                            String select = input.nextLine();
                            ps.println(select);
                            switch (select) {
                                case "0":
                                    break p;
                                case "1": {
                                    System.out.println("请输入修改后的单号:");
                                    String number = input.nextLine();
                                    ps.println(number);
                                    System.out.println("修改后的信息为:\t"+ois.readObject());
                                    break;
                                }
                                case "2": {
                                    System.out.println("请输入修改后的公司:");
                                    String company = input.nextLine();
                                    ps.println(company);
                                    System.out.println("修改后的信息为:\t"+ois.readObject());
                                    break;
                                }
                                case "3": {
                                    System.out.println("请输入修改后的电话号码:");
                                    String phoneNumber = input.nextLine();
                                    ps.println(phoneNumber);
                                    System.out.println("修改后的信息为:\t"+ois.readObject());
                                    break ;
                                }
                                default:
                                    System.out.println("输入有误");
                                    break;
                            }
                        }
                    }else
                        System.out.println("未找到快递信息");
                }
                default:break;
            }
        }
        // 在最后记得关闭连接
        oos.close();
        ois.close();
    }
}

有bug,有时间的话我会进行更新。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值