[Spring] Servlet(서블릿)이란? Servlet, Servlet Container 알아보기
스프링으로 개발을 하다 보면, HttpServletRequest, HttpServletResponse 등 Servlet이라는 단어를 많이 접하고는 합니다.
개발할 때 Servlet을 많이 사용하고는 있지만, 서블릿이 무엇이고, 어떤 역할을 하는지는 잘 알지 못했습니다. 이번 기회에 한 번 알아보고자 합니다.
1. 들어가기 전에
HTML Form으로 클라이언트에서 서버로 데이터를 전송할 때, 서버에서 일어나는 일들을 살펴보면서 Servlet이 하는 역할을 알아봅시다.
✔️ HTML Form으로 데이터를 주고받을 때
클라이언트단에, 다음과 같이 사용자의 이름과 나이를 받는 form이 있다고 합시다. username에 kim, age에 20 이라고 입력 후 전송버튼을 누르면, 웹브라우저에서는 오른쪽과 같은 HTTP 메시지를 생성합니다. 해당 data가 form형식이므로, HTTP 메시지의 Content Type는 application/x-www-form-unreloaded이고, username=kim&age=20 의 형식으로 데이터를 전송합니다.
✔️ 서블릿이 없을 경우, 서버가 해야 할 일들
서버에서는 위에서 보낸 데이터를 받은 다음, 다음과 같은 일들을 수행해야 합니다.
- 서버 TCP/IP 연결 대기, 소켓 연결
- HTTP 요청 메시지를 파싱해서 읽기
- POST 양식, /save URL 인지
- Content-Type 확인
- HTTP 메시지 바디 내용 파싱
- username, age 데이터를 사용할 수 있게 파싱- 저장 프로세스 실행
- 비즈니스 로직 실행
- 데이터베이스에 저장 요청- HTTP 응답 메시지 생성 시작
- HTTP 시작 라인 생성
- Header 생성
- 메시지 바디에 HTML 생성해서 입력- TCP/IP에 응답 전달, 소켓 종료
서블릿이 없다면, 위의 일들을 개발자가 모두 구현해야 합니다. TCP/IP 소켓 연결을 직접 수행하고, URL을 인지하고, Content-Type을 확인한 다음, 받은 데이터(메시지 바디)를 파싱하는 등.. 매우 복잡합니다. 또한 data를 주고받을 때마다 위의 과정을 모두 거쳐야 하기 때문에 불필요한 코드를 많이 발생시킵니다. 위의 과정에서 정작 필요한 과정은 비즈니스 로직을 실행하는 것인데 말입니다. 이런 생각에서 등장한 것이 바로 Servlet(서블릿) 입니다.
2. Servlet(서블릿) 이란?
서블릿에서는 위에서 나열한 일련의 과정(TCP/IP 소켓 연결을 직접 수행하고, Content-Type을 확인한 다음, 받은 데이터(메시지 바디)를 파싱하는 등..)을 대신 수행해줍니다. 서블릿을 이용하면 개발자는 가장 중요한 비즈니스 로직에만 집중하면 됩니다.
✔️ 특징
아래 코드는 서블릿을 사용한 코드입니다.
@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) {
//비즈니스 로직
}
}
코드 설명
- urlPatterns(/hello)의 URL이 호출되면, HelloServlet의 코드가 실행됩니다.
- HTTP 요청 정보는(예제에서 클라이언트 -> 서버로 보낸 값) HttpServletRequest를 통해 관리됩니다.
- HTTP 응답 정보는(예제에서 서버 -> 클라이언트로 보내는 값) HttpServletResponse를 통해 제공합니다.
서블릿을 통해, 개발자는 HTTP 스펙을 보다 편리하게 사용할 수 있습니다.
3. HttpServletRequest, HttpServletResponse
✔️ HttpServletRequest
HttpServletRequest 인터페이스에 대해 살펴보면, HTTP servlet의 request정보를 관리하기 위해 ServletRequest를 상속받고 있습니다. 다양한 메서드가 있는데, 그 중 getParameter를 이용해 클라이언트에서 서버로 넘어온 값을 확인할 수 있습니다. 또한 Enumeration을 반환하는 getHeaders를 이용해서 request 헤더 정보를 알 수 있습니다.
✔️ HttpServletResponse
HttpServletResponse 인터페이스에 대해 살펴보겠습니다. HTTP response를 보내므로, ServletResponse를 상속받고 있습니다. HTTP 헤더와 쿠키에 access하는 메서드들이 있습니다. 서블릿 컨테이너에서 HttpServletResponse객체를 만든 다음, doGet, doPost와 같은 서블릿 서비스 메서드로 만들어 전달합니다.
4. Servlet의 동작과 Servlet Container
✔️ 서블릿의 동작 원리
HTTP 요청이 오면, WAS(Web Application Server, 그림에서 Tomcat)는 Request, Response 객체를 새로 만들어서, 서블릿 객체(예시의 helloServlet)를 호출합니다. 개발자는 Request 객체에서 HTTP 요청 정보를 꺼내서 사용하고, 비즈니스 로직을 수행한 후, Response 객체에 HTTP 응답 정보를 입력해 보내면 됩니다. WAS에서는 Response 객체에 담겨있는 내용으로 HTTP 응답 정보를 생성한 다음, 클라이언트에 결과를 보내줍니다.
✔️ 서블릿 컨테이너
예시에서는 helloServlet만 등장했지만, 추후 saveServlet, deleteServlet 등 다양한 Servlet들이 추가될 여지가 있습니다. 이러한 Servlet들을 생성, 호출 및 관리하는 곳을 서블릿 컨테이너라고 합니다. 톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 하며, 서블릿 객체를 생성, 초기화, 호출, 종료하는 서블릿 생명주기를 관리합니다.
또한, 서블릿 객체는 싱글톤으로 관리됩니다. 고객의 요청이 올 때마다 새로운 helloServlet객체를 계속해서 생성하는 것은 매우 비효율적입니다. 따라서, 최초 로딩 시점에 서블릿 객체를 미리 만들어두고, 필요할 때 마다 꺼내 사용합니다. 모든 고객의 요청은 동일한 서블릿 객체 인스턴스에 접근하기 때문에, 공유 변수를 사용하는 것과 같습니다. 서블릿은 동시 요청을 위한 멀티 쓰레드 처리를 지원하기 때문에, 공유 변수 사용에 대한 Side Effect를 방지할 수 있습니다.
5. 정리 - Servlet의 역할
오늘은 서블릿에 대해 알아보는 시간을 가졌습니다. 서블릿은 HTTP통신 시 개발자를 편리하게 해주는 도구이며, 요청은 HttpServletRequest, 응답은 HttpServletResponse로 주고 받습니다. 다음 시간에는 멀티 쓰레드 처리와 쓰레드 풀에 대해서 알아보겠습니다. 감사합니다!
[참고한 곳]
Author And Source
이 문제에 관하여([Spring] Servlet(서블릿)이란? Servlet, Servlet Container 알아보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@fantastik/64저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)