【技能实训】DMS数据挖掘项目(完整程序)2

本文涉及的产品
数据管理 DMS,安全协同 3个实例 3个月
推荐场景:
学生管理系统数据库
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【技能实训】DMS数据挖掘项目(完整程序)

3.5 业务类及设计

DmsNetService类用于客户端与服务端的连接服务,用于确保客户端与服务端连接成功并进行数据的传输

package com.qst.dms.service;
import com.qst.dms.net.Request;
import com.qst.dms.net.Response;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class DmsNetService {
    private  static  DmsNetService instance = new DmsNetService();
    private  DmsNetService(){
    }
    public static DmsNetService getInstance(){
        return  instance;
    }
    public static void  sendRequest(Socket socket, Request request) throws IOException{
        ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
        out.writeObject(request);
        out.flush();
    }
    public static Request receiveRequest(Socket socket) throws ClassNotFoundException, IOException{
        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        Request req = (Request)in.readObject();
        return req;
    }
    public static void sendResponse(Socket socket, Response response) throws IOException{
        ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
        out.writeObject(response);
        out.flush();
    }
    public static Response receiveResponse(Socket socket) throws IOException,ClassNotFoundException{
        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        Response res = (Response)in.readObject();
        return res;
    }
}

LogRecService类中有许多方法,其中包含了日志数据的文件操作以及数据库操作,实现了日志数据的存取。

package com.qst.dms.service;
import com.qst.dms.entity.LogRec;
import com.qst.dms.entity.MatchedLogRec;
import com.qst.dms.exception.DataAnalyseException;
import com.qst.dms.gather.LogRecAnalyse;
import com.qst.dms.util.AppendObjectOutputStream;
import com.qst.dms.util.DBUtil;
import java.io.*;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
public class LogRecService {
    private static final String saveFile = "MatchedLogRec.dat";
    private Scanner scanner;
    public LogRecService() {
        scanner = new Scanner(System.in);
    }
    public LogRec inputLog() {
        int id, type, logType;
        String address;
        String user;
        String ip;
        String formattedDate;
        while (true) {
            try {
                System.out.println("请输入ID标识:");
                id = scanner.nextInt();
                Date currentDate = new Date();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                formattedDate = dateFormat.format(currentDate);
                System.out.println("请输入地址:");
                address = scanner.next();
                type = LogRec.GATHER;
                System.out.println("请输入登录用户名:");
                user = scanner.next();
                System.out.println("请输入主机IP:");
                ip = scanner.next();
                System.out.println("请输入登录状态(1表示登录,0表示登出):");
                logType = scanner.nextInt();
                if (logType == 0 || logType == 1) {
                    break;
                } else {
                    throw new IllegalArgumentException("非法的登录状态");
                }
            } catch (Exception e) {
                System.out.println("输入错误,请重新输入");
                scanner.nextLine();
            }
        }
        return new LogRec(id, formattedDate, address, type, user, ip, logType);
    }
    public void showLog(List<LogRec> logRecs) {
        System.out.println("日志信息:");
        for (LogRec logRec : logRecs) {
            System.out.println(logRec);
        }
    }
    // 匹配日志信息输出,参数是集合
    public void showMatchLog(List<MatchedLogRec> matchLogs) {
        System.out.println("匹配日志信息:");
        for (MatchedLogRec matchLog : matchLogs) {
            System.out.println(matchLog);
        }
    }
    // 保存
    public static void saveLogRec(List<LogRec> Logs) {
        try {
            AppendObjectOutputStream.setFile(new File(saveFile));
            File file = AppendObjectOutputStream.getFile();
            FileOutputStream fileOut = new FileOutputStream(file, true);
            AppendObjectOutputStream objOut = new AppendObjectOutputStream(file);
            for (LogRec Log : Logs) {
                objOut.writeObject(Log);
            }
            objOut.close();
            fileOut.close();
            System.out.println("匹配日志信息保存成功\n");
        } catch (IOException e) {
            System.out.println("保存匹配日志信息发生异常:" + e.getMessage()+"\n");
        }
    }
    //匹配
    public static List<MatchedLogRec> readMatchLogRec() {
        List<MatchedLogRec> matchedLogs = new ArrayList<>();
        List<LogRec> logs = readLogRec();
        try {
            AppendObjectOutputStream.setFile(new File(saveFile));
            File file = AppendObjectOutputStream.getFile();
            if (!file.exists()) {
                file.createNewFile();
            }
            FileInputStream fileIn = new FileInputStream(file);
            // 创建一个ObjectInputStream对象输入流,并连接文件输入流
            ObjectInputStream objIn = new ObjectInputStream(fileIn);
            // 创建日志数据分析对象
            LogRecAnalyse logAnalyse = new LogRecAnalyse(logs);
            // 日志数据过滤
            logAnalyse.doFilter();
            // 日志数据匹配分析
            try {
                List<MatchedLogRec> objs = logAnalyse.matchData(); // 进行数据匹配
                // 处理匹配的日志数据
                // 判断objs集合是否是配置日志集合
                if (objs instanceof List<?>) {
                    // 将集合强制类型转换成配置日志集合
                    matchedLogs = (List<MatchedLogRec>) objs;
                }
            } catch (DataAnalyseException e) {
                System.out.println(e.getMessage());
            }
            objIn.close();
            fileIn.close();
            System.out.println("匹配日志信息读取完成\n");
        } catch (IOException e) {
            System.out.println("读取匹配日志信息发生异常:" + e.getMessage()+"\n");
        }
        return matchedLogs;
    }
    //显示日志
    public static List<LogRec> readLogRec() {
        List<LogRec> logs = new ArrayList<>();
        try {
            AppendObjectOutputStream.setFile(new File(saveFile));
            File file = AppendObjectOutputStream.getFile();
            if (!file.exists()) {
                file.createNewFile();
            }
            FileInputStream fileIn = new FileInputStream(file);
            // 创建一个ObjectInputStream对象输入流,并连接文件输入流
            ObjectInputStream objIn = new ObjectInputStream(fileIn);
            // 使用异常处理和EOFException异常处理读取结束
            try {
                while (true) {
                    LogRec log = (LogRec) objIn.readObject();
                    logs.add(log);
                }
            } catch (EOFException e) {
                // 读取结束,不做任何操作
            }
            objIn.close();
            fileIn.close();
            System.out.println("日志信息读取完成\n");
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("读取日志信息发生异常:" + e.getMessage() +"\n");
        }
        return logs;
    }
    //显示能匹配的日志信息
    public static List<LogRec> readLogRecs() {
        List<LogRec> logs = new ArrayList<>();
        List<MatchedLogRec> matchlogs = readMatchLogRec();
        for(MatchedLogRec matchlog:matchlogs){
            logs.add(matchlog.getLogin());
            logs.add(matchlog.getLogout());
        }
        return logs;
    }
    /*
    // 匹配日志信息保存到数据库,参数是集合
    public static void saveMatchLogToDB() {
        List<MatchedLogRec> matchLogs = readMatchLogRec();
        List<LogRec> login = new ArrayList<>();
        List<LogRec> logout = new ArrayList<>();
        List<LogRec> logs = readLogRec();
        Connection conn = null;
        try {
            DBUtil db = new DBUtil();
            conn = db.getConnection();
            for (MatchedLogRec matchlog : matchLogs) {
                int loginId = matchlog.getLogin().getId();
                int logoutId = matchlog.getLogout().getId();
                for (LogRec log : logs) {
                    if (log.getId() == loginId) {
                        login.add(log);
                    } else if (log.getId() == logoutId) {
                        logout.add(log);
                    }
                }
            }
            // 保存匹配记录中的登录日志
            String querySqllogin = "INSERT INTO log_in VALUES (?, ?, ?, ?, ?, ?, ?)";
            for (LogRec log : login) {
                Object[] queryParams = {log.getId(), log.getTime(), log.getAddress(), log.getType(), log.getUser(), log.getIp(), log.getLogType()};
                db.executeUpdate(querySqllogin, queryParams);
            }
            System.out.println("保存匹配记录中的登录日志成功");
            // 保存匹配记录中的登出日志
            String querySqllogout = "INSERT INTO log_out VALUES (?, ?, ?, ?, ?, ?, ?)";
            for (LogRec log : logout) {
                Object[] queryParams = {log.getId(), log.getTime(), log.getAddress(), log.getType(), log.getUser(), log.getIp(), log.getLogType()};
                db.executeUpdate(querySqllogout, queryParams);
            }
            System.out.println("保存匹配记录中的登出日志成功");
            // 保存匹配日志的ID
            String querySqlmatch = "INSERT INTO log_match VALUES (?, ?)";
            for (MatchedLogRec matchlog : matchLogs) {
                Object[] queryParams = {matchlog.getLogin().getId(), matchlog.getLogout().getId()};
                db.executeUpdate(querySqlmatch, queryParams);
            }
            System.out.println("保存匹配日志的ID成功");
            db.commitAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接,释放资源
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    */
/*
    public static List<MatchedLogRec> readMatchedLogFromDB() {
        DBUtil db = new DBUtil();
        Connection conn = null;
        List<MatchedLogRec> matchedLogs = new ArrayList<>();
        try {
            conn = db.getConnection();
            // 查询匹配的日志
            String querySqlMatchedLogs = "SELECT * FROM log_match";
            ResultSet matchedLogsResult = db.executeQuery(querySqlMatchedLogs,null);
            while (matchedLogsResult.next()) {
                int loginId = matchedLogsResult.getInt("login_id");
                int logoutId = matchedLogsResult.getInt("logout_id");
                // 获取登录记录
                LogRec login = new LogRec();
                String querySqlLogin = "SELECT * FROM log_in WHERE id = ?";
                Object[] loginParams = { loginId };
                ResultSet loginResult = db.executeQuery(querySqlLogin, loginParams);
                if (loginResult.next()) {
                    // 设置登录记录的属性值
                    login.setId(loginResult.getInt("id"));
                    login.setTime(loginResult.getString("time"));
                    login.setAddress(loginResult.getString("address"));
                    login.setType(loginResult.getInt("type"));
                    login.setUser(loginResult.getString("user"));
                    login.setIp(loginResult.getString("ip"));
                    login.setLogType(loginResult.getInt("logtype"));
                    // 获取登出记录
                    LogRec logout = new LogRec();
                    String querySqlLogout = "SELECT * FROM log_out WHERE id = ?";
                    Object[] logoutParams = { logoutId };
                    ResultSet logoutResult = db.executeQuery(querySqlLogout, logoutParams);
                    if (logoutResult.next()) {
                        // 设置登出记录的属性值
                        logout.setId(logoutResult.getInt("id"));
                        logout.setTime(logoutResult.getString("time"));
                        logout.setAddress(logoutResult.getString("address"));
                        logout.setType(logoutResult.getInt("type"));
                        logout.setUser(logoutResult.getString("user"));
                        logout.setIp(logoutResult.getString("ip"));
                        logout.setLogType(logoutResult.getInt("logtype"));
                        // 添加匹配登录信息到匹配集合
                        MatchedLogRec matchedLog = new MatchedLogRec( login,  logout);
                        matchedLogs.add(matchedLog);
                    }
                    logoutResult.close();
                }
                loginResult.close();
            }
            matchedLogsResult.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接,释放资源
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return matchedLogs;
    }
 */
    public static void saveLogResult(List<MatchedLogRec> matchlogs) {
        Connection conn = null;
        try {
            DBUtil db = new DBUtil();
            conn = db.getConnection();
            // 保存匹配记录中的登录日志
            String querySqllogin = "INSERT INTO gather_logrec VALUES (?, ?, ?, ?, ?, ?, ?)";
            for (MatchedLogRec matchlog : matchlogs) {
                Object[] queryinParams = {matchlog.getLogin().getId(), matchlog.getLogin().getTime(), matchlog.getLogin().getAddress(), matchlog.getLogin().getType(), matchlog.getLogin().getUser(), matchlog.getLogin().getIp(), matchlog.getLogin().getLogType()};
                db.executeUpdate(querySqllogin, queryinParams);
                Object[] queryoutParams = {matchlog.getLogout().getId(), matchlog.getLogout().getTime(), matchlog.getLogout().getAddress(), matchlog.getLogout().getType(), matchlog.getLogout().getUser(), matchlog.getLogout().getIp(), matchlog.getLogout().getLogType()};
                db.executeUpdate(querySqllogin, queryoutParams);
            }
            System.out.println("保存匹配记录日志到数据库成功");
            db.commitAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接,释放资源
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    //LogRecService类中增加方法readLogResult()
    //获取数据库中的所有匹配的日志信息,返回一个ResultSet
    public static ResultSet readLogResult() {
        ResultSet matchedLogsResult = null;
        //获取匹配日志表中的所有数据,返回ResultSet
        //创建语句时使用:
        DBUtil db = new DBUtil();
        Connection conn = null;
        try {
            conn = db.getConnection();
            Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
            // 查询匹配的日志
            String querySqlMatchedLogs = "SELECT * FROM gather_logrec";
            matchedLogsResult = st.executeQuery(querySqlMatchedLogs);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return matchedLogsResult;
    }
}

TransportService类中有许多方法,其中包含了物流数据的文件操作以及数据库操作,实现了物流数据的存取。

package com.qst.dms.service;
import com.qst.dms.entity.MatchedLogRec;
import com.qst.dms.entity.MatchedTransport;
import com.qst.dms.entity.Transport;
import com.qst.dms.exception.DataAnalyseException;
import com.qst.dms.gather.TransportAnalyse;
import com.qst.dms.util.AppendObjectOutputStream;
import com.qst.dms.util.DBUtil;
import java.io.*;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
public class TransportService {
    private static final String saveFile = "MatchedTransport.dat";
    private Scanner scanner;
    public TransportService() {
        scanner = new Scanner(System.in);
    }
    public Transport inputTransport() {
        int transportType;
        int id, type;
        String formattedDate;
        String address, handler, receiver;
        while (true) {
            try {
                System.out.println("请输入ID标识:");
                id = scanner.nextInt();
                Date currentDate = new Date();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                formattedDate = dateFormat.format(currentDate);
                System.out.println("请输入地址:");
                address = scanner.next();
                type = Transport.GATHER;
                System.out.println("请输入货物经手人:");
                handler = scanner.next();
                System.out.println("请输入收货人:");
                receiver = scanner.next();
                System.out.println("请输入物流状态(1表示发货中,2表示送货中,3表示已签收):");
                transportType = scanner.nextInt();
                if (transportType == 1 || transportType == 2 || transportType == 3) {
                    break;
                } else {
                    throw new IllegalArgumentException("非法的物流状态");
                }
            } catch (Exception e) {
                System.out.println("输入错误,请重新输入");
                scanner.nextLine();
            }
        }
        return new Transport(id, formattedDate, address, type, handler, receiver, transportType);
    }
    public void showTransport(List<Transport> transports) {
        System.out.println("物流信息:");
        for (Transport transport : transports) {
            System.out.println(transport);
        }
    }
    // 匹配物流信息输出,参数是集合
    public void showMatchTransport(List<MatchedTransport> matchTrans) {
        System.out.println("匹配物流信息:");
        for (MatchedTransport matchTran : matchTrans) {
            System.out.println(matchTran);
        }
    }
    // 保存
    public static void saveTransport(List<Transport> transports) {
        try {
            AppendObjectOutputStream.setFile(new File(saveFile));
            File file = AppendObjectOutputStream.getFile();
            FileOutputStream fileOut = new FileOutputStream(file, true);
            AppendObjectOutputStream objOut = new AppendObjectOutputStream(file);
            for (Transport transport : transports) {
                objOut.writeObject(transport);
            }
            objOut.close();
            fileOut.close();
            System.out.println("匹配物流信息保存成功\n");
        } catch (IOException e) {
            System.out.println("保存匹配物流信息发生异常:" + e.getMessage() + "\n");
        }
    }
    //匹配
    public static List<MatchedTransport> readMatchTransport() {
        List<MatchedTransport> matchedTransports = new ArrayList<>();
        List<Transport> transports = readTransport();
        try {
            AppendObjectOutputStream.setFile(new File(saveFile));
            File file = AppendObjectOutputStream.getFile();
            if (!file.exists()) {
                file.createNewFile();
            }
            FileInputStream fileIn = new FileInputStream(file);
            // 创建一个ObjectInputStream对象输入流,并连接文件输入流
            ObjectInputStream objIn = new ObjectInputStream(fileIn);
            // 创建物流数据分析对象
            TransportAnalyse ta = new TransportAnalyse(transports);
            // 物流数据过滤
            ta.doFilter();
            try {
                // 物流数据分析
                List<MatchedTransport> objs = ta.matchData();
                // 判断objs集合是否是匹配物流集合
                if (objs instanceof List<?>) {
                    // 将集合强制类型转换成匹配物流集合
                    matchedTransports = (ArrayList<MatchedTransport>) objs;
                }
            } catch (DataAnalyseException e) {
                System.out.println(e.getMessage());
            }
            objIn.close();
            fileIn.close();
            System.out.println("匹配物流信息读取完成\n");
        } catch (IOException e) {
            System.out.println("读取匹配物流信息发生异常:" + e.getMessage() + "\n");
        }
        return matchedTransports;
    }
    //显示物流信息
    public static List<Transport> readTransport() {
        List<Transport> transports = new ArrayList<>();
        try {
            AppendObjectOutputStream.setFile(new File(saveFile));
            File file = AppendObjectOutputStream.getFile();
            if (!file.exists()) {
                file.createNewFile();
            }
            FileInputStream fileIn = new FileInputStream(file);
            // 创建一个ObjectInputStream对象输入流,并连接文件输入流
            ObjectInputStream objIn = new ObjectInputStream(fileIn);
            // 使用异常处理和EOFException异常处理读取结束
            try {
                while (true) {
                    Transport transport = (Transport) objIn.readObject();
                    transports.add(transport);
                }
            } catch (EOFException e) {
                // 读取结束,不做任何操作
            }
            objIn.close();
            fileIn.close();
            System.out.println("物流信息读取完成\n");
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("读取物流信息发生异常:" + e.getMessage() + "\n");
        }
        return transports;
    }
    //显示能匹配的物流信息
    public static List<Transport> readTransports() {
        List<Transport> transports = new ArrayList<>();
        List<MatchedTransport> matchtrans = readMatchTransport();
        for(MatchedTransport matchtran : matchtrans){
            transports.add(matchtran.getSend());
            transports.add(matchtran.getTrans());
            transports.add(matchtran.getReceive());
        }
        return transports;
    }
/*
    // 匹配日志信息保存到数据库,参数是集合
    public static void saveMatchTransportToDB() {
        List<MatchedTransport> matchTrans = readMatchTransport();
        List<Transport> sendList = new ArrayList<>();
        List<Transport> tranList = new ArrayList<>();
        List<Transport> recList = new ArrayList<>();
        List<Transport> transports = readTransport();
        Connection conn = null;
        try {
            DBUtil db = new DBUtil();
            conn = db.getConnection();
            for (MatchedTransport matchTran : matchTrans){
                int send = matchTran.getSend().getId();
                int tran = matchTran.getTrans().getId();
                int rec =  matchTran.getReceive().getId();
                for (Transport transport : transports){
                    if (transport.getId() == send){
                        sendList.add(transport);
                    }else if(transport.getId() == tran){
                        tranList.add(transport);
                    }else if(transport.getId() == rec){
                        recList.add(transport);
                    }
                }
            }
            String querySqllogsend = "INSERT INTO send VALUES (?, ?, ?, ?, ?, ?, ?)";
            for (Transport transport: sendList) {
                Object[] queryParams = {transport.getId(), transport.getTime(), transport.getAddress(), transport.getType(), transport.getHandler(), transport.getReciver(), transport.getTransportType()};
                db.executeUpdate(querySqllogsend, queryParams);
            }
            System.out.println("保存匹配物流中的发送日志成功");
            String querySqllogtran = "INSERT INTO tran VALUES (?, ?, ?, ?, ?, ?, ?)";
            for (Transport transport: tranList) {
                Object[] queryParams = {transport.getId(), transport.getTime(), transport.getAddress(), transport.getType(), transport.getHandler(), transport.getReciver(), transport.getTransportType()};
                db.executeUpdate(querySqllogtran, queryParams);
            }
            System.out.println("保存匹配物流中的运输日志成功");
            String querySqllogrec = "INSERT INTO receive VALUES (?, ?, ?, ?, ?, ?, ?)";
            for (Transport transport: recList) {
                Object[] queryParams = {transport.getId(), transport.getTime(), transport.getAddress(), transport.getType(), transport.getHandler(), transport.getReciver(), transport.getTransportType()};
                db.executeUpdate(querySqllogrec, queryParams);
            }
            System.out.println("保存匹配物流中的接收日志成功");
            // 保存匹配日志的ID
            String querySqlmatch = "INSERT INTO matchtrans VALUES (?, ?, ?)";
            for (MatchedTransport matchtran : matchTrans) {
                Object[] queryParams = {matchtran.getSend().getId(), matchtran.getTrans().getId(), matchtran.getReceive().getId()};
                db.executeUpdate(querySqlmatch, queryParams);
            }
            System.out.println("保存匹配物流的ID成功");
            db.commitAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接,释放资源
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static List<MatchedTransport> readMatchedTransportFromDB() {
        DBUtil db = new DBUtil();
        Connection conn = null;
        List<MatchedTransport> matchedtrans = new ArrayList<>();
        try {
            conn = db.getConnection();
            // 查询匹配的日志
            String querySqlmatchedtrans = "SELECT * FROM matchtrans";
            ResultSet matchedtransResult = db.executeQuery(querySqlmatchedtrans,null);
            while (matchedtransResult.next()) {
                int sendId = matchedtransResult.getInt("sendid");
                int tranId = matchedtransResult.getInt("tranid");
                int recId = matchedtransResult.getInt("recid");
                Transport sendList = new Transport();
                String querySqlsendList = "SELECT * FROM send WHERE id = ?";
                Object[] sendListParams = { sendId };
                ResultSet sendResult = db.executeQuery(querySqlsendList, sendListParams);
                if (sendResult.next()) {
                    sendList.setId(sendResult.getInt("id"));
                    sendList.setTime(sendResult.getString("time"));
                    sendList.setAddress(sendResult.getString("address"));
                    sendList.setType(sendResult.getInt("type"));
                    sendList.setHandler(sendResult.getString("handler"));
                    sendList.setReciver(sendResult.getString("receiver"));
                    sendList.setTransportType(sendResult.getInt("trantype"));
                    Transport tranList = new Transport();
                    String querySqltranList = "SELECT * FROM tran WHERE id = ?";
                    Object[] tranListParams = { tranId };
                    ResultSet tranListResult = db.executeQuery(querySqltranList, tranListParams);
                    if (tranListResult.next()) {
                        // 设置登出记录的属性值
                        tranList.setId(tranListResult.getInt("id"));
                        tranList.setTime(tranListResult.getString("time"));
                        tranList.setAddress(tranListResult.getString("address"));
                        tranList.setType(tranListResult.getInt("type"));
                        tranList.setHandler(tranListResult.getString("handler"));
                        tranList.setReciver(tranListResult.getString("receiver"));
                        tranList.setTransportType(tranListResult.getInt("trantype"));
                        Transport recList = new Transport();
                        String querySqlrecList = "SELECT * FROM receive WHERE id = ?";
                        Object[] recListParams = { recId };
                        ResultSet recListResult = db.executeQuery(querySqlrecList, recListParams);
                        if (recListResult.next()) {
                            // 设置登出记录的属性值
                            recList.setId(recListResult.getInt("id"));
                            recList.setTime(recListResult.getString("time"));
                            recList.setAddress(recListResult.getString("address"));
                            recList.setType(recListResult.getInt("type"));
                            recList.setHandler(recListResult.getString("handler"));
                            recList.setReciver(recListResult.getString("receiver"));
                            recList.setTransportType(recListResult.getInt("trantype"));
                            // 添加匹配登录信息到匹配集合
                            MatchedTransport matchedLog = new MatchedTransport( sendList, tranList, recList);
                            matchedtrans.add(matchedLog);
                        }
                        recListResult.close();
                    }
                    tranListResult.close();
                }
                sendResult.close();
            }
            matchedtransResult.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接,释放资源
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return matchedtrans;
    }
 */
    // 匹配日志信息保存到数据库,参数是集合
    public static void saveTranResult(List<MatchedTransport> matchtrans) {
        Connection conn = null;
        try {
            DBUtil db = new DBUtil();
            conn = db.getConnection();
            String querySqllogsend = "INSERT INTO gather_transport VALUES (?, ?, ?, ?, ?, ?, ?)";
            for (MatchedTransport matchtran: matchtrans) {
                Object[] queryParamsSend = {matchtran.getSend().getId(), matchtran.getSend().getTime(), matchtran.getSend().getAddress(), matchtran.getSend().getType(), matchtran.getSend().getHandler(), matchtran.getSend().getReciver(), matchtran.getSend().getTransportType()};
                db.executeUpdate(querySqllogsend, queryParamsSend);
                Object[] queryParamsTran = {matchtran.getTrans().getId(), matchtran.getTrans().getTime(), matchtran.getTrans().getAddress(), matchtran.getTrans().getType(), matchtran.getTrans().getHandler(), matchtran.getTrans().getReciver(), matchtran.getTrans().getTransportType()};
                db.executeUpdate(querySqllogsend, queryParamsTran);
                Object[] queryParamsRec = {matchtran.getReceive().getId(), matchtran.getReceive().getTime(), matchtran.getReceive().getAddress(), matchtran.getReceive().getType(), matchtran.getReceive().getHandler(), matchtran.getReceive().getReciver(), matchtran.getReceive().getTransportType()};
                db.executeUpdate(querySqllogsend, queryParamsRec);
            }
            System.out.println("保存匹配物流日志到数据库成功");
            db.commitAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接,释放资源
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    //获取数据库中的所有匹配的物流信息,返回一个ResultSet
    public ResultSet readTransResult() {
        //获取匹配物流表中的所有数据,返回ResultSet
        ResultSet matchedTransResult = null;
        //获取匹配日志表中的所有数据,返回ResultSet
        //创建语句时使用:
        DBUtil db = new DBUtil();
        Connection conn = null;
        ArrayList<MatchedTransport> matchedTrans = new ArrayList<>();
        try {
            conn = db.getConnection();
            Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
            // 查询匹配的日志
            String querySqlMatchedLogs = "SELECT * FROM gather_transport";
            matchedTransResult = st.executeQuery(querySqlMatchedLogs);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return matchedTransResult;
    }
}

UserService类实现了用户的注册以及登录信息的存储操作,将用户信息存入了数据库。

package com.qst.dms.service;
import com.qst.dms.entity.User;
import com.qst.dms.util.DBUtil;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserService {
    DBUtil db = new DBUtil();
    Connection conn = null;
    // 根据用户名查询用户,各用户的用户名不能相同
    public User findUserByName(String userName) {
        // 返回符合条件的用户对象
        User user = new User();
        try {
            try {
                conn = db.getConnection();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            String querySqluser = "SELECT * FROM users WHERE username = ?";
            Object[] userParams = {userName};
            ResultSet userResult = db.executeQuery(querySqluser, userParams);
            db.commitAll();
            if (userResult.next()) {
                // 设置登出记录的属性值
                user.setUsername(userResult.getString("username"));
                user.setPassword(userResult.getString("password"));
                user.setAddress(userResult.getString("address"));
                user.setGender(userResult.getInt("gender"));
                user.setHobby(userResult.getString("hobby"));
                user.setDegree(userResult.getString("degree"));
            }
            userResult.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接,释放资源
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return user;
    }
    // 保存用户信息
    public boolean saveUser(User user) {
        // 返回保存结果,成功返回true,失败返回false
        try {
            try {
                conn = db.getConnection();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            String querySqluser = "INSERT INTO users(username,password,gender,hobby,address,degree) VALUES (?, ?, ?, ?, ?, ?)";
            Object[] queryParams = {user.getUsername(), user.getPassword(), user.getGender(), user.getHobby(), user.getAddress(), user.getDegree()};
            db.executeUpdate(querySqluser, queryParams);
            db.commitAll();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接,释放资源
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }
}

3.6 异常处理

项目中有许多异常处理结构,比如当用户在注册时输入的用户名已经存在时,会提示“用户名已存在”的警告信息;当用户在客户端录入数据时输入了相同的id,会提示“id相同”的警告信息,并提示用户重新输入信息等等

3.7 界面设计

LoginFrame类实现了登陆界面

package com.qst.dms.ui;
import com.qst.dms.entity.User;
import com.qst.dms.service.UserService;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class LoginFrame extends JFrame {
    // 主面板
    private JPanel p;
    // 标签
    private JLabel lblName, lblPwd;
    // 用户名,文本框
    private JTextField txtName;
    // 密码,密码框
    private JPasswordField txtPwd;
    // 确认、取消和注册,按钮
    private JButton btnOk, btnCancle, btnRegist;
    // 登录用户
    private static User user;
    // 用户业务类
    private UserService userService;
    // 构造方法
    public LoginFrame() {
        super("登录");
        // 实例化用户业务类对象
        userService = new UserService();
        // 设置窗体的icon
        ImageIcon icon = new ImageIcon("images\\dms.png");
        this.setIconImage(icon.getImage());
        // 实例化组件
        p = new JPanel();
        // 使用null布局
        p.setLayout(null);
        lblName = new JLabel("用户名:");
        lblPwd = new JLabel("密    码:");
        txtName = new JTextField(20);
        txtPwd = new JPasswordField(20);
        txtPwd.setEchoChar('*');
        btnOk = new JButton("登录");
        btnOk.addActionListener((ActionListener) new LoginListener());
        btnCancle = new JButton("重置");
        btnCancle.addActionListener(new LoginFrame.ResetListener());
        btnRegist = new JButton("注册");
        btnRegist.addActionListener(new RegistListener());
        lblName.setBounds(30, 30, 60, 25);
        lblPwd.setBounds(30, 60, 60, 25);
        txtName.setBounds(95, 30, 120, 25);
        txtPwd.setBounds(95, 60, 120, 25);
        btnOk.setBounds(30, 90, 60, 25);
        btnCancle.setBounds(95, 90, 60, 25);
        btnRegist.setBounds(160, 90, 60, 25);
        p.add(lblName);
        p.add(txtName);
        p.add(lblPwd);
        p.add(txtPwd);
        p.add(btnOk);
        p.add(btnCancle);
        p.add(btnRegist);
        // 主面板放入窗体中
        this.add(p);
        // 设置窗体大小和位置
        this.setSize(280, 170);
        // 设置窗口在屏幕中央
        this.setLocationRelativeTo(null);
        //this.setAlwaysOnTop(true);
        // 设置窗体不能改变大小
        this.setResizable(false);
        // 设置窗体的默认关闭按钮
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置窗体初始可见
        this.setVisible(true);
    }
    // 监听类,负责处理登录按钮
    public class LoginListener implements ActionListener {
        // 重写actionPerFormed()方法,事件处理逻辑
        public void actionPerformed(ActionEvent e) {
            // 根据用户名查询用户
            try{
                user = userService.findUserByName((txtName.getText().trim()));
                if (user != null) {
                    //判断输入的密码是否正确
                    if (user.getPassword().equals(new String(txtPwd.getPassword()))) {
                        //输出提示信息
                        JOptionPane.showMessageDialog(null, "登录成功!", "成功提示", JOptionPane.PLAIN_MESSAGE);
                        //登录成功
                        LoginFrame.this.setVisible(false);
                        //显示主窗口
                        new ClientFrame();
                    } else {
                        //输出提示信息
                        JOptionPane.showMessageDialog(null, "密码错误!请重新输入!", "错误提示", JOptionPane.ERROR_MESSAGE);
                        //清空密码框
                        txtPwd.setText("");
                    }
                } else {
                    //输出提示信息
                    JOptionPane.showMessageDialog(null, "该用户不存在,请先注册!", "错误提示", JOptionPane.ERROR_MESSAGE);
                }
            }catch (Exception t){
                JOptionPane.showMessageDialog(null, "该用户不存在,请先注册!", "错误提示", JOptionPane.ERROR_MESSAGE);
            }
        }
    }
    // 监听类,负责处理重置按钮
    public class ResetListener implements ActionListener {
        // 重写actionPerFormed()方法,事件处理方法
        public void actionPerformed(ActionEvent e) {
            // 清空文本框
            try {
                txtName.setText("");
                txtPwd.setText("");
            }catch(Exception t){
                JOptionPane.showMessageDialog(null, "重置失败!", "错误提示", JOptionPane.ERROR_MESSAGE);
            }
        }
    }
    // 监听类,负责处理注册按钮
    public class RegistListener implements ActionListener {
        // 重写actionPerFormed()方法,事件处理方法
        public void actionPerformed(ActionEvent e) {
            // 创建注册窗口
            new RegistFrame();
        }
    }
}

RegistFrame类实现了注册界面

package com.qst.dms.ui;
import com.qst.dms.entity.User;
import com.qst.dms.service.UserService;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class RegistFrame extends JFrame{
    // 主面板
    private JPanel p;
    // 标签
    private JLabel lblName, lblPwd, lblRePwd, lblSex, lblHobby, lblAdress,
            lblDegree;
    // 用户名,文本框
    private static JTextField txtName;
    // 密码和确认密码,密码框
    private static JPasswordField txtPwd;
    private static JPasswordField txtRePwd;
    // 性别,单选按钮
    private static JRadioButton rbMale;
    private static JRadioButton rbFemale;
    // 爱好,多选框
    private static JCheckBox ckbRead;
    private static JCheckBox ckbNet;
    private static JCheckBox ckbSwim;
    private static JCheckBox ckbTour;
    // 地址,文本域
    private static JTextArea txtAdress;
    // 学历,组合框
    private static JComboBox<String> cmbDegree;
    // 确认和取消,按钮
    private JButton btnOk, btnCancle;
    // 注册的用户
    private static User user;
    // 用户业务类
    private UserService userService;
    private Image iconImage;
    // 构造方法
    public RegistFrame() {
        super("注册");
        // 实例化用户业务类对象
        userService = new UserService();
        // 设置窗体的icon
        ImageIcon icon = new ImageIcon("images\\dms.png");
        this.setIconImage(icon.getImage());
        // 设置面板布局,网格布局
        p = new JPanel(new GridLayout(8, 1));
        // 实例化组件
        lblName = new JLabel("用  户  名:");
        lblPwd = new JLabel("密        码:");
        lblRePwd = new JLabel("确认密码:");
        lblSex = new JLabel("性       别:");
        lblHobby = new JLabel("爱        好:");
        lblAdress = new JLabel("地        址:");
        lblDegree = new JLabel("学        历:");
        txtName = new JTextField(16);
        txtPwd = new JPasswordField(16);
        txtRePwd = new JPasswordField(16);
        rbMale = new JRadioButton("男");
        rbFemale = new JRadioButton("女");
        // 性别的单选逻辑
        ButtonGroup bg = new ButtonGroup();
        bg.add(rbMale);
        bg.add(rbFemale);
        ckbRead = new JCheckBox("阅读");
        ckbNet = new JCheckBox("上网");
        ckbSwim = new JCheckBox("游泳");
        ckbTour = new JCheckBox("旅游");
        txtAdress = new JTextArea(3, 20);
        // 组合框显示的学历数组
        String str[] = { "小学", "初中", "高中", "本科", "硕士", "博士" };
        cmbDegree = new JComboBox<String>(str);
        // 设置组合框可编辑
        cmbDegree.setEditable(true);
        btnOk = new JButton("确定");
        // 注册监听器,监听确定按钮
        btnOk.addActionListener((ActionListener) new RegisterListener());
        btnCancle = new JButton("重置");
        // 注册监听器,监听重置按钮
        btnCancle.addActionListener(new ResetListener());
        // 将组件分组放入面板,然后将小面板放入主面板
        JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
        p1.add(lblName);
        p1.add(txtName);
        p.add(p1);
        JPanel p2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
        p2.add(lblPwd);
        p2.add(txtPwd);
        p.add(p2);
        JPanel p3 = new JPanel(new FlowLayout(FlowLayout.LEFT));
        p3.add(lblRePwd);
        p3.add(txtRePwd);
        p.add(p3);
        JPanel p4 = new JPanel(new FlowLayout(FlowLayout.LEFT));
        p4.add(lblSex);
        p4.add(rbMale);
        p4.add(rbFemale);
        p.add(p4);
        JPanel p5 = new JPanel(new FlowLayout(FlowLayout.LEFT));
        p5.add(lblHobby);
        p5.add(ckbRead);
        p5.add(ckbNet);
        p5.add(ckbSwim);
        p5.add(ckbTour);
        p.add(p5);
        JPanel p6 = new JPanel(new FlowLayout(FlowLayout.LEFT));
        p6.add(lblAdress);
        p6.add(txtAdress);
        p.add(p6);
        JPanel p7 = new JPanel(new FlowLayout(FlowLayout.LEFT));
        p7.add(lblDegree);
        p7.add(cmbDegree);
        p.add(p7);
        JPanel p8 = new JPanel(new FlowLayout(FlowLayout.CENTER));
        p8.add(btnOk);
        p8.add(btnCancle);
        p.add(p8);
        // 主面板放入窗体中
        this.add(p);
        // 设置窗体大小和位置居中
        this.setSize(310, 400);
        this.setLocationRelativeTo(null);
        // 设置窗体不可改变大小
        this.setResizable(false);
        // 设置窗体初始可见
        this.setVisible(true);
    }
    public void setIconImage(Image iconImage) {
        this.iconImage = iconImage;
    }
    // 监听类,负责处理确认按钮的业务逻辑
    private class RegisterListener implements ActionListener {
        // 重写actionPerFormed()方法,事件处理方法
        public void actionPerformed(ActionEvent e) {
            // 获取用户输入的数据
            String userName = txtName.getText().trim();
            String password = new String(txtPwd.getPassword());
            String rePassword = new String(txtRePwd.getPassword());
            int sex = Integer.parseInt(rbFemale.isSelected()?"0":"1");
            String hobby = (ckbRead.isSelected()?"阅读":"")
                    + (ckbNet.isSelected()?"上网":"")
                    + (ckbNet.isSelected()?"游泳":"")
                    + (ckbNet.isSelected()?"旅游":"");
            String address = txtAdress.getText().trim();
            String degree = cmbDegree.getSelectedItem().toString().trim();
            user = userService.findUserByName((txtName.getText().trim()));
            if(user != null){
                JOptionPane.showMessageDialog(null, "用户名已存在!", "错误提示", JOptionPane.ERROR_MESSAGE);
                return;
            }
            //判断两次输入密码是否一致
            try {
                if (password.equals(rePassword)) {
                    //将数据封装到对象中
                    user = new User(userName, password, sex, hobby, address, degree);
                    //保存数据
                    if (userService.saveUser(user)) {
                        //输出提示信息
                        JOptionPane.showMessageDialog(null, "注册成功!", "成功提示", JOptionPane.PLAIN_MESSAGE);
                    } else {
                        //输出提示信息
                        JOptionPane.showMessageDialog(null, "注册失败!", "错误提示", JOptionPane.ERROR_MESSAGE);
                    }
                } else {
                    //输出提示信息
                    JOptionPane.showMessageDialog(null, "两次输入的密码不一致!", "错误提示", JOptionPane.ERROR_MESSAGE);
                }
            }catch (Exception t){
                JOptionPane.showMessageDialog(null, "注册失败!", "错误提示", JOptionPane.ERROR_MESSAGE);
            }
        }
    }
    // 监听类,负责处理重置按钮
    public static class ResetListener implements ActionListener {
        // 重写actionPerFormed()方法,重置组件内容事件处理方法
        public void actionPerformed(ActionEvent e) {
            // 清空姓名、密码、确认密码内容
            try {
                txtName.setText("");
                txtPwd.setText("");
                txtRePwd.setText("");
                // 重置单选按钮为未选择
                rbMale.setSelected(false);
                rbFemale.setSelected(false);
                // 重置所有的复选按钮为未选择
                ckbRead.setSelected(false);
                ckbNet.setSelected(false);
                ckbSwim.setSelected(false);
                ckbTour.setSelected(false);
                // 清空地址栏
                txtAdress.setText("");
                // 重置组合框为未选择状态
                cmbDegree.setSelectedIndex(0);
            }catch (Exception t){
                JOptionPane.showMessageDialog(null, "重置失败!", "错误提示", JOptionPane.ERROR_MESSAGE);
            }
        }
    }
}

ClientFrame类实现了客户端的操作界面

package com.qst.dms.ui;
import com.qst.dms.entity.*;
import com.qst.dms.net.Request;
import com.qst.dms.net.Response;
import com.qst.dms.service.DmsNetService;
import com.qst.dms.service.LogRecService;
import com.qst.dms.service.TransportService;
import com.qst.dms.util.Config;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
public class ClientFrame extends JFrame {
    //菜单
    private JMenuBar menuBar;//包含多个菜单
    private JMenu oper, help, matchMenu;
    private JMenuItem mGather, mSave, mSend, mShow, mCheck, mHelp, mLog, mTransport, mExit;
    //工具栏mShow,showBtn
    private JToolBar toolBar;
    private JButton gatherBtn, logBtn, transportBtn, saveBtn, sendBtn, showBtn;
    //数据采集和显示卡片布局组件
    private JPanel p;//数据采集和显示的界面面板,里面采用CardLayout布局,分别显示采集界面和显示界面
    private JTabbedPane jGather, jShow;
    private CardLayout card;
    //日志数据采集组件
    private JTextField txtLogId, txtName, txtLocation, txtIP;
    private JRadioButton rbLogin, rbLogout;
    private JButton btnLogConfirm, btnLogReset;
    //物流数据采集组件
    private JTextField txtTransId, txtAdress, txtHandler, txtReceiver;
    private JComboBox<String> cmbTanStatus;
    private JButton btnTranConfirm, btnTranReset;
    private JTable logTable;//日志原始数据显示Table
    private JTable transTable;//物流原始数据显示Table
    //日志数据存储集合
    private ArrayList<LogRec> logList = new ArrayList<>();
    private ArrayList<MatchedLogRec> matchLogList = new ArrayList<>();
    //物流数据存储集合
    private ArrayList<Transport> transList = new ArrayList<>();
    private ArrayList<MatchedTransport> matchTransList = new ArrayList<>();
    //日志与物流业务对象
    private LogRecService logRecService = new LogRecService();
    private TransportService transService = new TransportService();
    private String serverIp;//服务端IP
    private int serverPort;//服务端端口
    //客户端配置文件
    private final static String CONFIG_FILE = "config/client.properties";
    private void initConfig() {
        try {
            //通过Properties类获取配置文件中的属性赋值给serverPort和serverIp
            Properties p = new Properties();
            //加载配置类
            p.load(new FileInputStream(CONFIG_FILE));
            serverIp = p.getProperty("host");
            serverPort = Integer.parseInt(p.getProperty("port"));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    // 构造方法
    public ClientFrame() {
        // TODO Auto-generated constructor stub
        super("DMS客户端");//给窗口一个名称,显示左上角
        ImageIcon icon = new ImageIcon("images\\dms.png");
        this.setIconImage(icon.getImage());
        initConfig();//读取配置文件
        initMenu();//初始化菜单
        initToolBar();//初始化工具栏
//--------数据采集界面的设计----------
        //后面补充代码
        card = new CardLayout();
        p = new JPanel(card);
        this.getContentPane().add(p, BorderLayout.CENTER);
        jGather = new JTabbedPane(JTabbedPane.TOP);
        p.add(jGather, "gather");
        jShow = new JTabbedPane(JTabbedPane.TOP);
        jShow.addTab("日志", new JScrollPane());
        jShow.addTab("物流", new JScrollPane());
        p.add(jShow, "show");
        initLogGatherGUI();
        initGatherTransport();
        initGatherLogRecShowUI();
        initGatherTransportShowUI();
//--------数据采集界面的设计结束----------
        //数据采集的监听
        mGather.addActionListener(new miGatherListener());//数据采集菜单项增加监听
        gatherBtn.addActionListener(new miGatherListener());//工具栏上采集按钮监听
        //数据显示监听
        mShow.addActionListener(new miShowListener());
        showBtn.addActionListener(new miShowListener());
        //帮助菜单的监听设置
        // 注册监听
        mHelp.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // 显示消息对话框
                JOptionPane.showMessageDialog(null, "本系统实现数据的采集、过滤分析匹配、保存、发送及显示功能", "帮助", JOptionPane.QUESTION_MESSAGE);
            }
        });
        // 注册监听
        mCheck.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // 显示消息对话框
                JOptionPane.showMessageDialog(null, "版本:1.0版", "关于", JOptionPane.WARNING_MESSAGE);
            }
        });
        //initGatherLogRecShowUI();//日志显示界面初始化
        //initGatherTransportShowUI();//物流采集界面初始化
        // 设置窗体大小
        this.setSize(600, 400);
        // 设置窗口在屏幕中央
        this.setLocationRelativeTo(null);//居中
        // 设置默认的关闭按钮操作为退出程序
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置窗体初始可见
        this.setVisible(true);
    }
    // 初始化菜单的方法
    private void initMenu() {
        //-------系统菜单的初始化开始----------------
        menuBar = new JMenuBar();
        this.setJMenuBar(menuBar);//创建菜单条,并放入到JFrame
        oper = new JMenu("操作");
        help = new JMenu("帮助");
        menuBar.add(oper);
        menuBar.add(help);
        mGather = new JMenuItem("采集数据");
        mGather.addActionListener(new miGatherListener());
        //子菜单
        matchMenu = new JMenu("匹配数据");
        mLog = new JMenuItem("日志数据匹配");
        mLog.addActionListener(new MatchedLogRecListener());
        mTransport = new JMenuItem("物流数据匹配");
        mTransport.addActionListener(new MatchedTransportListener());
        matchMenu.add(mLog);
        matchMenu.add(mTransport);
        mSave = new JMenuItem("保存数据");
        mSave.addActionListener(new SaveActionListener());
        mSend = new JMenuItem("发送数据");
        mSend.addActionListener(new SendActionListener());
        mShow = new JMenuItem("显示数据");
        mExit = new JMenuItem("退出应用");
        mExit.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                System.exit(0);
            }
        });
        oper.add(mGather);
        oper.add(matchMenu);
        oper.add(mSave);
        oper.add(mSend);
        oper.add(mShow);
        oper.add(mExit);
        mCheck = new JMenuItem("关于系统");
        mHelp = new JMenuItem("查看帮助");
        help.add(mCheck);
        help.add(mHelp);
        //-------系统菜单的初始化结束----------------
    }
    // 初始化工具栏的方法
    private void initToolBar() {
        //-------系统工具栏的初始化------------
        toolBar = new JToolBar();
        ImageIcon icon1 = new ImageIcon("images\\gatherData.png");
        gatherBtn = new JButton("采集数据", icon1);
        gatherBtn.addActionListener(new miGatherListener());
        ImageIcon icon2 = new ImageIcon("images\\matchData.png");
        logBtn = new JButton("日志数据匹配", icon2);
        logBtn.addActionListener(new MatchedLogRecListener());//-----------------
        ImageIcon icon3 = new ImageIcon("images\\matchData.png");
        transportBtn = new JButton("物流数据匹配", icon3);
        transportBtn.addActionListener(new MatchedTransportListener());//------------
        ImageIcon icon4 = new ImageIcon("images\\saveData.png");
        saveBtn = new JButton("保存数据", icon4);
        saveBtn.addActionListener(new SaveActionListener());
        ImageIcon icon5 = new ImageIcon("images\\sendData.png");
        sendBtn = new JButton("发送数据", icon5);
        sendBtn.addActionListener(new SendActionListener());
        ImageIcon icon6 = new ImageIcon("images\\showData.png");
        showBtn = new JButton("显示数据", icon6);
        toolBar.add(gatherBtn);
        toolBar.add(logBtn);
        toolBar.add(transportBtn);
        toolBar.add(saveBtn);
        toolBar.add(sendBtn);
        toolBar.add(showBtn);
        //JFrame默认有个JPanel
        this.getContentPane().add(toolBar, BorderLayout.NORTH);
        //-------系统工具栏的初始化结束------------
    }
    // 初始化日志数据采集界面的方法
    private void initLogGatherGUI() {
        JPanel pLog = new JPanel();
        jGather.addTab("日志", pLog);
        pLog.setLayout(new BoxLayout(pLog, BoxLayout.Y_AXIS));
        JPanel pLogId = new JPanel();
        pLog.add(pLogId);
        pLogId.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        JLabel lblLogId = new JLabel("日志ID:");
        pLogId.add(lblLogId);
        txtLogId = new JTextField();
        txtLogId.setPreferredSize(new Dimension(100, 20));
        pLogId.add(txtLogId);
        JPanel pName = new JPanel();
        pLog.add(pName);
        pName.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        JLabel lblName = new JLabel("用户名:");
        pName.add(lblName);
        txtName = new JTextField();
        txtName.setPreferredSize(new Dimension(100, 20));
        pName.add(txtName);
        JPanel pLocation = new JPanel();
        pLog.add(pLocation);
        JLabel lblLocation = new JLabel("登录地点:");
        pLocation.add(lblLocation);
        txtLocation = new JTextField();
        txtLocation.setPreferredSize(new Dimension(100, 20));
        pLocation.add(txtLocation);
        JPanel pIP = new JPanel();
        pLog.add(pIP);
        JLabel lblIP = new JLabel("登录IP:");
        pIP.add(lblIP);
        txtIP = new JTextField();
        txtIP.setPreferredSize(new Dimension(100, 20));
        pIP.add(txtIP);
        JPanel pLogStatus = new JPanel();
        pLog.add(pLogStatus);
        JLabel lblLogStatus = new JLabel("登录状态:");
        pLogStatus.add(lblLogStatus);
        rbLogin = new JRadioButton("登录");
        pLogStatus.add(rbLogin);
        rbLogin.setSelected(true);
        rbLogout = new JRadioButton("登出");
        pLogStatus.add(rbLogout);
        ButtonGroup bg = new ButtonGroup();
        bg.add(rbLogin);
        bg.add(rbLogout);
        JPanel pLogButton = new JPanel();
        pLog.add(pLogButton);
        btnLogConfirm = new JButton("确认");
        // 添加确认按钮监听
        btnLogConfirm.addActionListener(new GatherLogListener());
        pLogButton.add(btnLogConfirm);
        btnLogReset = new JButton("重置");
        // 添加重置按钮监听
        btnLogReset.addActionListener(new ResetListener());
        pLogButton.add(btnLogReset);
    }
    // 初始化物流数据采集界面的方法
    private void initGatherTransport() {
        //-----物流数据采集详情界面------
        JPanel pTran = new JPanel();
        jGather.addTab("物流", new JScrollPane(pTran));
        pTran.setLayout(new BoxLayout(pTran, BoxLayout.Y_AXIS));
        JPanel pTransId = new JPanel();
        pTran.add(pTransId);
        JLabel lblTransId = new JLabel("物流ID: ");
        pTransId.add(lblTransId);
        txtTransId = new JTextField();
        txtTransId.setPreferredSize(new Dimension(100, 20));
        pTransId.add(txtTransId);
        JPanel pAdress = new JPanel();
        pTran.add(pAdress);
        JLabel lblAdress = new JLabel("目的地:");
        pAdress.add(lblAdress);
        txtAdress = new JTextField();
        txtAdress.setPreferredSize(new Dimension(100, 20));
        pAdress.add(txtAdress);
        JPanel pHandler = new JPanel();
        pTran.add(pHandler);
        JLabel lblHandler = new JLabel("经手人");
        pHandler.add(lblHandler);
        txtHandler = new JTextField();
        txtHandler.setPreferredSize(new Dimension(100, 20));
        pHandler.add(txtHandler);
        JPanel pReceiver = new JPanel();
        pTran.add(pReceiver);
        JLabel lblReceiver = new JLabel("收货人:");
        pReceiver.add(lblReceiver);
        txtReceiver =new JTextField();
        txtReceiver.setPreferredSize(new Dimension(100,20));
        pReceiver.add(txtReceiver);
        JPanel pTranStatus = new JPanel();
        pTran.add(pTranStatus);
        JLabel lblTranStatus =new JLabel("物流状态:");
        pTranStatus.add(lblTranStatus);
        String[] tranStatus = new String[] {"发货中","送货中", "已签收"};
        cmbTanStatus=new JComboBox<String>(tranStatus);
        pTranStatus.add(cmbTanStatus);
        JPanel pTranButton=new JPanel();
        pTran.add(pTranButton);
        btnTranConfirm=new JButton("确认");
        btnTranConfirm.addActionListener(new GatherTransListener());
        pTranButton.add(btnTranConfirm);
        btnTranReset=new JButton("重置");
        btnTranReset.addActionListener(new ResetListener());
        pTranButton.add(btnTranReset);
    }
    private void initGatherLogRecShowUI(){
        JPanel pLog = new JPanel();
        jGather.addTab("日志数据显示", pLog);
        pLog.setLayout(new BoxLayout(pLog, BoxLayout.Y_AXIS));
    }
    private void initGatherTransportShowUI(){
        JPanel pLog = new JPanel();
        jGather.addTab("物流数据显示", pLog);
        pLog.setLayout(new BoxLayout(pLog, BoxLayout.Y_AXIS));
    }
    private void flushGatherLogRecShowUI(){
        DataTableModelFromList<LogRec> logModel = new DataTableModelFromList<>(logList,1);
        JTable logTable = new JTable(logModel);
        jGather.addTab("日志数据显示",new JScrollPane(logTable));
    }
    private  void flushGatherTransportShowUI(){
        DataTableModelFromList<Transport> logModel = new DataTableModelFromList<>(transList,2);
        JTable transTable = new JTable(logModel);
        jGather.addTab("物流数据显示",new JScrollPane(transTable));
    }
    // 数据采集监听类
    private class miGatherListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e){
            card.show(p, "gather");
        }
    }
    // 匹配日志信息监听类
    private class MatchedLogRecListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            //参考前面字符控制界面,自己完成代码
            try {
                if(LogRecService.readLogRecs().size()>0){
                    JOptionPane.showMessageDialog(null, "日志数据匹配成功!", "提示", JOptionPane.INFORMATION_MESSAGE);
                } else{
                    JOptionPane.showMessageDialog(null, "日志数据匹配失败!", "警告" , JOptionPane. WARNING_MESSAGE);
                }
            }catch (Exception t){
                JOptionPane.showMessageDialog(null, "日志数据匹配失败!", "警告" , JOptionPane. WARNING_MESSAGE);
            }
        }
    }
    // 匹配物流信息监听类
    private class MatchedTransportListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            //参考前面字符控制界面,自己完成代码
            try {
                if (TransportService.readTransports().size()>0) {
                    JOptionPane.showMessageDialog(null, "物流数据匹配成功!", "提示", JOptionPane.INFORMATION_MESSAGE);
                }else{
                    JOptionPane.showMessageDialog(null, "物流数据匹配失败!", "警告", JOptionPane.WARNING_MESSAGE);
                }
            } catch (Exception t) {
                JOptionPane.showMessageDialog(null, "物流数据匹配失败!", "警告", JOptionPane.WARNING_MESSAGE);
            }
        }
    }
    private class SaveActionListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                LogRecService.saveLogRec(logList);
                TransportService.saveTransport(transList);
                logList.clear();
                transList.clear();
                JOptionPane.showMessageDialog(null, "保存成功!", "提示" , JOptionPane. INFORMATION_MESSAGE);
            }catch (Exception t){
                JOptionPane.showMessageDialog(null, "保存失败!", "警告" , JOptionPane. WARNING_MESSAGE);
            }
        }
    }
    private class SendActionListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            List<MatchedLogRec> matchedlogs = LogRecService.readMatchLogRec();
            List<? extends MatchedDataBase> matchedDataList1 = new ArrayList<>(matchedlogs);
            try {
                // 创建一个Socket并连接到服务器
                Socket socket = new Socket(serverIp, serverPort);
                Date time = new Date();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String formattedDate = dateFormat.format(time);
                // 发送请求
                Request request = new Request(formattedDate,"localhost",Request.DATA_TYPE_LOGREC, (List<MatchedDataBase>)matchedDataList1);
                //System.out.println(request);
                DmsNetService.sendRequest(socket, request);
                System.out.println("发送请求: " + request);
                // 接收响应
                Response response = DmsNetService.receiveResponse(socket);
                System.out.println("接收响应: " + response);
                // 关闭Socket连接
                socket.close();
            } catch (IOException | ClassNotFoundException t) {
                t.printStackTrace();
            }
            List<MatchedTransport> matchedtrans = TransportService.readMatchTransport();
            List<? extends MatchedDataBase> matchedDataList2 = new ArrayList<>(matchedtrans);
            try {
                // 创建一个Socket并连接到服务器
                Socket socket = new Socket(serverIp, serverPort);
                Date time = new Date();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String formattedDate = dateFormat.format(time);
                // 发送请求
                Request request = new Request(formattedDate,"localhost",Request.DATA_TYPE_LOGREC, (List<MatchedDataBase>)matchedDataList2);
                //System.out.println(request);
                DmsNetService.sendRequest(socket, request);
                System.out.println("发送请求: " + request);
                // 接收响应
                Response response = DmsNetService.receiveResponse(socket);
                System.out.println("接收响应: " + response);
                // 关闭Socket连接
                socket.close();
            } catch (IOException | ClassNotFoundException t) {
                t.printStackTrace();
            }
        }
    }
    // 日志数据采集监听类
    private class GatherLogListener implements ActionListener {
        // 数据采集的事件处理方法
        public void actionPerformed(ActionEvent e) {
            // 获取日志ID
            int id = Integer. parseInt(txtLogId. getText(). trim());
            // 创建当前时间
            Date currentDate = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time = dateFormat.format(currentDate);
            // 获取地址栏地址
            String adress = txtLocation. getText(). trim();
            // 设置数据类型为:采集
            int type = DataBase. GATHER;
            // 获取用户姓名
            String user = txtName. getText(). trim();
            // 获取ip地址
            String ip = txtIP. getText(). trim();
            // 设置日志类型
            int logType = rbLogin. isSelected() ? LogRec. LOG_IN: LogRec. LOG_OUT;
            // 将数据封装到日志对象
            LogRec log = new LogRec(id, time, adress, type, user, ip, logType);
            List<LogRec> same = LogRecService.readLogRecs();
            // 将日志对象添加到日志列表
            for (LogRec t:same){
                if(t.getId()==log.getId()){
                    JOptionPane.showMessageDialog(null, "ID重复!", "警告" , JOptionPane. WARNING_MESSAGE);
                    return;
                }
            }
            for (LogRec t:logList){
                if(t.getId()==log.getId()){
                    JOptionPane.showMessageDialog(null, "ID重复!", "警告" , JOptionPane. WARNING_MESSAGE);
                    return;
                }
            }
            logList.add(log);
            // 显示对话框
            JOptionPane.showMessageDialog(null, "日志采集成功!", "提示" , JOptionPane. INFORMATION_MESSAGE);
            jGather.removeAll();
            initLogGatherGUI();
            initGatherTransport();
            flushGatherLogRecShowUI();
            flushGatherTransportShowUI();
            //logTable.updateUI();//更新了JTable的数据来源List,更新JTable界面
        }
    }
    // 物流数据采集监听类
    private class GatherTransListener implements ActionListener {
        // 数据采集的事件处理方法
        public void actionPerformed(ActionEvent e) {
            // 获取物流ID
            int id = Integer. parseInt(txtTransId. getText(). trim());
            // 创建当前时间
            Date currentDate = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time = dateFormat.format(currentDate);
            // 获取地址栏地址
            String adress = txtAdress. getText(). trim();
            // 设置数据类型为: 采集
            int type = DataBase. GATHER;
            // 获取经手人信息
            String handler = txtHandler. getText(). trim();
            // 获取发送人信息
            String reciver = txtReceiver. getText(). trim();
            // 设置物流类型
            int transportType = cmbTanStatus. getSelectedIndex() +1;
            // 将数据包装成物流对象
            Transport trans = new Transport(id, time, adress, type, handler, reciver, transportType);
            List<Transport> same = TransportService.readTransports();
            // 将日志对象添加到日志列表
            for (Transport t : same){
                if(t.getId() == trans.getId()){
                    JOptionPane.showMessageDialog(null, "ID重复!", "警告" , JOptionPane. WARNING_MESSAGE);
                    return;
                }
            }
            for (Transport t : transList){
                if(t.getId() == trans.getId()){
                    JOptionPane.showMessageDialog(null, "ID重复!", "警告" , JOptionPane. WARNING_MESSAGE);
                    return;
                }
            }
            // 将物流对象放入物流列表
            transList. add(trans);
            jGather.removeAll();
            initLogGatherGUI();
            initGatherTransport();
            flushGatherLogRecShowUI();
            flushGatherTransportShowUI();
            //logTable.updateUI();
            // 显示对话框
            JOptionPane. showMessageDialog(null, "物流采集成功!", "提示", JOptionPane.INFORMATION_MESSAGE);
        }
    }
    // 重置按钮监听类
    private class ResetListener implements ActionListener {
        // 重置按钮的事件处理方法
        public void actionPerformed(ActionEvent e) {
            txtName.setText("");
            txtLocation.setText("");
            txtIP.setText("");
            txtAdress.setText("");
            txtHandler.setText("");
            txtReceiver.setText("");
        }
    }
    private  class miShowListener implements  ActionListener{
        @Override
        public void actionPerformed(ActionEvent e){
            card.show(p, "show");
            jShow.removeAll();
            ClientFrame.this.flushMatchedLogTable();
            ClientFrame.this.flushMatchedTransTable();
        }
    }
    private void flushMatchedLogTable(){
        DataTableModelFromList<LogRec> logModel = new DataTableModelFromList<>(logRecService.readLogRecs(),1);
        JTable logTable = new JTable(logModel);
        jShow.addTab("日志",new JScrollPane(logTable));
    }
    private  void flushMatchedTransTable(){
        DataTableModelFromList<Transport> logModel = new DataTableModelFromList<>(transService.readTransports(),2);
        JTable transTable = new JTable(logModel);
        jShow.addTab("物流",new JScrollPane(transTable));
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new LoginFrame();
    }
}

ServerFrame类实现了服务端的操作界面

package com.qst.dms.ui;
import com.qst.dms.entity.*;
import com.qst.dms.net.Request;
import com.qst.dms.net.Response;
import com.qst.dms.service.DmsNetService;
import com.qst.dms.service.LogRecService;
import com.qst.dms.service.TransportService;
import com.qst.dms.util.AppendObjectOutputStream;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
public class ServerFrame extends JFrame{
    // 菜单
    private JMenuBar menuBar;// 包含多个菜单
    private JMenu oper, help;
    private JMenuItem mCheck, mHelp, mExit, mFlush;
    // 显示卡片布局组件
    private JPanel p;// 数据显示的界面面板,里面采用CardLayout布局,分别显示采集界面和显示界面
    private JTabbedPane jShow;
    private CardLayout card;
    private JTable logrecTable;
    private JTable transportTable;
    // 数据服务对象
    private LogRecService logRecService = new LogRecService();
    private TransportService transService = new TransportService();
    private ServerSocket serverSocket;//服务Socket
    private Executor threadPool;//线程池
    private int threadPoolSize =100;//线程池的大小
    private int serverPort = 8000;//服务端口号
    private File tmpFile;//临时文件
    private long saveInterval =5000;//保存数据的间隔时间
    private Thread mdStore;//保存数据的线程对象
    private int queueSize = 100;//队列大小
    private BlockingQueue<MatchedDataBase> queue;//接收数据的队列
    private final static String CONFIG_FILE = "config/server.properties";
    //服务端配置文件
    private void initConfig() {
        try {
            //通过Properties类获取配置文件中的属性赋值给serverPort和serverIp
            Properties p = new Properties();
            //加载配置类
            p.load(new FileInputStream(CONFIG_FILE));
            serverPort = Integer.parseInt(p.getProperty("port"));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    public ServerFrame(){
        super("DMS服务器");// 给窗口一个名称,显示左上角 initConfig();//初始化配置参数
        ImageIcon icon= new ImageIcon("images\\dns.png");
        this.setIconImage(icon.getImage());
        initConfig();
        initMenu();
        // 数据显示界面的设计
        card= new CardLayout();
        p = new JPanel(card);// 显示卡片(JPanel或者 JPanel子典)
        this. getContentPane().add(p, BorderLayout.CENTER);// CardLayout布局的JPanel加到JFrame中 数据表格阻件
        // 数据显示界面的设计(卡片2)一
        jShow = new JTabbedPane(JTabbedPane.TOP);
        transportTable = new JTable();
        logrecTable = new JTable();
        p.add(jShow, "show");
        this.flushMatchedLogTable();
        this.flushMatchedTransTable();
        // 注册监听
        mHelp. addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JOptionPane. showMessageDialog(null,"本系统实现数据的采集、过滤分析匹配、保存、发送总显示功能", "帮助" ,JOptionPane.QUESTION_MESSAGE);
            }
        });
        // 注册监听
        mCheck. addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(null,"版本:1.0版", "关于", JOptionPane. WARNING_MESSAGE);
            }
        });
        // 设置窗体大小
        this.setSize(600, 400);
        // 设置窗口在屏幕中央
        this.setLocationRelativeTo(null);// 居中
        // 设置默认的关闭按钮操作为退出程序
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置窗体初始可见
        this.setVisible(true);
        start();
    }
    private void initMenu(){
        menuBar = new JMenuBar();
        this.setJMenuBar(menuBar);
        oper = new JMenu("操作");
        help = new JMenu("帮助");
        menuBar.add(oper);
        menuBar.add(help);
        mFlush = new JMenuItem("刷新");
        mExit = new JMenuItem("退出应用");
        mExit.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                System. exit(0);
            }
        });
        mFlush.addActionListener(new miShowListener());
        oper.add(mFlush);
        oper.add(mExit);
        mCheck = new JMenuItem("关于系统");
        mHelp = new JMenuItem("查看帮助");
        help.add(mCheck);
        help.add(mHelp);
    }
    private class miShowListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            //切换显示卡片,参考ClientFrame
            card.show(p,"show");
            jShow.removeAll();
            ServerFrame.this.flushMatchedLogTable();
            ServerFrame.this.flushMatchedTransTable();
        }
    }
    private void flushMatchedLogTable(){
        MatchedTableModel logModel = new MatchedTableModel(logRecService.readLogResult(),1);
        JTable logTable = new JTable(logModel);
        jShow.addTab("匹配日志",new JScrollPane(logTable));
    }
    private  void flushMatchedTransTable(){
        MatchedTableModel logModel = new MatchedTableModel(transService.readTransResult(),2);
        JTable transTable = new JTable(logModel);
        jShow.addTab("匹配物流",new JScrollPane(transTable));
    }
    //接收数据从存储队列
    class MatchedDataBaseReceiver implements Runnable {
        Socket s;
        public MatchedDataBaseReceiver(Socket s) {
            this.s = s;
        }
        public void run() {
            try {
                //接收数据存储到数据队列
                Request request = DmsNetService.receiveRequest(s);
                System.out.println("接收请求" + request);
                List<MatchedDataBase> datas = request.getData();
                for(MatchedDataBase data :datas){
                    queue.put(data);
                }
                Date time = new Date();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String formattedDate = dateFormat.format(time);
                //发送响应对象
                Response response = new Response(formattedDate,Response.OK);
                DmsNetService.sendResponse(s,response);
                System.out.println("发送响应:" + response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    class MatchedDataBaseStore extends Thread {
        @Override
        public void run() {
            while (true) {
                try {
                    // 每5秒钟将队列中的数据保存到临时文件
                    try {
                        Thread.sleep(saveInterval);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    tmpFile = new File("tempData.dat");
                    AppendObjectOutputStream.setFile(tmpFile);
                    File file = AppendObjectOutputStream.getFile();
                    FileOutputStream fileOut = new FileOutputStream(file, true);
                    AppendObjectOutputStream objOut = new AppendObjectOutputStream(file);
                    while (!queue.isEmpty()) {
                        // 从队列中取出数据并写入临时文件
                        MatchedDataBase data = queue.poll();
                        objOut.writeObject(data);
                    }
                    objOut.close();
                    fileOut.close();
                    System.out.println("保存成功");
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (tmpFile.exists() && !tmpFile.isDirectory()) {
                    // 如果临时文件存在,则将数据转存到数据库
                    try {
                        storeToDB(tmpFile);
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                    tmpFile.delete();
                }
            }
        }
    }
    public boolean storeToDB(File tmpFile) throws IOException, ClassNotFoundException {
        //从数据文件中读取数据并存储到数据库
        List<MatchedLogRec> matchlogs = new ArrayList<>();
        List<MatchedTransport> matchtrans = new ArrayList<>();
        try {
            AppendObjectOutputStream.setFile(tmpFile);
            File file = AppendObjectOutputStream.getFile();
            if (!file.exists()) {
                file.createNewFile();
            }
            FileInputStream fileIn = new FileInputStream(file);
            // 创建一个ObjectInputStream对象输入流,并连接文件输入流
            ObjectInputStream objIn = new ObjectInputStream(fileIn);
            // 使用异常处理和EOFException异常处理读取结束
            try {
                while (true) {
                    MatchedDataBase data = (MatchedDataBase) objIn.readObject();
                    // 根据具体对象类型将数据添加到对应的列表中
                    if (data instanceof MatchedLogRec) {
                        matchlogs.add((MatchedLogRec) data);
                    } else if (data instanceof MatchedTransport) {
                        matchtrans.add((MatchedTransport) data);
                    }
                }
            } catch (EOFException e) {
                // 读取结束,不做任何操作
            }
            objIn.close();
            fileIn.close();
            System.out.println("————————————————————————————————————————————————————————");
            System.out.println(matchlogs);
            LogRecService.saveLogResult(matchlogs);
            System.out.println("————————————————————————————————————————————————————————");
            System.out.println(matchtrans);
            TransportService.saveTranResult(matchtrans);
            System.out.println("信息读取完成\n");
            //存储成功,返回true
            return true;
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("读取信息发生异常:" + e.getMessage() + "\n");
        }
        //否则返回False
        return false;
    }
    public void start() {
        try{
            //绑定服务器端口号
            serverSocket = new ServerSocket(serverPort);
            //创建线程池对象
            threadPool= Executors.newFixedThreadPool(threadPoolSize);
            queue = new LinkedBlockingQueue<MatchedDataBase>(queueSize);
            //创建并启动数据存储线程
            mdStore = new MatchedDataBaseStore();
            mdStore.start();
            //循环监听网络请求
            while(true){
                //服务器主循环,等待客户的监听
                System.out.println("等待客户的连接");
                Socket socket = serverSocket.accept();
                //有客户连接以后,提交到线程池执行
                System.out.println("提交客户处理线程!");
                threadPool.execute(new MatchedDataBaseReceiver(socket));
            }
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    public static void main(String[] args) {
        new ServerFrame();
    }
}

4. 系统测试

4.1 设置测试数据

用户表

匹配日志表

匹配物流表

客户端

服务端


相关实践学习
MySQL基础-学生管理系统数据库设计
本场景介绍如何使用DMS工具连接RDS,并使用DMS图形化工具创建数据库表。
目录
相关文章
|
9月前
|
前端开发 Java 数据管理
javaWeb基于SSM框架开发的社区医疗数据管理系统【项目源码+数据库脚本+报告】
javaWeb基于SSM框架开发的社区医疗数据管理系统【项目源码+数据库脚本+报告】
129 0
|
9月前
|
数据管理 程序员 人工智能
后台数据管理系统 - 项目架构设计【黑马程序员】
后台数据管理系统 - 项目架构设计【黑马程序员】
302 0
后台数据管理系统 - 项目架构设计【黑马程序员】
|
监控 数据挖掘 数据库
【技能实训】DMS数据挖掘项目(完整程序) 1
【技能实训】DMS数据挖掘项目(完整程序)
157 0
|
存储 数据挖掘 Java
【技能实训】DMS数据挖掘项目-Day15
【技能实训】DMS数据挖掘项目-Day15
91 0
|
数据挖掘 数据库 数据库管理
【技能实训】DMS数据挖掘项目-Day14
【技能实训】DMS数据挖掘项目-Day14
78 1
|
3月前
|
人工智能 关系型数据库 分布式数据库
拥抱Data+AI|“全球第一”雅迪如何实现智能营销?DMS+PolarDB注入数据新活力
针对雅迪“云销通App”的需求与痛点,本文将介绍阿里云瑶池数据库DMS+PolarDB for AI提供的一站式Data+AI解决方案,助力销售人员高效用数,全面提升销售管理效率。
|
3月前
|
关系型数据库 分布式数据库 数据库
云栖大会|从数据到决策:AI时代数据库如何实现高效数据管理?
在2024云栖大会「海量数据的高效存储与管理」专场,阿里云瑶池讲师团携手AMD、FunPlus、太美医疗科技、中石化、平安科技以及小赢科技、迅雷集团的资深技术专家深入分享了阿里云在OLTP方向的最新技术进展和行业最佳实践。
|
4月前
|
存储 人工智能 安全
【荣誉奖项】荣获2024数据治理优秀产品!瓴羊Dataphin联合DAMA发布数据管理技能认证
瓴羊Dataphin连续俩年获得DAMA年度优秀数据治理产品奖,本次与DAMA联合发布“DAMA x 瓴羊 数据管理技能认证”,助力提升全民数据素养。
218 0
【荣誉奖项】荣获2024数据治理优秀产品!瓴羊Dataphin联合DAMA发布数据管理技能认证
|
4月前
|
数据采集 安全 数据管理
通信行业数据治理:如何实现高效、安全的数据管理?
在未来的发展中,通信行业的企业应加强数据治理意识,提高数据治理能力;同时,积极开展跨行业的合作创新,共同推动行业的繁荣与发展。相信在不久的将来,通信行业将迎来更加美好的明天。
|
6月前
|
Java 测试技术 容器
从零到英雄:Struts 2 最佳实践——你的Web应用开发超级变身指南!
【8月更文挑战第31天】《Struts 2 最佳实践:从设计到部署的全流程指南》深入介绍如何利用 Struts 2 框架从项目设计到部署的全流程。从初始化配置到采用 MVC 设计模式,再到性能优化与测试,本书详细讲解了如何构建高效、稳定的 Web 应用。通过最佳实践和代码示例,帮助读者掌握 Struts 2 的核心功能,并确保应用的安全性和可维护性。无论是在项目初期还是后期运维,本书都是不可或缺的参考指南。
70 0