
스터디카페 커피는 공짜이기 때문에 굉장히 좋아하지만,
퇴근 후 스터디카페에 오면 시간이 늦어서 슬프게도 커피를 마시지 못합니다.
밤에 꿀잠을 자야 다음날 일을 할 수 있기 때문이죠.
김영한 강사님의 Spring MVC 강의에서 서블릿에 관해 다루어 주셨는데, 강의를 참고해서 정리를 해보겠습니다.
김영한 강사님의 스프링 MVC 1편 강의
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 강의 | 김영한 - 인프런
김영한 | , 원리를 알아야 핵심이 보인다!김영한의 스프링 MVC 기본편 👨💻 📌 수강 전 확인해주세요! 본 강의는 자바 스프링 완전 정복 시리즈의 네 번째 강의입니다. 우아한형제들 최연소
www.inflearn.com
목차
- 서블릿이란?
- 서블릿 컨테이너
1. 서블릿이란?
서블릿(Servlet)은 웹페이지를 동적으로 생성하는 서버측 프로그램이라고 위키피디아에서 정의했다. 동적으로 생성한다는 것은 어떠한 요청이 왔을때 그 요쳥에 맞게 처리해주는 행위라고 할 수 있으며 필자는 HTTP 요청 처리 + 뷰 페이지 생성 이 두 가지를 서블릿이 수행하는 대표적인 두 가지라고 생각한다.
서블릿(Servlet)은 클라이언트의 HTTP 요청과 서버의 응답을 다루기 위해 자바에서 제공하는 표준 인터페이스이며, 이를 통해 웹 요청을 구조화되고 확장 가능하게 처리할 수 있도록 지원하는 서버 측 컴포넌트다.
(1). HTTP 요청 처리
클라이언트가 서버로 HTTP 요청을 하게 되면 서블릿 컨테이너는 각 요청마다 thread를 할당하고, 해당 thread는 web.xml(또는 어노테이션)에 정의된 서블렛을 확인 후 매핑된 서블렛을 호출한다.
서블릿 컨테이너는 서블릿을 싱글턴 인스턴스로 관리하고, 클라이언트 요청마다 위 그림과 같이 별도의 스레드를 할당해 하나의 서블릿 인스턴스의 service()를 병렬로 실행한다. 따라서 여러 클라이언트가 동시에 동일한 서블릿에 접근할 수 있다는 강력한 장점이 있다.
thread란?
- 애플리케이션 코드를 순차적으로 실행하는 것(java main 메서드를 실행하면 main이라는 이름의 thread가 실행)
- 동시 처리가 필요하면 thread 추가 생성
- thread는 thread pool에서 관리 -> thread가 필요하면 pool에 미리 생성되어 있는 thread를 꺼내서 사용
- 사용을 종료하면 thread pool에 반납
위와 같이 서블릿 컨테이너가 밥상을 차려주면 서블릿은 다음과 같은 역할을 한다.
- 요청 해석 및 파라미터 처리
- request.getParameter(), getHeader(), getCookie() 등으로 필요한 데이터 획득
- 비즈니스 로직 호출
- 서비스(DAO, 외부 API) 레이어와 연동해 실제 작업 수행
- 모델 데이터 설정
- request.setAttribute() 또는 session.setAttribute()로 결과를 저장
- 뷰(View) 선택 및 포워딩
- RequestDispatcher.forward()로 JSP나 템플릿 엔진에 제어를 위임
- 또는 직접 response.getWriter().write()로 HTML 생성
- 응답 헤더·상태 코드 조작
- response.setStatus(), setHeader() 등을 통해 캐싱, 쿠키, MIME 타입 설정
dispacterServlet을 사용하기 전, 일일이 Servlet을 등록하던 시절에 일반적으로 web.xml에 다음과 같이 Servlet을 등록하고 매핑시켰다.
web.xml에 helloServlet을 정의한 코드
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.example.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
(2). 뷰 페이지 생성
초창기 서블릿은 HTTP 요청을 처리하는 컨트롤러(controller) 역할과, 클라이언트에 동적 화면을 생성해 보여주는 뷰(view) 역할을 동시에 수행했다. Tomcat + jsp로 개발을 하는 경우에 Tomcat의 jsp엔진인 jasper를 통해서 서블릿 뷰를 만들었다. 프로세스는 다음과 같다.
- 클라이언트가 .jsp 요청
- Jasper라는 Tomcat의 JSP 엔진이 .jsp를 .java 서블릿 파일로 변환
- 예: /test.jsp → org/apache/jsp/test_jsp.java
- 변환된 .java 파일을 JDK가 컴파일하여 .class 생성
- 해당 서블릿 클래스가 로딩되고, 요청 처리
파일 생성 위치 예시
JSP가 서블릿으로 변환되면 아래 디렉토리에 생성된다.
$CATALINA_HOME/work/Catalina/localhost/{app-name}/org/apache/jsp/test_jsp.java //Servlet
$CATALINA_HOME/work/Catalina/localhost/{app-name}/org/apache/jsp/test_jsp.class
2. 서블릿 컨테이너
서블릿 컨테이너는 위에서 잠깐 설명했던 것처럼 HTTP 요청을 받아서 thread에 요청을 할당하고 서블릿 인스턴스를 매핑해주는 등 서블릿이 요청을 처리하기 위한 전, 후 프로세스를 처리한다. 이론적으로 나열해보면 다음과 같다.
- HTTP 연결 관리
- 클라이언트와의 TCP 연결을 수립·해제
- HTTP 메시지(요청·응답)의 헤더와 바디를 파싱/생성
- URL 매핑 및 라우팅
- web.xml 또는 @WebServlet 설정을 로드
- 요청 URL에 맞는 서블릿을 찾아 호출
- 라이프사이클 관리
- 서블릿 인스턴스 생성(new + init())
- 요청마다 service() → doGet()/doPost() 호출
- 애플리케이션 언로드나 종료 시 destroy() 호출
- 스레드 풀 운영
- 요청당 스레드를 할당하거나 재사용
- 병렬 처리 환경 제공
- 추가 인프라 제공
- JSP 컴파일(Jasper 통해 .jsp→.java→.class)
- 필터(Filter), 리스너(Listener) 실행
- 세션(Session), 컨텍스트(ServletContext) 관리
- 보안(인증·인가), JNDI 리소스 연결 등
지금까지 순수 서블릿의 역할과 서블릿 컨테이너에 대해서 정리해 보았다. 서블릿을 직접 정의하고 매핑하는 방식을 옛날에는 사용했지만 요즘은 잘 사용하지 않는다. 왜냐? 스프링과 DispatcherServlet이라는 서블릿을 사용하기 때문이다. 다음 시간에 DispatcherServlet은 어떤 역할을 하며 기존의 서블릿과는 어떤 차이점을 가지는지 정리해 보겠다.