이것이 점프 투 공작소

스프링 서블릿(servlet)에 대해 알아보자 본문

스프링

스프링 서블릿(servlet)에 대해 알아보자

겅겅겅 2023. 9. 17. 19:32

업무 중 application.yml에 붙어있던 prefix를 특정 api에서는 제거해야하는 상황이 생겼습니다.
그래서 서블릿을 사용해야 할 것 같아, prefix를 제거하고 새로 서블릿을 만들어 라우팅을 하여 해결하였지만 이해가 부족한 것 같아
서블릿에 대하여 다시 공부하고 정리하려합니다

서블릿이란?

웹 어플리케이션에서 HTTP 요청과 응답 처리를 위한 스프링에서 제공하는 핵심 기능입니다.
스프링 부트에서는 HttpServlet클래스를 상속을 받아 사용하며, Servlet Container에 의해 실행됩니다.
doGet, doPost, doPut, doDelete 등의 메서드를 사용하여 요청을 처리하며
스프링 부트에서는 어노테이션과 HttpServlet 상속을 이용하여 간단하게 생성 할 수 있습니다.
 
아래 사진은 /apis라는 url이 붙은 요청을 캐치하는 서블릿 예시코드입니다.
추가로 생성한 서블릿에는 MultipartConfig 설정이 있어야 해당 서블릿에서 들어오는 멀티파트 요청을 처리 할 수 있습니다.

서블릿 컨테이너란?

스프링에서 서블릿을 관리해주는 컨테이너입니다.
클라이언트의 요청을 받고 응답하도록 웹서버(nginx 등)와 소켓을 만들어 통신합니다.
서블릿 컨테이너는 쓰레드 풀을 가지며 요청이 도착하면 쓰레드를 가져와 서블릿 인스턴스를 생성하여 요청을 처리합니다. 
대표적인 서블릿 컨테이너로 톰캣(Tomcat)이 있습니다.
 

  • 1. 웹서버와의 통신지원 : 소켓기능들을 API로 제공하여 복잡한 과정을 생략하고, 비즈니스 로직에 대해서만 집중하도록 도와줍니다.
  • 2. 서블릿 생명주기 관리 : 서블릿 클래스를 로딩하여 인스턴스화하고, 초기화 메소드를 호출하고, 요청이 들어오면 적절한 서블릿 메소드를 호출합니다.
  • 3. 멀티쓰레드 지원 및 관리 : 서블릿 컨테이너는 요청이 올 때 마다 새로운 자바 쓰레드를 하나 생성하는데, HTTP 서비스 메소드를 실행한 후 쓰레드는 자동으로 됩니다. 이러한 관리를 컨테이너가 알아서 해준다.

서블릿 동작 과정 및 생명주기

추가로 서블릿의 생명주기 관련 메소드 또한 오버라이딩하여
비즈니스 로직을 추가 가능합니다.
init(), service(), destroy()로 서블릿의 생명주기를 관리 할 수 있습니다.

서블릿 동작 과정

1. 클라이언트에서 URL 호출
2. 웹서버에서 URL을 확인하여 해당 서블릿으로 요청 전달, 없으면 서블릿 클래스의 init()으로 생성
3. 서블릿 컨테이너는 요청정보를 HttpServletRequest, HttpServletResponse 두 객체에 저장
4. 서블릿 클래스의 service()메소드 호출 (HTTP Method에 따라 서블릿의 doGet, doPost 호출)
5. 요청 처리 후 HttpServletResponse 객체에 HTTP 데이터를 담아 응답
6. 웹서버가 클라이언트에 응답처리
7. 서블릿의 destroy() 호출하여 GC에 의해 서블릿 종료
 

디스패쳐 서블릿이란?

서블릿과 함께 스프링을 사용하다보면 항상 듣게되는 디스패쳐 서블릿입니다.
서블릿 컨테이너 앞에서 최초로 가장 먼저 요청을 받고 처리하기에 Front Controller라고 부르기도 합니다.
 
디스패쳐 서블릿을 이해하기 위해서는 스프링MVC 패턴에 대한 이해가 먼저 필요한데
간단하게 정리하자면 아래 3가지 엔티티를 사용하여 만들어내는 스프링의 구조화된 패턴 방식입니다.
 
Model : 어플리케이션의 비즈니스 로직 및 데이터
View : Model의 데이터를 사용하여 클라이언트에게 보여줄 사용자 UI
Controller : HTTP 요청을 받아들이고, 모델을 생성 및 가공하여 적절한 뷰를 반환
 

디스패쳐 서블릿은 다음과 같은 순서로 역할을 수행합니다.
 
1. 클라이언트에서 최초 요청을 전달받습니다.
2. 요청을 처리할 적절한 핸들러(컨트롤러)에 라우팅합니다. (핸들러 매핑을 통해 요청 URI와 컨트롤러를 매핑합니다.)
3. 적절한 핸들러를 실행시킬 수 있는 Handler Adapter를 통해 선택된 핸들러를 실행시킵니다.
4. 선택된 핸들러(컨트롤러)는 비즈니스 로직을 수행합니다.
5. 핸들러(컨트롤러)가 비즈니스 로직 실행을 마치면 처리 결과를 Model에 설정하여 HandlerAdapter에 view name을 반환합니다.
6. 전달받은 view name을 뷰 리졸버에 반환하고 view name과 맡는 view객체를 반환합니다.
7. 디스패쳐 서블릿은 view에 model을 전달합니다.
8. 렌더링하여 클라이언트에 반환합니다.