📌 File Class
: 자바에서 특정 경로의 파일에 접근하고 싶을때에 사용
파일 생성, 삭제, 읽기, ...
File file = new File("c:\\"); //c: 를 경로로 하는 새로운 파일 객체를 생성
File (File parent, String child); // 주어진 부모 파일의 경로와 자식 경로로 새로운파일 객체를 생성
File (String parent, String child); // 부모 경로와 자식 경로로 새로운 파일 객체를 생성
💡 File Class Method
.canRead() // 응용 프로그램이 지정된 파일을 읽을 수 있는지 여부를 확인 (Boolean)
.canWrite() // 응용 프로그램이 지정된 파일을 기록할 수 있는지 여부를 확인 (Boolean)
.createNewFile() // 빈 파일을 생성 (Boolean)
.delete() // 지정된 파일을 삭제 (Boolean)
.getName() // 파일의 이름을 반환 (String)
.getAbsolutePath() // 파일의 절대경로를 반환 (String)
.length() // 파일 크기를 바이트 단위로 반환 (Long)
.list() // 디렉터리에 있는 파일을 배열로 반환 (String[])
.mkdir() // 디렉터리 생성 (Boolean)
📌 MVC Pattern
: Model, View, Controller의 약자
하나의 애플리케이션, 프로젝트를 구성할 때 그 구성요소를 세가지의 역할로 구분한 패턴
💡 사용자가 Controller를 조작하면 Controller는 Model을 통해서 데이터를 가져오고,
그 정보를 바탕으로 시각적인 표현을 담당하는 View를 제어해서 사용자에게 전달하게 됨.
✅ Model : 데이터를 가진 객체
데이터는 내부의 상태에 대한 정보를 가질 수도 있고, 모델을 표현하는 이름 속성으로 가질 수 있음. 모델의 상태에변화가 있을때 컨트롤러와 뷰에 이를 알려주고 이를 통해 뷰는 최신의 결과를 보여줄 수 있고, 컨트롤러는 모델의 변화에 따른 적용가능한 명령을 추가, 제거, 수정할 수 있음
1. 사용자가 편집하길 원하는 모든 데이터를 가지고 있어야한다.
2. 뷰나 컨트롤러에 대해 어떤 정보도 알지 말아야한다.
3. 변경이 일어나면, 변경 통지에 대한 처리방법을 구현해야한다.
✅ View : 사용자가 볼 결과물을 생성하기 위해 모델로부터 정보를 얻어옴
1. 모델이 가지고 있는 정보를 따로 저장해서는 안됨
2. 모델이나 컨트롤러와 같이 다른 구성요소를 몰라야함
3. 변경이 일어나면, 변경 통지에 대한 처리 방법을 구현해야함
✅ Controller : 사용자가 접근한 URL에 따라 사용자의 요청사항을 파악한 후에 그 요청에 맞는 데이터를 Model에 의뢰하고, 데이터를 View에 반영해서 사용자에게 알려줌
1. 모델이나 뷰에 대해서 알고 있어야함
2. 모델이나 뷰의 변경을 모니터링해야함
💡 MVC를 써야하는 이유 ?
- 비즈니스 로직과 UI로직을 분리하여 유지보수를 독립적으로 수행 가능
- Model과 View가 다른 컴포넌트들에 종속되지 않아 애플리케이션의 확장성, 유연성에 유리함
- 중복 코딩의 문제점 제거
📌 JavaBean
: 특정한 정보를 가지고 있는 클래스를 표현하는 하나의 규칙
- 데이터를 표현하기 위한 목적을 지니고 있음.
- 이 규칙을 지닌 클래스를 Java Bean 이라고 함.
- 데이터를 표현하는 것을 목적으로 하는 자바 클래스
💡 Java Bean은 쉽게 말해 MVC 패턴에서 데이터를 표현해주는 Model에서 사용하기 위한 표현의 형태
서로 다른 데이터타입을 한 곳에 저장할 수 있다
-> Bean만 전송하면 하나의 parameter로 여러개의 데이터를 전송할 수 있음
🤝 Java Bean의 규약
다음의 규약들이 지켜져야 Bean으로 분류됨
1️⃣ 모든 필드는 private이며, getter/setter 메서드를 통해서만 접근이 가능
2️⃣ 생성자를 명시적으로 작성하지 않음
3️⃣ 데이터 저장소는 field로 선언
📌 DAO, DTO, VO
💡 DAO (Data Access Object)
: DB나 외부 파일 시스템과 같은 영속성 메커니즘에 접근해서 데이터의 CRUD (Create, Read, Update, Delete) 처리를 담당하는 객체
- DB의 상세한 사항을 노출시키지 않고 특정 데이터의 일부 동작을 제공
- DataBase에 접근 하기 위한 로직 & 비지니스 로직을 분리하기 위해 사용
💡 DTO (Data Transfer Object)
: 순수하게 데이터를 담아 계층간으로 전달하는 객체
- 로직이 필요하지 않음
- getter/setter 메소드를 가진 클래스를 의미
💡 VO (Value Object)
: 값 그 자체를 나타내는 객체
- 로직을 포함할 수 있음
- 불변성을 보장하기 위해 생성자를 사용하여야함
- getter 메소드만 가진 클래스를 의미, setter가 존재해선 안됨(불변성)
💡 DTO 와 VO 차이점 ?
VO와 DTO는 Data를 전달하는 객체로 동일한 개념이지만,
VO는 "값 그 자체", DTO는 "Data를 전달"하는 것!
📌 .split()
: 구분자를 기준으로 문자열을 나누어 배열로 반환해주는 메서드
package split;
public class Split {
public static void main(String[] args) {
String[] str = new String[4];
String str1 = new String();
str1 = "Hello,world,my,world";
str = str1.split(","); //문자열을 "," 기준으로 나누어서 배열에 저장
for (int i=0;i<str.length;i++) {
System.out.println(str[i]);
}
}
}
Hello
world
my
world
📌 StringTokenizer Class
: split과 유사하게 문자열을 나누어주는 메소드
String : 문자열을
Tokenizer : 토큰화한다.
토큰은 분리된 문자열조각으로, StringTokenizer 클래스는 하나의 문자열을 여러개의 토큰으로 분리하는 클래스
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
String str = "구분자를 생략하면 공백이 기본 구분자가 된다.";
StringTokenizer st = new StringTokenizer(str);
while (st.hasMoreTokens()) {
System.out.println(st.nextToken()); //구분자 생략
}
}
}
구분자를
생략하면
공백이
기본
구분자가
된다.
💡 split()과 StringTokenizer ?
- split() :
String 클래스의 메소드
지정한 구분자로 문자열을 나눠 배열에 저장
공백 문자열도 포함 - StringTokenizer :
java.util에 포함되어있는 메소드
지정한 한가지 구분자로 문자열을 나눌 수 있음
구분자를 생략하면 공백이 기본 구분자가 됨
제한 조건에 만족할 경우에 Split()보다 더 빠름
1) 구분자가 하나 일경우
2) 하나의 구분자는 유니코드가 아닐 때 (!@#$%^&*()_+?><)
💻 TODO LIST
💻 loader Package
Loader.java
package loader;
import client.UserApp;
public class Loader {
public static void main(String[] args) {
new UserApp();
}
}
💻 client Package
UserApp.java
package client;
import java.util.Scanner;
import server.ServerController;
import java.text.SimpleDateFormat;
import java.util.Date;
//loader에서 연결될 클래스
public class UserApp {
public UserApp() {
this.fontController();
}
//이 밑에서부턴 Loader가 알 필요 없으니 private로 메소드 생성
/* 클라이언트 화면 및 데이터 흐름 제어 */
private void fontController() {
// String loginID = new String();
// String loginPW = new String();
Scanner scanner = new Scanner(System.in); // 사용자 입력 받는 scanner
String[] text = { " Main ", " Loading... ", " Closing... " }; // MainTitle 출력시 출력할 문구의 배열 생성
boolean isLoop = true;
boolean accessResult;
String[] accessInfo = new String[2]; // 로그인과 비밀번호를 저장할 배열 선언
String mainMenu = this.getMainMenu(); // mainMenu (1.TaskList, 2.Task Settings.... )을 만들어 String mainMenu에 저장
this.display(loginTitle());// loginTitle은 맨처음 한번만 출력
ServerController ctl = new ServerController();
while (isLoop) { // 종속관계에서는 boolean값 하나로 반복문 여러개 제어 가능
for (int idx = 0; idx < accessInfo.length; idx++) { // 2번 반복
this.display(this.mainTitle(this.getToday(), text[1])); // mainTitle에 날짜와 text[1](Loading...) 인자로
this.display(this.loginLayout(true, accessInfo[0])); // loginLayout에 true값과 accessInfo[0] (id입력시 id,
// 미입력시 null)
accessInfo[idx] = this.userInput(scanner);// idx = 0일때 accessInfo[0]에 id 입력, idx=1일때 accessInfo[1]에 비밀번호
// 입력
}
this.display(this.loginLayout(false, null)); // loginLayout에 false값과 null값 인자로 넘겨서 출력
/* ClientData 생성 */
String[] itemName = { "id", "password" };
/* 서버에 로그인 정보 전달 */
ctl.controller(this.makeClientData("1", itemName, accessInfo)); //makeClientData로 "serviceCode=1&id=hoonzzang&password=1234"과 같은 String 데이터를 만들어
// controller로 보냄
accessResult = true; // accessResult를 true값으로 가정, 백엔드랑 연동될 부분
this.display(resultPrint(accessResult)); // accessResult가 true면 success출력, accessResult가 false면 fail 출력
if (!accessResult) { // accessResult가 false면(로그인 정보가 틀리면)
accessInfo[0] = null; // accessInfo값 null로 초기화
accessInfo[1] = null; // accessInfo값 null로 초기화
if (this.userInput(scanner).toUpperCase().equals("N")) { // 로그인 정보가 틀렸을때, retry? n(아니오)이면
isLoop = false; // 반복문(isLoop) 탈출
}
} else { // accessResult가 true면(로그인 정보가 맞으면)
while (isLoop) { // 반복문 실행
String menuSelection = new String(); // menuSelection String 객체 선언
this.display(this.mainTitle(this.getToday(), text[0])); // 오늘 날짜와 Main 출력
this.display(mainMenu); // mainMenu 출력 (1.TaskList, 2.Task Settings.... )
menuSelection = this.userInput(scanner); // menuSelection에 사용자 입력 받아서 저장
if (menuSelection.equals("0")) { // 사용자 입력이 0이면..0~4 범위.. 1~4 구현전
isLoop = false; // isLoop를 false로 반복문 탈출
}
}
}
}
this.display(this.mainTitle(this.getToday(), text[2])); // frontController 메서드 종료 직전에 메인타이틀(Closing...) 출력
scanner.close(); // 스캐너 종료
}
private String makeClientData(String serviceCode, String[] item, String[] userData) {
// serviceCode("1")와 String[] itemName = { "id", "password" }, String[] accessInfo {"(id값)","(pw값)"}을 받아
// String "serviceCode=1&id=(id값)&password=(pw값)"으로 반환
StringBuffer clientData = new StringBuffer();
clientData.append("serviceCode=" + serviceCode);
for (int idx = 0; idx < userData.length; idx++) {
clientData.append("&" + item[idx] + "=" + userData[idx]);
}
return clientData.toString();
}
/* 메인 타이틀 제작 */
private String loginTitle() { // loginTitle을 생성하는 객체 선언 -> 로그인시 한번만 출력하기로
StringBuffer title = new StringBuffer(); // String Buffer 선언후
title.append(" ______ _____ ____ _____ \r\n"
+ "/\\__ _\\ /\\ __`\\ /\\ __`\\ /\\ __`\\ \r\n"
+ "\\/_/\\ \\/ \\ \\ \\/\\ \\ \\ \\ \\/\\ \\ \\ \\ \\/\\ \\ \r\n"
+ " \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\\r\n"
+ " \\ \\ \\ \\ \\ \\_\\ \\ \\ \\ \\_\\ \\ \\ \\ \\_\\ \\ \r\n"
+ " \\ \\_\\ \\ \\_____\\ \\ \\____/ \\ \\_____\\ \r\n"
+ " \\/_/ \\/_____/ \\/___/ \\/_____/\n\n");
title.append("\t\t __ ______ _____ ______ \r\n"
+ "\t\t /\\ \\ /\\__ _\\ /\\ __`\\ /\\__ _\\ \r\n"
+ "\t\t \\ \\ \\ \\/_/\\ \\/ \\ \\ \\L\\_\\ \\/_/\\ \\/ \r\n"
+ "\t\t \\ \\ \\ __ \\ \\ \\ \\/_\\__ `\\ \\ \\ \\ \r\n"
+ "\t\t \\ \\ \\L\\ \\ \\_\\ \\__ /\\ \\L\\ \\ \\ \\ \\ \r\n"
+ "\t\t \\ \\____/ /\\_____\\ \\ `\\____\\ \\ \\_\\\r\n"
+ "\t\t \\/___/ \\/_____/ \\/_____/ \\/_/\n\n\n\n\n");
title.append("\t\t\t\t\tDesigned by group_2\n\n\n"); // StringBuffer에 문자열을 append(추가) 한뒤
return title.toString(); // StringBuffer를 String으로 만들어 frontController에 return(반환)
}
private String mainTitle(String date, String text) { // 현재 날짜와 text(" Main ", " Loading... ", " Closing... ")를 받아
// String으로 만들어 반환
StringBuffer title = new StringBuffer();
title.append("\n▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▼▽▼▽▼▽▼▽▼▽▼▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼\n\n\n");
title.append("\tTODO LIST\n\n");
title.append("\t\t\t\t " + date + "\n\n\n");
if (text != "") {
title.append("\t\t\t[" + text + "]\n\n");
}
title.append("▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲\n");
return title.toString();
}
private String resultPrint(boolean isAccess) { // boolean값을 받아 true면 success, false면 fail 출력
StringBuffer accessResult = new StringBuffer();
if (isAccess) { // true면
accessResult.append("\t\t[■■■■■■■■■■■■■■■■■■■■■■■■■■■■■] SUCCESS !\n");
} else { // false면
accessResult.append("\t\t[■■■■■■■■■■ ] FAIL\n");
accessResult.append("▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△ 다시 하시겠습니까? (y/n) : ");
}
return accessResult.toString();
}
/* 로그인 */
private String loginLayout(boolean loginAccess, String accessInfo) { // boolean : 두가지 경우의 수를 true랑 false의 경우로 나눔
StringBuffer loginLayout = new StringBuffer();
if (loginAccess) { // loginAccess true면 (첫번째 경우의 수)
loginLayout.append("\n");
loginLayout.append("▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽ [ LOGIN ] ▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽\n\n");
loginLayout.append("\n");
loginLayout.append("\t\tID\t\tPassword\n\t\t");
loginLayout.append(((accessInfo != null) ? accessInfo + "\t\t" : "")); // accessInfo가 null이 아니면 (값이 있으면),
// accessInfo의 값을 출력, 값이 없으면 출력하지 않음
} else {
loginLayout.append("\n\n"); // loginAccess false면 (두번째 경우의 수)
loginLayout.append("▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△ Connecting ...\n"); // 다 입력하고 false를 넘겨
// 받아 connecting
}
return loginLayout.toString();
}
private String getMainMenu() { // 메인 메뉴 String 객체 생성 메서드
StringBuffer mainPage = new StringBuffer();
mainPage.append("▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼ [ MENU ] ▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽\n\n");
mainPage.append("\t\t1. Task List\n");
mainPage.append("\t\t2. Task Settings\n");
mainPage.append("\t\t3. Modify Task\n");
mainPage.append("\t\t4. Task Status\n\n");
mainPage.append("\t\t0. Exit\n\n");
mainPage.append("▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△△▲△▲△ [ SELECT ] : ");
return mainPage.toString();
}
/* 날짜시간 출력 : LocalDateTime Class + DateTimeFormatter Class */
private String getToday() { // true를 넘겨받음
// String pattern = (isDate) ? "yyyy년 MM월 dd일" : "yyyy-MM-dd HH:mm:ss";
// String pattern = "yyyy년 MM월 dd일";
// return LocalDateTime.now().format(DateTimeFormatter.ofPattern(pattern));
Date today = new Date();
SimpleDateFormat date = new SimpleDateFormat("yyyy년 MM월 dd일");
return date.format(today);
}
/* 출력 */
private void display(String text) {
System.out.print(text);
}
/* 사용자 입력 */
private String userInput(Scanner scanner) {
return scanner.next();
}
}
💻 server Package
Auth.java
package server;
import server.beans.MemberBean;
/* 로그인, 로그아웃, 접속 로그 기록(히스토리) 담당. service class */
public class Auth {
public Auth() {
}
/*
* Job : 로그인
* 1. param : id, password
* 2. id가 DB에 존재 여부 check --> DAO 가 MEMBERS 전체 레코드를 전달 --> 비교
* 2-1 true -> p3
* 2-2 false -> client
* 3. id와 password를 DB와 비교
* 3-1 true -> p4
* 3-2 false -> client
* 4. 접속기록(로그기록) 생성
* 5. client 결과 통보
*/
public void accessCtl(String clientData) {
/*
* serviceCode=1&id=hoonzzang&password=1234
* --> split("&")
* --> {"serviceCode=1", "id=hoonzzang", "password=1234"}[1].split("=") // 1번지는 "id=hoonzzang", =을 기준으로 나눠서 배열로 반환
* --> {"id", "hoonzzang"}[1] // => 1번지는 hoonzzang
* --> MemberBean.setAccessCode [2].split("=") //
* --> {"password", "1234"}[1]
* --> MemberBean.setSecretCode
*/
MemberBean member = this.setMemberBean(clientData);
System.out.println(member.getAccessCode()); //member에 있는 AccessCode를 불러와 출력
System.out.println(member.getSecretCode());//member에 있는 SecretCode를 불러와 출력
}
private MemberBean setMemberBean(String clientData) {
MemberBean member = new MemberBean();
String[] splitData = clientData.split("&"); //clientData &기준으로 나누고 splitData라는 배열에 저장
member.setAccessCode(splitData[1].split("=")[1]); //splitData 배열의 1번지의 값을 "=" 기준으로 나누고 MemberBean의 member에 저장(id)
member.setSecretCode(splitData[2].split("=")[1]); //splitData 배열의 2번지의 값을 "=" 기준으로 나누고 MemberBean의 member에 저장(pw)
return member;
}
/* AccessCode 존재 여부 판단 */
private boolean compareAccessCode() {
return false;
}
/* AccessCode와 SecretCode의 비교 */
private boolean isAuth() {
return false;
}
}
ServerController.java
package server;
//서버단의 시작점
/*클라이언트 요청에 따른 서비스 분기*/
public class ServerController {
public ServerController() {
}
public boolean controller(String clientData) { //UserApp에서 전달받은 "serviceCode=1&id=hoonzzang&password=1234"을
boolean accessResult = false; //일단 false로 지정
String serviceCode = (clientData.split("&")[0]).split("=")[1]; // serviceCode = {"serviceCode","1"} 의 1번지 인덱스이므로 "1"이 된다
/*
* serviceCode=1&id=hoonzzang&password=1234
* --> split("&") &를 기준으로 string을 나눠서
* --> {"serviceCode=1","id=hoonzzang","password=1234"} 배열로 반환
* --> split("=") =을 기준으로 string을 나눠서
* --> {"serviceCode","1"} 배열로 반환
*/
if (serviceCode.equals("1")) { //만약 serviceCode가 "1"이면,
Auth auth = new Auth(); //Auth 생성자 호출
auth.accessCtl(clientData); //auth의 accessctl에 clientData를 보냄 ("serviceCode=1&id=hoonzzang&password=1234")
}
return accessResult; //일단 false로 반환..
}
}
💻 server.beans Package
MemberBean.java
package server.beans;
public class MemberBean {
// 생성자를 명시하지 않음
// 접근 제한자 private
private String accessCode;
private String secretCode;
private String userName;
private String phoneNumber;
private int Activation;
public String getAccessCode() {
return accessCode;
}
public void setAccessCode(String accessCode) {
this.accessCode = accessCode;
}
public String getSecretCode() {
return secretCode;
}
public void setSecretCode(String secretCode) {
this.secretCode = secretCode;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public int getActivation() {
return Activation;
}
public void setActivation(int activation) {
Activation = activation;
}
}
💻 실행결과
______ _____ ____ _____
/\__ _\ /\ __`\ /\ __`\ /\ __`\
\/_/\ \/ \ \ \/\ \ \ \ \/\ \ \ \ \/\ \
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
\ \ \ \ \ \_\ \ \ \ \_\ \ \ \ \_\ \
\ \_\ \ \_____\ \ \____/ \ \_____\
\/_/ \/_____/ \/___/ \/_____/
__ ______ _____ ______
/\ \ /\__ _\ /\ __`\ /\__ _\
\ \ \ \/_/\ \/ \ \ \L\_\ \/_/\ \/
\ \ \ __ \ \ \ \/_\__ `\ \ \ \
\ \ \L\ \ \_\ \__ /\ \L\ \ \ \ \
\ \____/ /\_____\ \ `\____\ \ \_\
\/___/ \/_____/ \/_____/ \/_/
Designed by group_2
▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▼▽▼▽▼▽▼▽▼▽▼▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼
TODO LIST
2022년 10월 25일
[ Loading... ]
▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲
▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽ [ LOGIN ] ▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽
ID Password
asdf
▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▼▽▼▽▼▽▼▽▼▽▼▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼
TODO LIST
2022년 10월 25일
[ Loading... ]
▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲
▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽ [ LOGIN ] ▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽
ID Password
asdf 1234
▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△ Connecting ...
asdf //id 와 password가 출력됨
1234
[■■■■■■■■■■■■■■■■■■■■■■■■■■■■■] SUCCESS !
▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▼▽▼▽▼▽▼▽▼▽▼▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼
TODO LIST
2022년 10월 25일
[ Main ]
▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲
▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼ [ MENU ] ▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽▼▽
1. Task List
2. Task Settings
3. Modify Task
4. Task Status
0. Exit
▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△▲△△▲△▲△ [ SELECT ] :
'JAVA' 카테고리의 다른 글
#18 [Java] substring, object (0) | 2022.10.27 |
---|---|
#17 [Java] ArrayList Class, Generic, try-catch, Buffer, .size() (0) | 2022.10.27 |
#15 [Java] Date Class, .toUpperCase(), .toLowerCase(), (0) | 2022.10.27 |
#14 [Java] (0) | 2022.10.27 |
#13 [Java] 사칙연산 계산기 (0) | 2022.10.27 |
댓글