라우터, 컨트롤러 개념
제목에 라우터, 컨트롤러 개념 링크 걸어 놨다. 저쪽이 설명 더 잘 되어있음
우리가 지금까지 만든 건 프로그램이 아니다. DELETE할 때, SELECT할 때... BANKAPP에서 코드를 바꿀 때마다 지웠다 말았다, 주석도 지웠다 말았다... 이제 안그럴거다. 어떤 요청이 들어오면 A를 실행하고, 어떤 요청이 들어오면 B를 실행하고… (마치 IF처럼..) 그런 프로그램을 만들거고, 그게 바로 라우터다. 우린... 라우터를 만들 것이다. 너 이거해! 하면 DAO 탁 때려주고.. 막 이런
이 자바를 좀 더 자세히 보면 아래와 같다.
MAIN , CONTROLLER, DAO, DB 이 하나하나를 다 ‘레이어’ 라고 부른다
각 레이어는 특정한 역할을 수행하고, 서로 상호작용하면서 전체 시스템을 구성한다.
[ 라우터 ]
클라이언트가 특정 URL에 접속하면 라우터는 해당 URL과 연결된 컨트롤러를 찾아서 실행시킴 (클라이언트의 요청을 컨트롤러로 연결해주는 역할)
[ 컨트롤러 ]
클라이언트로부터 받은 요청을 (DAO에 필요한 데이터를) 처리하고, 이후 DAO가 수행한 작업 결과를 받아와서 응답을 생성, 클라이언트에게 반환한다. (실제로 요청을 처리하고 응답을 생성하는 역할)
데이터베이스랑 상호 작용하는게 DAO의 책임
컨트롤러는 클라이언트의 요청을 받는 애지 데이터베이스와 상호 작용하는게 아님
ex. 택배 기사가 3호로 어떻게 가요? 물어보면 카운터에서 3호로 가는 길을 안내해주죠? 그 카운터가 바로 CONTROLLER.
자원명이 아니라 식별자를 넣을 것! url에?
REST API (지금은 몰라도 O)
자원을 고유한 식별자로 표현하고, HTTP 메소드(GET, POST, PUT, DELETE 등)를 사용하여 해당 자원에 대한 조작을 수행한다. 1. 자원(리소스) 기반 각각의 자원은 고유한 식별자(URI)를 가지며, 이를 통해 접근된다. ex) /users는 사용자 자원에 접근하는 URI 2. HTTP 프로토콜에서 사용되는 메소드 활용 HTTP 메소드(GET, POST, PUT, DELETE 등)를 사용하여 자원에 대한 조작을 수행
GET = 조회(select) || POST = 생성(insert) || PUT = 수정(update) || DELETE =삭제
[ REST API를 사용해 DAO에 접근 ]
REST API를 사용하여 요청을 받아서 DAO에 접근하는 방식으로 개발하면, 클라이언트와 서버 간의 효율적인 통신과 데이터 조작이 가능하다.
REST API는 클라이언트로부터의 요청을 받아들이기 위한 URI을 정의한다. 클라이언트는 HTTP 메소드(GET, POST, PUT, DELETE 등)를 사용하여 해당 URL에 요청을 보냄. 요청을 받은 서버는 해당 요청을 분석하여 필요한 데이터를 추출하고, DAO에 접근하여 데이터베이스 작업을 수행. 이때 DAO는 식별자 또는 요청에 필요한 데이터를 기반으로 데이터베이스에서 데이터를 조회하거나 수정, 삭제 등의 작업을 수행. DAO가 작업을 완료하면, 서버는 클라이언트에게 HTTP 응답으로 결과를 반환. 이 응답은 주로 상태 코드와 함께 데이터를 포함한 JSON, XML 등의 형태로 전송된다. 클라이언트는 이 응답을 받아 결과를 처리하거나 다음 동작을 수행한다.
URL 설계 [ GET, DELETE, PUT, POST = HTTP 프로토콜 메소드 ]
지금 웹 요청이 아니라 앞에 프로토콜이나 도메인은 안 받고,
식별자만 받아서 실습할 것.
즉, /account 나 /acount/10 이런 식으로 요청이 들어올 거다. 이렇게만 받겠다.
[ GET, DELETE ] - 조회, 삭제 select, delete
근데 /account만 딱 적혀 있으면.. 뭘 하라는 건지 모른다. 그래서 달라고 GET을 적어주는 것! account GET! 프로토콜! (/account/10 GET = 10번 내용 줘) (/account GET = account 전체 내용 줘) * DELETE를 사용할 땐.. 뭘 삭제하라는지 꼭!! 꼭!!! 알려줘야 함 account/1 DELETE 이런 식으로. /1을 해줘야 함. 안하면 전체 삭제.....!!! * 이 정보만 보고도 쿼리문을 맞출 수 있겠지? delete from account_tb where number = 1 이런 쿼리문을 만들 수 있잖아! (이거 1< 이거는 무조건!!! 프라이머리 키다. 세계적인 약속이다)
이렇게 요청을 딱 받아서 DAO를 딱 때리는 것 = 레스트 API
GET과 DELETE는 HTTP의 바디 필요 없이 헤더만 있으면 된다,
그치만 응답 받을 땐 꼭 바디 데이터가 있어야겠지?
요청은 바디 없이 하지만 요청한 데이터를 받을 때는 바디가 필요하단 말
[ PUT ] - 수정 update
* PUT은 수정이다. 애도 뭘 수정해야하는지 꼭 말해줘야 함
PUT은 요청 시, 반드시 HTTP 바디가 필요! 실어나를 데이터가 필요하기 때문
[ POST ] - 생성 insert ✓
클라이언트가 서버에게 새로운 데이터를 생성하고자 할 때 사용되며, INSERT 작업과 관련 됨 클라이언트는 POST 요청을 보내면서 서버에게 새로운 데이터를 전달하고, 이 데이터는 요청 본문(BODY)에 담겨서 전송된다. (POST는 '줄게' 라는 약속. 준다는 말 = 계좌를 만든다는 말. INSERT하겠단 말.)
POST는 요청 시, 반드시 HTTP 바디가 필요! 실어나를 데이터가 필요하기 때문
즉, POST에는 BODY가 있어야 된단 말이잖아? 우리가 썼던 쿼리문을 살펴보자 "insert into account_tb(password, balance, created_at) values(?, ?, now())" 쿼리문을 POST 요청으로 보낼 때는 물음표 자리의 값을 바인딩해서 보내야 한다. 즉, 이렇게는 DAO를 못 때린다는 뜻. 일반적으로 쿼리문의 물음표 자리에는 동적으로 변경되는 값들을 넣는다. 이를 위해 POST 요청을 사용하여 본문(body)에 값을 담아서 보내는 것이 일반적인 방법. DAO(Data Access Object)는 데이터베이스와의 상호작용을 담당하는 객체로, 쿼리문을 실행하고 결과를 반환하는 역할을 한다. 하지만 DAO에서 직접 쿼리문을 작성하여 물음표 자리에 값을 넣는 것은 권장 X 클라이언트에서 요청한 값을 컨트롤러(Controller) 등을 통해 전달받아 DAO에 전달할 때, 해당 값을 쿼리문에 바인딩하여 실행하는 방식을 사용 패스워드와 밸런스에 해당하는 값을 BODY에 넣어줘야 한다. (ex) password=1234&balance=500) 그때 요청 기법 = 식별자 요청을 받아서 쿼리로 질의해서 받는다. (보안을 위해서) 데이터베이스(db에 있는 데이터를 가져오는건) 무조건 식별자! (단순히 파일을 들고오는 건 url에 자원명(a.html 같은..)을 쓴다)
[ 바인딩 ]
실행 시점에서 값을 결정해 쿼리문에 넣는 것
바인딩은 주로 식별자(Identifier)를 사용하여 수행된다.
쿼리문에서 바인딩을 하기 위해 사용되는 식별자는 일반적으로 변수나 매개변수
ex) 쿼리문에 "SELECT * FROM users WHERE age > ?"라는 쿼리가 있으면
물음표 자리에는 실행 시점에서 결정될 값을 넣어야 한다.
[ application/x-www-form-urlencoded 형식의 데이터 전송 방식 ]
password=1234&balance=500
* key-value 쌍인 "password"와 "1234" / "balance"와 "500"
* [ = ] 기호는 각각의 key와 value를 구분하고,
* [ & ] 기호는 각각의 key-value 쌍을 구분
실습을 해보자
[ MAIN 코드 ]
method 메소드 (GET, DELETE, PUT, POST 입력용)과
action 식별자 (/account/1 입력용) 2개를 입력 받기 위해 둘 다 만들어줬다.
아직 컨트롤러 만든거 아니다. 일단 여기까지 하고 테스트를 해보자.
[ TEST 에서 실습 ]
GET 요청하고 /account (전체 조회라는 뜻)로 치면 전체 데이터가 나온 것 확인
3번 데이터를 조회하고 싶으면 이거 3이라고 다 바꿔줘야 함.
작동이 되긴 하는데... 수동이다. 그래서 컨트롤러가 필요
[ POST로 전송…하려는데? ]
그런데..... 이렇게 하면 앞에가 패스워드고 뒤에가 밸런스 값인거... 알겟음? 때문에 mime이 중요한 것!!! mime타입을 써 볼 것이다!
MIME 타입 - x-www-form-urlencoded
우린 지금 mime타입 중에서 x-www-form-urlencoded를 써볼 것이다 x-www-form-urlencoded니까... [ password=1234&balance=1000 ] 이렇게 데이터가 들어올 것. 파싱하자!
balance는 INT인데... 통신은 다 String이라서 오류 뜬다. int로 바꿔주자 Integer.parseInt 해준다. .........근데 원래 이렇게 안 짠다. 힘든걸 알아야... 귀한줄 안다 ㅠㅠ
암튼간 바디를 post에서만 받았죠? 그래서 파싱해줌… url에서 받아서 디비에 미는거임 클라이언트가 POST 요청을 보낼 때는 요청의 바디에 데이터를 담아서 서버로 전송하고, 서버는 해당 데이터를 파싱하여 데이터베이스에 저장하거나 처리할 수 있다.
우린 이렇게 쓰지만 고객은 이렇게 못 쓴다. 때문에 form으로 이쁘게 보이도록 만들고, 그 데이터를 [ password=1234&balance=1000 ] 이런 식으로 받는 것.
입력하니까
생성된 것 확인!
(컨트롤러는 아직 안 한) 전체 코드
import dao.BankDAO; import db.DBConnection; import model.Account; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; import java.util.Scanner; public class BankApp { public static void main(String[] args) { //이거 BR로도 만들 수 있다 Scanner sc = new Scanner(System.in); // http://bank.com/account GET // http://bank.com/account/1 GET // http://bank.com/account POST // http://bank.com/account/1 DELETE // http://bank.com/account/1 PUT System.out.println("http 메서드를 입력하세요"); String method = sc.nextLine(); System.out.println("식별자를 입력하세요"); String action = sc.nextLine(); String body = ""; BankDAO bankDAO = new BankDAO(); if (method.equals("GET")) { if (action.equals("/account")) { List<Account> accountList = bankDAO.selectAll(); System.out.println(accountList); } else if (action.equals("/account/1")) { Account account = bankDAO.selectByNumber(1); //지금은 파싱 안하고 강제로 1넣기 System.out.println(account); } } else if (method.equals("POST")) { System.out.println("body 데이터를 입력하세요"); body = sc.nextLine(); // password=1234&balance=1000 String[] st1 = body.split("&"); String password = st1[0].split("=")[1]; int balance = Integer.parseInt(st1[1].split("=")[1]); if (action.equals("/account")) { bankDAO.insert(password,balance); } } else if (method.equals("PUT")) { } else if (method.equals("DELETE")) { } } }
TIP!
www.naver.com?password=1234&balance=500
이거 두 개를 구분하는게 바로 ? 물음표다!
이렇게 받으면 파싱해서 팍~! 쓰면 된다.
오늘 수업 : WAS가 알아서 다 파싱해주니까.. 이걸 해보고 WAS가 얼마나 감사한지 느껴보자
uri = 식별자 = @WebServlet(”/main”) <뭐 이런것
Share article