-
[Servlet] 사용자 요청과 Servlet 알아보기Java 2023. 2. 26. 23:25
Spring 프레임워크에 대해 공부하기 전에 웹을 동적으로 구현하는 Servlet에 대해 알아보았습니다.
[ HTTP ]
HTTP는 웹브라우저와 웹서버가 통신할 때 사용하는 통신규약입니다.
사용자가 웹브라우저를 사용하여 서버에서의 결과 데이터를 얻고자 하는 경우 , 웹브라우저는 사용자의 요청 정보를 HTTP 형태로 웹서버에전달합니다.
브라우저와 서버 모두 정해진 규칙인 HTTP 형태로 구현되어야 해당 요청을 정상적으로 읽고 답할 수 있습니다.
두 프로그램 사이를 통신할 수 있게 해주는 HTTP를 두 가지 형태로 나눌 수 있습니다.
(상세 구조에 대한 내용은 생략합니다.)
웹클라이언트에서 웹서버로 보내는 요청은 HTTP Request
요청에 대한 결과로 웹서버에서 보내는 응답은 HTTP Response 입니다.
[ Web Server와 WAS ]
웹브라우저가 생성한 HTTP Request에는 요청이 전달될 서버의 도메인 정보가 포함되어 있습니다.
요청은 네트워크를 통해 웹서버 프로그램으로 전달됩니다.
(해당 글에서는 웹서버와 WAS가 분리된 경우를 가정하여 설명하겠습니다.)
- Web Server
이미지나 html 파일 같은 정적 컨텐츠를 제공하는 리소스 서버입니다. Request 메세지의 URI에 해당하는 컨텐츠를 식별할 수 있습니다.
- WAS
웹서버의 정적인 파일이 아닌 DB 같은 데이터를 사용하여 동적으로 결과를 불러오는 시스템입니다. 웹 컨테이너 (서블릿 컨테이너)가 존재하고, 요청에 해당하는 URL과 매핑된 Servlet 파일을 실행시킵니다.
좀 더 상세하게 표현하자면 웹브라우저로부터 전송된 HTTP Request 요청에 존재하는 URL을 웹 컨테이너에서 파악하고 동적인 컨텐츠라고 판단되면 요청 URL과 매핑된 Servlet 파일을 실행하는 것입니다.
대표적으로 Spring Boot에 내장되어 있는 Tomcat이 있습니다.
[ Servlet (서블릿) ]
앞서 WAS에서 처리해야 할 요청이 들어오면 URL과 매핑된 Servlet 파일을 실행한다고 하였습니다.
그렇다면 서블릿이란 무엇일까요? 서블릿은 자바를 기반으로 만들어진 동적 웹 구현 기술입니다.
웹 컨테이너가 요청 URL에 매핑된 서블릿 파일을 찾아 실행시켜주기 때문에, 개발자는 해당 파일에 코드를 작성만 하면됩니다.
그런데 컨테이너가 요청 URL마다 어떤 파일을 실행하면 되는지 어떻게 판단할 수 있을까요?
미리 작성된 web.xml (배포서술자 파일)을 읽으면 요청마다 매핑된 파일을 찾아서 실행할 수 있습니다.
예전에는 Servlet을 사용할 때, 개발자가 web.xml 파일에 <servlet-mapping>으로 URL과 Servlet 파일을 매핑하였지만 servlet-api.jar의 버전 3.0 이상부터는 xml 파일 별도 등록 없이 @WebServlet(URL) 어노테이션으로 간편하게 매핑 시킬 수 있게 변경되었습니다.
(web.xml 예시)
<servlet> <servlet-name>myurlservlet</servlet-name> <servlet-class>com.duniv.my.urlServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>myurlservlet</servlet-name> <url-pattern>/myurl</url-pattern> </servlet-mapping>
코드에서 개발자가 서블릿을 이용하여 동적 웹 프로그래밍을 하기 위해서는 HTTPServlet을 상속받은 서블릿 파일을 구현해야 합니다.
우리는 Spring 프레임워크의 동작방식을 알기위해 Servlet을 보고있으니, 자세한 프로그래밍 방법은 다루지 않겠습니다.
@WebServlet("myurlservlet") public class UrlServlet extends HttpServlet { ... }
이렇게 요청에 해당하는 코드를 작성해두었으니 사용자에게 요청을 받아볼 수 있을 것 같습니다.
어떠한 과정을 통해 요청이 처리되는지는 다음과 같습니다.
[ 웹 브라우저 요청 - 응답 동작 과정 ]
- 웹 브라우저를 통해 사용자의 HTTP 요청이 URL에 맞는 웹서버로 전달된다.
- 웹서버에서 해당 요청이 Servlet 호출이 필요한 URL인지 판단하고, 필요한 경우 WAS (웹 컨테이너)로 요청을 전달한다.
- 웹 컨테이너는 사용자로부터의 요청 정보를 저장하는 Reqeust 객체와, 응답을 보낼 Response 객체를 생성한다.
- 배포서술자를 기반으로 해당 요청이 어떤 서블릿 클래스를 실행해야 하는지 확인한다.
- 필요한 서블릿 클래스의 인스턴스가 생성되지 않은 경우 (= 웹 컨테이너가 첫 실행된 경우 혹은 해당 서블릿에 대한 첫 번째 클라이언트 요청인 경우 (설정으로 어떤 경우에 인스턴스가 생성될지 선택 가능))
- 서블릿의 인스턴스는 웹 컨테이너에 하나만 존재하여, Servlet별 init함수는 컨테이너가 실행된 후 한 번만 실행된다. (= 서블릿 전체에서 공유하는 자원)
- 이렇게 첫 요청으로 init() 메소드를 실행하여 인스턴스 생성이 완료되거나, 이미 인스턴스가 생성되어 있으면 요청 하나에 해당하는 스레드 하나를 생성한다.
- 앞서 사용자의 요청이 저장되어 있는 HttpRequest와 사용자에게 전달할 HttpResponse 객체를 service 메소드의 매개변수로 전달한다.
- service() 호출
스레드가 생성되면 스레드에서 service() 메소드를 호출한다 (요청 하나 당 service 메소드를 한 번 호출). HTTP 요청 방식에 따라 서블릿 클래스의 doGet 혹은 doPost 메소드를 실행한다. - 정상적으로 완료된 메소드는 Response 객체에 결과를 담고 웹 컨테이너가 http Response 형태로 웹서버로 전송한다. 웹서버는 전송받은 Response 객체를 사용자 브라우저로 전송하고, 사용자는 동적으로 생성된 결과를 전달받는다.
- 웹 컨테이너는 Request, Response 객체를 소멸하고 스레드를 종료한다.
위와 같은 과정을 통해 요청 URL을 찾고 매핑된 서블릿 파일을 실행하고, doGet 혹은 doPost 메소드로 요청을 전달하여 동적인 데이터를 생성하게됩니다.
'Java' 카테고리의 다른 글
Java의 Stack과 Queue 들여다보기 (0) 2023.03.11