[Java] Servlet - CGI 부터 DispatcherServlet까지의 여정

·2024년 1월 29일
0

Java

목록 보기
2/5
post-thumbnail

Servlet이란

클라이언트의 요청을 처리하고, 그 결과를 반환하는 Java 의 동적 웹 프로그래밍 기술이다.

Servlet 등장배경

CGI, Common Gateway Interface

초창기 웹 시장은 웹 서버를 활용하여 정적인 페이지만 전달할 수 있었다. 즉, 사용자의 요청에 따라 뭔가를 가공하여 보여주기 보다는, 그냥 단순히 작성한 글자나 데이터를 보여주는 것에 그쳤다. 이윽고, 하나 둘 동적인 컨텐츠를 가미한 페이지가 등장하기 시작했고, 이를 보다 원할하게 개발할 수 있도록 나타난 것이 CGI 이다.

CGI 는 웹 서버와 프로그래밍 언어를 활용한 외부 프로그램 간의 상호작용을 정의하는 기술 규격이다. 웹 서버에 클라이언트 요청이 들어오는 경우, 해당 요청에 대한 CGI 프로그램을 실행하여, 적절한 응답을 생성한 후, 이를 클라이언트에게 전달하는 방식이다.

그러나 CGI 는 여러가지 한계점을 가지고 있다. 클라이언트 요청마다, 매번 새로운 프로그램을 실행하기 때문에, 컨텐츠에 대한 응답도 느릴 뿐더러, 오버헤드가 크다는 단점이 있다. 특히 방문 접속자가 많은 대규모의 어플리케이션의 경우, 수많은 요청들을 다 해결하지 못하는 문제도 빈번했다.

추후 이러한 문제를 해결하기 위해, 프로세스 별 작업을 스레드로 변경하고 더불어, Singleton 패턴을 활용하여 여러 프로그램을 하나의 CGI 구현체가 등장하기도 했다. 이 CGI 구현체Java 에 적용시킨 것이 Servlet 이다.

Servlet의 등장

기본적으로 ServletCGI 와 기술 체계가 매우 유사하다. CGI 가 기존 요청에 대해 프로그램을 실행하는 방식이라면, Servlet 는 요청별로 새로운 Servlet 을 실행하는 방식이다. 단, Servlet 은 컨테이너를 통해 개별적으로 Servlet 의 생명주기를 관리한다는 점이 다르다.

Servlet 특징

Servlet 은 다음과 같은 3가지 메서드를 가지고 있다.

  • init() : Servlet 인스턴스를 생성한다.
  • service() : Servlet 의 기능을 수행하는 메서드로, HTTP Method 에 따라, doGet(), doPost(), doPut(), doDelete() 등의 메서드들이 호출된다. 개발자는 해당 요청을 알맞게 연결한 후, doXXX() 메서드를 오버라이드하여, 응답할 컨텐츠를 구현해야 한다.
  • destroy() : Servlet 인스턴스를 종료한다.

실질적으로 개발자는 xml 파일에, 구현한 인스턴스를 등록하여 언어에게 이를 알리고, Servlet 별로, 요청에 따른 응답을 구현하면, 요청 시 서버에서 이를 알아서 호출하여 적절한 동적 컨텐츠가 반환되도록 하는 것이다.

추후 등록과정은 @WebServlet 어노테이션을 사용하는 것으로 web.xml 에 설정이 더욱 간소화된다.

<servlet>
  <description></description>
  <display-name>login</display-name>
  
  <servlet-name>login</servlet-name>
  <servlet-class>com.ssamz.web.user.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>login</servlet-name>
  <url-pattern>/login.naver</url-pattern>
</servlet-mapping>
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
 	public LoginServlet() {
        System.out.println("===> LoginServlet 객체 생성");
  	}

 	// doGet, doPost 는 오버라이딩된 상태
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("===> doGet() 호출");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("===> doPost() 호출");   
	}
}

Dispatcher Servlet

Servlet의 한계

Servlet 에 각기 다른 Servlet 에 대한 요청이 동시에 들어오는 경우, 스레드별로 Servlet 인스턴스가 생성되어 요청을 수행하는 멀티 스레딩이 이루어진다. 멀티스레딩 자체의 위험성도 존재하지만, 서블릿 별로 공통적으로 수행하는 로직이 중복된다는 단점이 존재했다.

추후 이 문제를 보완하여, 기존 공통처리 사항을 위한 Controller 를 따로 설계한 것이 FrontController 패턴이다.

프론트 컨트롤러 패턴

MVC 디자인 패턴을 기반으로, 서버에 대한 모든 요청을 일괄적으로 처리하도록 구성한 설계를 의미한다. 기존에는 Controller(Servlet) 별로, 요청, 기능 구현, 클라이언트에게 응답을 모두 관리했다면, FrontController 에게 요청, 클라이언트에게 응답 부분을 위임하는 것으로 더욱 효율적인 서버 운영이 가능했다.

DispatcherServlet

Spring MVC 에서 FrontController 의 역할을 수행하는 Servlet 을 의미한다. DispatcherServlet 은 기존 FrontController 와 동일하게 Servlet 의 공통영역을 처리하는 것은 물론, 각각의 Controller(Servlet) 의 결과정보를 기반으로, ViewResolver 를 통해 동적 페이지를 생성하여 결과를 반환하도록 해준다.

참고
CGI 기술의 등장 배경과 WAS로의 발전
웹 서버와 WAS, CGI (feat. 스레드와 프로세스)
[10분 테코톡] 🌻타미의 Servlet vs Spring
[Servlet] 서블릿(Servlet)이란?
Servlet 과 web.xml 파일 활용 및 서버 Tomcat 실행
[10분 테코톡] 🐶 코기의 Servlet vs Spring
만들면서 배우는 프론트 컨트롤러(Front Controller) 패턴
[Spring] 스프링의 구조/작동순서

profile
새로운 것에 관심이 많고, 프로젝트 설계 및 최적화를 좋아합니다.

0개의 댓글