본문 바로가기
Java

[Java] Servlet (서블릿)

by gungle 2023. 11. 19.

Java Servlet(서블릿)은 서버의 기능을 확장하는 Java 소프트웨어 구성 요소이다.

서블릿은 많은 유형의 요청에 응답할 수 있지만 웹 서버에서 웹 응용 프로그램을 호스팅하기 위해 웹 컨테이너를 가장 일반적으로 구현하므로 서버 측 서블릿 웹 API로 적합하다.

이러한 웹 서블릿은 PHP 및 ASP.NET 과 같은 다른 동적 웹 콘텐츠 기술(dynamic web content technologies)과 동등한 역할을 처리한다고 볼 수 있다.

서블릿을 정의해보면 서블릿(servlet)은 WAS에 동작하는 JAVA 클래스이고, 서블릿은 HttpServlet 클래스를 상속받아야 합니다.

서블릿과 JSP로부터 최상의 결과를 얻으려면, 웹 페이지를 개발할 때 이 두 가지(JSP, 서블릿)를 조화롭게 사용해야 한다.

예를 들어, 웹 페이지를 구성하는 화면(HTML)은 JSP로 표현하고, 복잡한 프로그래밍은 서블릿으로 구현해야 한다.

Life of a JSP file

 

JSP가 실행되기 전에 서블릿으로 번역되기 때문에 서블릿 컨테이너가 아닌 JSP 컨테이너는 없다.
그래서 JSP 컨테이너는 서블릿을 지원해야 한다.
서블릿 기술이 처음 등장하고 컨테이너를 서블릿 컨테이너라고 불렀던 옛날에는 그 반대가 항상 맞는 것은 아니었다.
JSP가 나왔을 때, JSP 페이지를 서블릿으로 해석하고 처리하는 엔진이 구 서블릿 컨테이너에 추가되고 사람들은 보통 그런 컨테이너를 JSP/서블릿 컨테이너라고 부른다.
오늘날, JSP 컨테이너와 서블릿 컨테이너는 둘 다 JSP와 서블릿을 지원하기 때문에 거의 같은 것을 의미한다.

 

init(), service(), 그리고 destroy(), 이 세 가지 method들이 서블릿의 Life Cycle의 중심이다.

서블릿 수명 주기의 초기화 단계에서 웹 컨테이너는 init() method를 호출하여 javax.servlet.ServletConfig를 구현하는 개체를 전달함으로써 서블릿 인스턴스를 초기화한다.

이 객체는 서블릿이 웹 응용프로그램에서 name-value 초기화 매개변수에 접근할 수 있도록 한다.

초기화 후 서블릿 인스턴스는 클라이언트 요청을 처리할 수 있다.

각각의 요청은 각각의 개별적인 스레드로 처리된다.

웹 컨테이너는 모든 요청에 대해 서블릿의 service() method를 호출한다.

service() method는 요청의 종류를 결정하고, 이를 적절한 방법으로 발송하여 요청을 처리한다.

서블릿 개발자는 이러한 방법에 대한 구현을 제공해야 한다.

서블릿에 의해 구현되지 않은 방법에 대해 요청이 있을 경우, 상위 클래스의 방법을 호출하여 일반적으로 요청자에게 오류가 반환된다.

마지막으로, 웹 컨테이너는 서블릿을 서비스 중단시키는 destroy() method를 호출한다.

destroy() method는 init()과 마찬가지로 서블릿의 라이프사이클에 한 번만 호출된다.

 

import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletLifeCycleExample extends HttpServlet {
    private Integer sharedCounter;

    @Override
    public void init(final ServletConfig config) throws ServletException {
        super.init(config);
        getServletContext().log("init() called");
        sharedCounter = 0;
    }

    @Override
    protected void service(final HttpServletRequest request, final HttpServletResponse response)
            throws ServletException, IOException {
        getServletContext().log("service() called");
        int localCounter;
        synchronized (sharedCounter) {
            sharedCounter++;
            localCounter = sharedCounter;
        }
        response.getWriter().write("Incrementing the count to " + localCounter); // accessing a local variable
    }

    @Override
    public void destroy() {
        getServletContext().log("destroy() called");
    }
}