<React.js, 스프링 부트, AWS로 배우는 웹 개발 101>(김다정 지음)을 따라 TO-DO 앱을 하나 만들 예정이다.
앞으로 쓸 대부분의 포스팅(이미지/글)은 위의 서적을 참고/출처로 작성되었음을 미리 밝힌다.
서버는 일단 프로그램이다.
이 프로그램은 지정된 포트에 소켓을 열고 클라이언트가 연결할 때까지 무한 대기하며 기다린다. 그러다 클라이언트가 연결하면 해당 클라이언트 소켓에서 요청을 받아와 수행하고 응답을 작성해 전달한다.
import java.net.ServerSocket;
import java.net.Socket;
public class WebServer {
public static void main(String[] args) {
new WebServer().run();
}
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(8080)'
while(true) {
try {
Socket client = serverSocket.accept();
new Thread(() -> handleClient(client)).start();
} catch (Exception e) {
e.printStackTrace();
}
}
} catch(Exception e) {
e.printStactTrace();
}
private static void handleClient(Socket client) {
// (1) 클라이언트의 요청 읽어오기
// (2) 클라이언트의 요청에 맞는 작업 수행하기
// (3) 클라이언트에게 응답 작성하기
// (4) 소켓 닫기
}
}
}
아주 간단한 서버에서 클아이언트에게 요청 읽어올 때 / 응답을 작성할 때 파일 트랜스퍼 프로토콜을 사용한다면 FTP 서버가 되는 것이고, 하이퍼텍스트 트랜스퍼 프로토콜을 사용한다면 HTTP 서버가 되는 것이다.
HTTP 서버 중에서도 리소스 파일을 리턴하는 서버를 의미한다.
(이미지)
클라이언트가 localhost:8080/file.html HTTP 요청을 서버로 보내면 정적 웹 서버인 해당 서버가 지정된 디텍터리 경로에서 file.html을 찾아 그 내용을 HTTP 응답 바디에 넣어 전송한다.
이때 서버는 해당 html 파일에 아무 작업도 하지 않고 파일을 있는 그대로 리턴하는데, 그래서! static(정적) 웹 서버인 것이다. 이런 정적 웹 서버의 예로 아파치나 Nginx 등이 있다.
동적 웹 서버는 파일을 있는 그대로 리턴하지 않는다. 요청을 처리한 후 처리한 결과에 따라 응답 바디를 재구성하거나 HTML 템플릿 파일에 결과를 대체해 보낸다.
(이미지)
클라이언트는 요청에 요청 매개 변수를 보낼 수 있다. (매개변수 = 값) 이런 식으로..
이를 확인한 서버는 요청과 매개변수에 맞는 작업을 수행한 후 그 자리에서 html 파일을 구성하거나 템플릿 html 파일에서 적절한 값을 대체하는 방식으로 html을 구성해 리턴한다. → 클라이언트가 누군지, 어떤 매개변수를 보내는지에 따라 같은 요청이라도 다른 응답을 받을 수 있다. → 이 일을 하는 것이 백엔드 → 아파치나 Nginx 같은 서버 프로그램들은 정적 서버이므로.. 소켓 프로그래밍, HTTP 파싱, 스레드 풀 관리 등 모든 것을 새로 다 작성해야 할까? 아님~! 이런 동적 웹 서버 구현을 도와주는 프로그램이 바로 서블릿 엔진
개발자들은 서블릿 엔진을 설치한 후 서블릿 엔진에게 자기가 개발한 비즈니스 로직, 즉 클래스 파일과 해당 클래스 파일을 어느 요청에서 실행해야 하는지 알려줘야 한다. 즉, 서블릿엔진이 이해할 수 있는 형태로 클래스 파일을 작성해야 한다.
(이미지)
서블릿엔진이 이해하는 클래스 → javax.servlet.http.HttpServlet을 상속받는 서브 클래스
스프링부트도 내부적으로 서블릿을 상속 및 구현 해서 서블릿 엔진을 사용한다.