Servlet과 Servlet Container

Servlet

서블릿은 자바 표준이다. Jakarta EE 스펙이다. (예전에는 Java EE라고 불렸다.)

Java로 HTTP 요청을 처리하는 프로그램을 만들 때 서블릿을 사용한다.

Java를 사용해서 웹 페이지를 동적으로 생성할 수 있는 기술(Java Class)가 Servlet이다.

즉, 서블릿은 웹 애플리케이션 서버에서 동작하며, 클라이언트의 HTTP 요청에 대한 처리를 담당한다.

Q. 자바로 웹 서비스를 개발할 때 스프링 사용하는데?

A. 스프링 MVC는 서블릿 기반으로 작동한다.

  • DispatcherServelt

  • Filter(서블릿 스펙 中)

서블릿은 javax.servlet.Servlet 인터페이스를 구현하거나 javax.servlet.http.HttpServlet 클래스를 상속하여 작성한다. 이를 통해 클라이언트와 서버 간의 통신을 처리하고 동적인 웹 페이지를 생성할 수 있다.

package jakarta.servlet;

import java.io.IOException;

/**
 * Defines methods that all servlets must implement.
 ~ 어쩌구 저쩌구
 */
public interface Servlet {

    /**
     * Called by the servlet container to indicate to a servlet that the servlet is being placed into service.
     ~ 어쩌구 저쩌구
     */
    public void init(ServletConfig config) throws ServletException;

    /**
     * Returns a {@link ServletConfig} object, which contains initialization and startup parameters for this servlet. The
     ~ 어쩌구 저쩌구
     */
    public ServletConfig getServletConfig();

    /**
     * Called by the servlet container to allow the servlet to respond to a request.
     ~ 어쩌구 저쩌구
     */
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;

    /**
     * Returns information about the servlet, such as author, version, and copyright.
     ~ 어쩌구 저쩌구
     */
    public String getServletInfo();

    /**
     * Called by the servlet container to indicate to a servlet that the servlet is being taken out of service. This method
     ~ 어쩌구 저쩌구
     */
    public void destroy();
}

서블릿 표준에 맞춰서 구현할 수 있도록 인터페이스가 존재한다.

  • getServletConfig()와 getServletInfo()는 서블릿 정보, 서블릿을 초기화하는 설정값들이여서 신경쓰지 않아도된다.

아래 3가지 메소드를 묶어서 생명주기(life-cycle) 메소드라고 부른다.

life cycle

가장 처음 톰캣(Web Container = WAS)이 실행되면 서블릿 클래스(서블릿 인터페이스를 가지고 구현한 클래스)로드한다. 불러온 파일을 Servlet Obj(객체)로 만들고 init() 메소드를 실행한다.

톰캣은 클라이언트의 요청을 받아 처리해주는 역할을 하는데, 요청을 처리할 때 서블릿에 service() 메소드가 호출된다.

circle-info
  1. init() 웹 컨테이너, 서블릿이 실행될 때 단 한번만 실행된다.

  2. service() 톰캣은 클라이언트의 요청을 받아 처리해주는 역할을 하는데, 요청을 처리할 때 서블릿에 service() 메소드가 호출된다. 개발자는 서블릿을 구현할 때 serivce() 메소드에 처리 하고싶은 비즈니스 로직을 작성한다.

  3. destory() 서블릿을 종료할 때 작업해야 할 내용을 여기에 작성하면 톰캣이 종료될 때 메소드가 호출된다.

위와같이 서블릿 컨테이너가 실행되면서 서블릿 인스턴스(객체)가 생성되고, 요청들을 처리하고, 종료 되는것이 라이프 사이클이다.

urlPattern에 정의한 URL이 호출되면 서블릿 코드가 실행되고, HTTP 요청 정보와 응답 정보를 편리하게 사용할 수 있는 HttpServeltRequest request, HttpServeltResponse response가 존재한다.

Q: 서블릿 객체는 단 한개만 존재하나?

A: 여러 개 존재할 수 있다. 서블릿 인터페이스를 구현한 구현 클래스가 3개라면 서블릿 객체도 3개가 생성된다.

Servlet Container

이 서블릿 컨테이너를 톰캣, WAS라고도 부른다. 서블릿은 웹 컨테이너의 인스턴스로써 한개씩 존재하고 있다.

서블릿은 일반적으로 싱글톤으로 관리되며, 서블릿 컨테이너는 각 서블릿 클래스당 하나의 인스턴스만 생성하고 재사용한다.

클라이언트에게 요청(request)을 받으면, 서블릿 컨테이너는 서블릿 컨테이너는 request(HttpServletRequest)와 response(HttpServletResponse) 객체를 생성한다.

그리고 서블릿 컨테이너는 URL에 맞춰서 적절한 서블릿을 찾아서 서블릿에 service() 메소드를 실행하며, 이때 생성한 request와 response 객체를 parameter로 전달한다. 이 실행은 스레드 하나에서 실행이 된다.

  • 서블릿 컨테이너는 요청이 들어올 때마다 새로운 자바 스레드를 생성하고, 스레드가 servlet을 호출한다.

서블릿 객체는 하나지만 요청마다 새로운 스레드가 생성되기 때문에 동시에 여러 사용자의 요청을 처리할 수 있는 이유이다. 그리고 처리한 내용을 reponse 객체에 담아서 컨테이너에 돌려주고, 컨테이너는 사용자에게 되돌려준다.

추가로, 서블릿 컨테이너는 요청을 처리하기 위해 스레드 풀을 사용한다. 새로운 요청이 들어오면 스레드 풀에서 사용 가능한 스레드를 하당하여 요청을 처리하기 때문에 멀티스레딩 환경에서 동시에 여러 사용자의 요청을 처리할 수 있다.

서블릿이 요청을 처리하고 결과를 response 객체에 담아 컨테이너에 반환하면, 컨테이너는 이를 사용자에게 전달한다.

응답 처리가 완료되면 request와 response 객체는 소멸되고, 사용된 스레드는 스레드 풀로 반환된다.

  • 여기서 request, response 객체는 HttpServletRequest와 HttpServletResponse 인스턴스를 의미한다.

  • 요청을 처리하는 동안 사용한 쓰레드는 다시 반납하고, request reponse 객체는 jvm에게 반납한다.

응답을 반환한다고 서블릿 객체가 같이 소멸하는 것이 아니라, 서블릿 객체는 서블릿 컨테이너가 유지되는 동안 계속 존재하며 서버를 종료하거나 애플리케이션을 재구동할 때 소멸된다.

triangle-exclamation

필터(Filter)란?

요청, 응답에 추가적인 작업을 하고 싶을 때 필터를 사용한다.

필터도 스펙이기 때문에 표준에 맞춰 구현할 수 있도록 인터페이스가 제공된다.

요청, 응답에 추가 하고싶은 작업은 doFilter() 메소드를 구현하면 된다.

doFilet()는 꼭 구현해서, request, response에 작업을 처리하고 filterChain에 다음 작업을 넘겨준다.

비즈니스 로직을 처리하지 않지만 다음과 같은 작업들을 한다.

  • Authentication Filters

  • Logging and Auditing Filters

  • Image conversion Filters

  • Data compression Filters

  • Encryption Filters

  • Tokenizing Filters

클라이언트에 요청을 받으면 컨테이너가 적절한 서블릿을 찾고 요청을 처리하도록 한다.

컨테이너가 서블릿에 요청과 응답 객체를 넘기기 전 필터에서 처리한다.

또, 서블릿에서 컨테이너에 응답을 넘길 때 응답에 추가적인 작업을 하고 사용자에게 반환한다.

Summary

서블릿은 서버 측 프로그램이며, 클라이언트 요청에 HTTP 응답을 제공한다.

서블릿 컨테이너

  • 서블릿의 생명주기를 관리하는 역할을 담당한다.

  • 스레드 생성 및 관리 : 요청이 URL을 통해 들어오면 컨테이너는 HTTP 요청을 받아 HttpServletRequest/HttpServletResponse 객체를 생성하여 서블릿/클라이언트에게 전송한다.

  • URL 매핑 : 컨테이너는 URL을 특정 서블릿에 매핑하여 서블릿을 실행시킬 수 있다.

Last updated