1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | package card.validator.client; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.security.NoSuchAlgorithmException; import card.validator.utils.Log; public class ValidatorLauncher { private static String DONE = "DONE"; private static String LOGOUT = "LOGOUT"; public static void main(String[] args) throws IOException, NoSuchAlgorithmException { String userId = ""; String busId = ""; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String readLine; while((readLine = br.readLine()) != null) { String[] idPass = readLine.split(" "); if(idPass.length < 2) continue; boolean result = UserLoginValidator.userLoginCheck(idPass[0], idPass[1]); if(result) { System.out.println("LOGIN SUCCESS"); userId = idPass[0]; break; }else{ System.out.println("LOGIN FAIL"); } } Log.debug("Login ID : " + userId); BusCardValidator busValidator = null; while((readLine = br.readLine()) != null) { if(LOGOUT.equals(readLine)) { ResultFileSender fileSender = new ResultFileSender(userId); fileSender.fileSend(); Log.debug("FileSend & Backup End"); break; } else{ busId = readLine; busValidator = new BusCardValidator(userId, busId); } while((readLine = br.readLine()) != null) { if(DONE.equals(readLine.trim())) { Log.debug(busId + " is DONE"); break; }else{ if(readLine.length() < 30) continue; busValidator.cardValidate(readLine); } } } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | package card.validator.client; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.security.NoSuchAlgorithmException; import card.validator.utils.CardUtility; public class UserLoginValidator { /* 로그인 LOG 정상, 오류 발생시 오류 */ public static boolean userLoginCheck(String id, String passwd) { File file = new File("../CLIENT/INSPECTOR.TXT"); boolean findFlag = false; boolean isPasswdCollrect = false; try { BufferedReader br = new BufferedReader(new FileReader(file)); String readLine; while((readLine = br.readLine()) != null) { String[] strArry = readLine.split(" "); if(strArry[0].equals(id)) { findFlag = true; if(strArry[1].equals(CardUtility.passwordEncryption(passwd))) { isPasswdCollrect = true; break; } } } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(findFlag && isPasswdCollrect) { return true; }else{ return false; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | package card.validator.client; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; public class ResultFileSender { private final static String IP = "127.0.0.1"; private final static int PORT = 1234; private Socket socket; private String dirName; public ResultFileSender(String dirName) { this.dirName = dirName; } public void fileSend() { File dir = new File("../" + this.dirName); if(!dir.exists()) return; File[] fileList = dir.listFiles(); for(File file : fileList) { try { this.socket = new Socket(IP, PORT); byte[] buffer = new byte[512]; byte[] fileName = file.getName().getBytes(); System.arraycopy(fileName, 0, buffer, 0, fileName.length); BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); BufferedOutputStream bos = new BufferedOutputStream(this.socket.getOutputStream()); int readLen; /* file name Send */ bos.write(buffer, 0, 512); bos.flush(); while((readLen = bis.read(buffer)) != -1) { bos.write(buffer, 0, readLen); } bos.close(); bis.close(); socket.close(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } File backDir = new File("../BACKUP"); if(!backDir.exists()) backDir.mkdir(); /* 파일 이동 */ for(File file : fileList) { file.renameTo(new File("../BACKUP/" + file.getName())); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package card.validator.utils; public class Log { private static boolean flag = false; public static void debug(String arg) { if(flag)System.out.println(arg); } public static void debug(int arg) { if(flag)System.out.println(arg); } public static void debug(double arg) { if(flag)System.out.println(arg); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | package card.validator.utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.sql.Date; import java.text.ParseException; import java.text.SimpleDateFormat; public class CardUtility { public static long hourDiff(String strTime2, String strTime1) throws ParseException { SimpleDateFormat transFormat = new SimpleDateFormat("yyyyMMddHHmmss"); java.util.Date date1 = transFormat.parse(strTime1); java.util.Date date2 = transFormat.parse(strTime2); long gap = date2.getTime() - date1.getTime(); return gap/60/60/1000; } public static String passwordEncryption(String input) throws NoSuchAlgorithmException { MessageDigest mDigest = MessageDigest.getInstance("SHA-256"); byte[] result = mDigest.digest(input.getBytes()); StringBuffer sb = new StringBuffer(); for (int i = 0; i < result.length; i++) { sb.append(Integer.toString((result[i] & 0xFF) + 0x100, 16).substring(1).toUpperCase()); } return sb.toString(); } public static void intToByte(byte [] buffer, int offset, int num) { buffer[offset + 3] = (byte)(num >> 24); buffer[offset + 2] = (byte)(num >> 16); buffer[offset + 1] = (byte)(num >> 8); buffer[offset + 0] = (byte)(num); } public static int byteToInt(byte [] buffer, int offset) { int nRet = ((((int)buffer[offset+3] & 0xff) << 24) | (((int)buffer[offset+2] & 0xff) << 16) | (((int)buffer[offset+1] & 0xff) << 8) | (((int)buffer[offset] & 0xff))); return nRet; } public static String getCurrentDateTimeString() { long time = System.currentTimeMillis(); SimpleDateFormat dayTime = new SimpleDateFormat("yyyyMMddHHmmss"); String strTime = dayTime.format(new Date(time)); return strTime; } public static String getCurrentDateString() { long time = System.currentTimeMillis(); SimpleDateFormat today = new SimpleDateFormat("yyyyMMdd"); String strToday = today.format(new Date(time)); return strToday; } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package card.validator.server; import java.io.IOException; import card.validator.utils.Log; public class CardServerLauncher { public static void main(String[] args) throws IOException, InterruptedException { CardServer cardServer = new CardServer(); CardServerConsol consol = new CardServerConsol(); Thread fileTransportThread = new Thread(cardServer); Thread consolThread = new Thread(consol); fileTransportThread.start(); consolThread.start(); Log.debug("Colsol is running"); consolThread.join(); cardServer.getServer().close(); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | package card.validator.server; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.Socket; import card.validator.utils.Log; public class CardServerFileTransporter implements Runnable { Socket socket; public CardServerFileTransporter(Socket socket) { this.socket = socket; } @Override public void run() { fileReceiver() ; } public void fileReceiver() { String fileName; byte[] buffer = new byte[512]; int readLen; File dir = new File("../SERVER"); /* 디렉토리 확인 및 생서 */ if(!dir.exists()) dir.mkdir(); try { BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); readLen = bis.read(buffer, 0, 512); if(readLen != -1) { fileName = new String(buffer); } else { return; } String recvFilePath = "../SERVER/" + fileName.trim(); Log.debug("RecvFileName : [" + recvFilePath + "]"); File recvFile = new File(recvFilePath); FileOutputStream fis = new FileOutputStream(recvFile, false); while((readLen = bis.read(buffer)) != -1) { fis.write(buffer, 0, readLen); } fis.flush(); fis.close(); bis.close(); this.socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | package card.validator.server; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import card.validator.utils.CardUtility; import card.validator.utils.Log; public class CardServerConsol implements Runnable { private static final String QUIT = "QUIT"; private static final String REPORT = "REPORT"; @Override public void run() { // TODO Auto-generated method stub BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String command; CardReporter reporter = new CardReporter(); try { while((command = br.readLine()) != null) { if(QUIT.equals(command)) { Log.debug(command); break; } else if(REPORT.equals(command)) { String currentDate = CardUtility.getCurrentDateString(); reporter.makeReport(currentDate); //reporter.makeReport("20180110"); System.out.println("REPORT FINISH"); } else { if(command.length() >= 8) { String[] args = command.split(" "); if(args.length > 1) { if(args[1].equals("C")) { reporter.printReport(args[0], true); }else{ reporter.printReport(args[0], false); } }else{ reporter.printReport(args[0], false); } } } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } Log.debug("Consol is closed"); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | package card.validator.server; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import card.validator.utils.Log; public class CardServer implements Runnable { private static final int PORT = 1234; private ServerSocket server; public CardServer() { try { server = new ServerSocket(PORT); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void readyServer() { ExecutorService exeService = Executors.newFixedThreadPool(10); while(true) { try { Socket socket = server.accept(); CardServerFileTransporter fileTransporter = new CardServerFileTransporter(socket); exeService.execute(fileTransporter); } catch (IOException e) { // TODO Auto-generated catch block //e.printStackTrace(); Log.debug("FileTransporter is closed"); break; } } exeService.shutdown(); } @Override public void run() { // TODO Auto-generated method stub readyServer(); } public ServerSocket getServer() { return server; } public void setServer(ServerSocket server) { this.server = server; } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | package card.validator.server; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; public class CardReporter { /* 검사원ID, 검사 카드 수, 비정상 카드 수 */ /*• Server에서 ‘REPORT’를 입력하면 수신한 파일들 중 현재 날짜의 파일들을 분석하여 Report 파일을 작성하고 * ‘REPORT FINISH’를 출력한다. Report 파일은 ‘../SERVER/’폴더에 저장하고(상대경로 사용), 파일명은 * ‘REPORT_YYYYMMDD.TXT’ * 형태로 한다(YYYYMMDD에는 현재 날짜 사용). • Report 파일의 내용은 다음과 같이 저장한다. 검사원ID 순서로 저장하고, * 각 필드의 구분은 빈 칸으로 한다. (카드 수는 가변 길이임) * [검사원ID] [검사 카드 수] [비정상 카드 수] * ex) INSP_001 20 11 * INSP_002 30 8 * INSP_003 10 3 */ //INSP_007_20180131144552.TXT //INSP_007_20180131143532.TXT //Result format //INSP_007#BUS_004#CARD_001BUS_004N20180110114108#R4#20180131144552 //INSP_007#BUS_004#CARD_002BUS_004N20180131104108#R4#20180131144552 //INSP_007#BUS_004#CARD_003BUS_004F20180110114108#R3#20180131144552 //INSP_007#BUS_004#CARD_004BUS_004N20171122103010#R4#20180131144552 Map<String, CardReportData> report = new HashMap<String, CardReportData>(); public CardReporter() { } public void makeReport(String currentDate) { //Log.debug("currentDate : " + currentDate); File dir = new File("../SERVER"); if(!dir.exists()) return; /* 대상파일 추출 */ File[] fileList = dir.listFiles(); for(File file : fileList) { String fileName = file.getName(); /* 파일명 validate */ if(file.getName().length() < 17) continue; if(currentDate.equals(fileName.substring(9, 17))) { countValidedCard(file); } } writeReportFile(currentDate); } public void writeReportFile(String currentDate) { // 1. ../SERVER에 저장 // 2. REPORT_YYYYMMDD.TXT 파일명 // 3. INSP_003 10 3 파일 포멧 File dir = new File("../SERVER"); if(!dir.exists()) return; File dest = new File("../SERVER/" + "REPORT_" + currentDate + ".TXT"); try { FileWriter fw = new FileWriter(dest); BufferedWriter bw = new BufferedWriter(fw); Set<String> keys = this.report.keySet(); List<String> keyList = new ArrayList<String>(); Iterator<String> iter = keys.iterator(); while(iter.hasNext()) { keyList.add(iter.next()); } Collections.sort(keyList); iter = keyList.iterator(); while(iter.hasNext()) { CardReportData reportData = this.report.get(iter.next()); String str = String.format("%s %d %d", reportData.validatorId, reportData.cardCnt, reportData.errorCnt); bw.write(str); bw.newLine(); } bw.flush(); bw.close(); fw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void printReport(String reportDate, boolean option) { // Server 콘솔 화면에서 날짜를 입력 받으면 해당 날짜에 해당하는 Report를 출력한다. // 날짜만 입력하면 Report 파일 내용 그대로 출력하고, 날짜 한 칸 뒤에 ‘C’를 추가하면 ‘검사 카드 수’로 // 내림차순으로 정렬하여 출력한다. File dir = new File("../SERVER"); if(!dir.exists()) return; File reportFile = new File("../SERVER/" + "REPORT_" + reportDate + ".TXT"); if(!reportFile.exists()) return; try { BufferedReader br = new BufferedReader(new FileReader(reportFile)); if(option == false) { String readLine; while((readLine = br.readLine()) != null) { System.out.println(readLine); } } else { String readLine; List<CardReportData> list = new ArrayList<CardReportData>(); while((readLine = br.readLine()) != null) { //INSP_003 10 3 String[] strArray = readLine.split(" "); CardReportData data = new CardReportData(); data.validatorId = strArray[0].trim(); data.cardCnt = Integer.parseInt(strArray[1].trim()); data.errorCnt = Integer.parseInt(strArray[2].trim()); list.add(data); } Collections.sort(list, new Comparator<CardReportData>(){ @Override public int compare(CardReportData o1, CardReportData o2) { // TODO Auto-generated method stub return (o1.cardCnt - o2.cardCnt) * -1; } }); Iterator<CardReportData> iter = list.iterator(); while(iter.hasNext()) { CardReportData data = iter.next(); String outStr = String.format("%s %d %d", data.validatorId, data.cardCnt, data.errorCnt); System.out.println(outStr); } } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void countValidedCard(File file) { try { BufferedReader bw = new BufferedReader(new FileReader(file)); String readLine; while((readLine = bw.readLine()) != null) { //INSP_007#BUS_004#CARD_004BUS_004N20171122103010#R4#20180131144552 String[] strArray = readLine.split("#"); // for(String str : strArray) { // Log.debug("Splite " + str); // } // // Log.debug("ID : " + strArray[0]); // Log.debug("READ : " + readLine); CardReportData reportData = this.report.get(strArray[0].trim()); if(reportData == null) { reportData = new CardReportData(); reportData.validatorId = strArray[0].trim(); this.report.put(reportData.validatorId, reportData); } /* 카운팅 */ reportData.cardCnt++; if("R1".equals(strArray[3].trim()) == false) { reportData.errorCnt++; } } bw.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //Log.debug(this.report.toString()); } } | cs |
1 2 3 4 5 6 7 8 9 10 | package card.validator.server; public class CardReportData { /* 검사원ID, 검사 카드 수, 비정상 카드 수 */ public String validatorId; public int cardCnt; public int errorCnt; } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | package card.validator.client; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.text.ParseException; import card.validator.utils.CardUtility; import card.validator.utils.Log; public class BusCardValidator { public String busId; public String validatorId; public File resultFile; public boolean cardValidate(String cardInfoStr) { BusCardInfo busCardInfo = new BusCardInfo(cardInfoStr); Log.debug(busCardInfo.toString()); /* -최근 이용 버스 ID가 승차한 버스의 ID와 일치하는가 - 최근 승차/하차 여부 정보가 ‘승차’인가 - 최근 승차 시각이 현재 시각과 비교하여 3시간 이내인가 (버스가 출발지에서 종점까지 3시간 - 이내 도착하므로 3시간이 초과될 경우는 없음) */ /* R1 : 정상 R2 : 버스ID 정보가 다름 R3 : 승차 정보 없음 R4 : 승차 시각(3시간) 초과 */ // 카드 ID 텍스트 // 8 // CARD_001, CARD_002, … // 최근 이용 버스 ID // 텍스트 // 7 // BUS_001, BUS_002, … // 최근 승차/하차 여부 // CHAR // 1 // ‘N’ : 승차, ‘F’ : 하차 // 승차 시각 // 텍스트 // 14 // YYYYMMDDHHmmSS형태 String result = cardCheck(busCardInfo); Log.debug(result); try { BufferedWriter bw = new BufferedWriter(new FileWriter(this.resultFile, true)); //[검사원ID]#[버스ID]#[카드데이터]#[검사 결과 코드]#[검사시각] //INSP_001#BUS_001# CARD_001BUS_001N20171019093610#R1#20171023164905 String resultStr = String.format("%s#%s#%s#%s#%s", this.validatorId, this.busId, cardInfoStr, result, CardUtility.getCurrentDateTimeString()); Log.debug(resultStr); bw.write(resultStr); bw.newLine(); bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } public String cardCheck(BusCardInfo cardInfo) { if(!busId.equals(cardInfo.busId)) { //Log.debug("BusId : " + busId + " CardBusId : " +cardInfo.busId ); return "R2"; } if(!cardInfo.rideCode.equals("N")) { //Log.debug("RideCode : " + cardInfo.rideCode); return "R3"; } String currentTime = CardUtility.getCurrentDateTimeString(); try { //Log.debug("diff hour " + CardUtility.hourDiff(currentTime, cardInfo.lastRideTime)); if( CardUtility.hourDiff(currentTime, cardInfo.lastRideTime) > 3 ) { return "R4"; } } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } return "R1"; } public BusCardValidator(String validatorId, String busId) { this.busId = busId; this.validatorId = validatorId; File dir = new File("../" + validatorId); if(!dir.exists()) dir.mkdir(); this.resultFile = new File("../" + validatorId + "/"+ validatorId + "_" + CardUtility.getCurrentDateTimeString() + ".TXT"); //Log.debug("Result file : " + this.resultFile); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package card.validator.client; public class BusCardInfo { //[카드ID(8)][버스ID(7)][승차/하차 코드(1)][최근 승차시각(14)] public String cardId ; public String busId ; public String rideCode; public String lastRideTime; //[카드ID(8)][버스ID(7)][승차/하차 코드(1)][최근 승차시각(14)] // String cardId = cardInfo.substring(0, 7); // String busId = cardInfo.substring(8,15); // String rideCode = cardInfo.substring(15, 16); // String lastRideTime = cardInfo.substring(16,30); public BusCardInfo(String cardInfo) { cardId = cardInfo.substring(0, 8); busId = cardInfo.substring(8,15); rideCode = cardInfo.substring(15, 16); lastRideTime = cardInfo.substring(16,30); } public String toString() { return( "cardId " + cardId + "\n" +"busId " + busId + "\n" +"rideCode " + rideCode + "\n" +"lastRideTime" + lastRideTime+ "\n"); } } | cs |