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 设置测试数据
用户表
匹配日志表
匹配物流表
客户端
服务端