티스토리 뷰
👻 Servlet(서블릿)
Servlet(서블릿)은 Java 언어를 기반으로 하는 웹 애플리케이션 개발을 위한 기술로, 클라이언트의 요청에 따라 동적으로 서버에서 처리하는 자바 클래스이다.
서블릿은 동적 웹페이지를 만들 때 사용되는 자바 기반의 웹 애플리케이션 프로그래밍 기술이며 HTTP 프로토콜을 통해 클라이언트의 요청을 받고, 자바 코드를 통해 동적인 웹 페이지를 생성하거나 데이터를 처리해서 응답을 반환해준다.
서블릿 이전에는?
서블릿 이전의 초기 웹은 단순히 정적인 HTML 문서를 클라이언트에게 제공하는 방식이었다.
사용자가 서버에 HTML 파일을 요청하면 👉 서버는 해당 HTML 문서를 그대로 전송한 것이다.
이를 통해 웹 페이지를 표시할 수는 있었지만, 사용자 맞춤형 데이터나 동적인 컨텐츠는 제공할 수 없었다.
(ex. 사용자가 로그인하면 이름을 표시하거나, 상품 검색 결과를 동적으로 보여줄 수 없었음)

이를 해결하기 위해서 나온 기술이 CGI(Common Gateway Interface)였다.
CGI는 웹 서버가 클라이언트의 요청을 받을 때마다 외부 프로그램을 실행해서 동적인 결과를 생성하고 이를 HTML로 반환했다. 즉, 동적인 컨텐츠 제공이 가능해진 것이다.
그런데, CGI의 치명적인 문제가 있는데 바로 각 요청마다 매번 새로운 프로세스를 생성한다는 것이다.(1요청 1프로세스)
즉, 리소스의 소모가 크고, 성능 이슈를 발생시키고 확장성도 부족했다.

그래서 나온 것이 바로 서블릿(Servlet)이라는 기술이다!
서블릿의 등장
위의 역사를 요약하자면
- 정적인 웹(초기) : 단순 HTML 파일만 제공. A 클라이언트와 B 클라이언트가 보는 화면 같음
- CGI 도입 : 동적인 콘텐츠 제공이 가능하지만 리소스 낭비와 성능 문제 발생(1요청 1프로세스)
- 서블릿(Servlet) : Java 기반의 멀티 스레드 기술로 CGI의 문제를 해결하고 동적인 웬 애플리케이션 개발 가능하게 함
이렇게 해서 서블릿이라는 기술이 등장했다고 이해할 수 있다.
그럼 서블릿의 특징을 간단히 알아보자
1️⃣ 멀티 스레드 지원
서블릿은 각 클라이언트의 요청을 새로운 스레드로 처리하여 멀티 스레드를 지원한다.
CGI와 다르게 별도의 프로세스를 생성하는 것이 아니라 하나의 프로그램에서 여러 스레드가 작동한다.
그러면 프로그램은 하나만 켜져있고, 그 안에서 스레드들이 요청을 처리할 수 있어 성능 이슈를 줄인다.
2️⃣ Wirte Once, Run Anywhere
서블릿은 자바 언어로 작성되므로, 플랫폼 독립성을 가진다. 어떤 OS에서든 자바를 지원하는 서버 환경에서 실행 가능하다.
3️⃣ 영구적인 서버 프로그램
서블릿은 웹 애플리케이션이 실행되는 동안 서버에 지속적으로 유지된다.
요청마다 종료되는 CGI와 다르게 웹 애플리케이션이 실행되는 동안 서버에 유지되므로 속도와 성능이 더 뛰어나다.
4️⃣ 효율적인 자원 관리
서블릿은 웹 애플리케이션 시작 시 메모리에 로드되며 요청이 들어오면 해당 서블릿 객체가 재사용된다.(싱글톤으로 관리되는 서블릿 객체)
이런 특성으로 인해 초기화 비용이 줄어들고 서버 자원을 효율적으로 사용할 수 있다.
서블릿 동작 방식
그렇다면 서블릿은 어떻게 동작할까?
- 클라이언트 측에서 HTTP 요청을 보내면 HTTP 요청이 Servlet Container(서블릿 컨테이너)로 전송된다.
- 요청을 전송받은 서블릿 컨테이너는 HttpServletRequest, HttpServletResponse 객체를 생성한다.
- web.xml을 기반으로 사용자가 요청한 URL이 어느 서블릿에 대한 요청인지 찾는다.
- 해당 서블릿에서 service 메소드를 호출한 후 클라이언트의 GET, POST 여부에 따라 doGet(), doPost()를 호출한다.
- doGet(), doPost() 메소드는 동적 페이지를 생성하서 HttpServletResponse 객체에 응답을 담는다.(서블릿 컨테이너(WAS)가 객체에 담긴 내용으로 HTTP응답 정보를 생성해서 클라이언트에게 전달한다.)
- 응답이 끝난 후 생성한 HttpServletRequest, HttpServletResponse 객체를 소멸한다.
동작 과정을 코드로 살펴보자
import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
// GET 요청을 처리하는 메서드
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 응답의 Content-Type을 설정
response.setContentType("text/html");
// 클라이언트에게 데이터를 쓰기 위한 PrintWriter 객체 생성
PrintWriter out = response.getWriter();
// 응답으로 반환할 HTML 생성
out.println("<html>");
out.println("<head><title>Hello Servlet</title></head>");
out.println("<body>");
out.println("<h1>Hello, Servlet!</h1>");
out.println("<p>This is a simple servlet example.</p>");
out.println("</body>");
out.println("</html>");
// PrintWriter 닫기
out.close();
}
}
클라이언트의 요청이 GET인 경우의 코드이다. 이 때는 위의 설명과 같이 doGet() 메소드가 동작한다.
클라이언트가 http://localhost:8080/MyServletApp/hello 요청을 보내면 화면에 "Hello, Servlet!"이라는 메세지가 출력된 HTML 페이지가 표시된다.
서블릿 컨테이너(Servlet Container)
서블릿 컨테이너(Servlet Container)는 서블릿을 관리하는 컨테이너이다.
말 그대로 서블릿 컨테이너는 서블릿을 관리하는 컨테이너이다.
서블릿을 생성했다고 해서 스스로 작동하는 것이 아니다. 누군가 서블릿을 관리해주어야 하는데 그 역할을 하는 것이 서블릿 컨테이너이다.
서블릿 컨테이너는 WAS(Web Application Server)로 클라이언트의 요청을 받고 응답할 수 있도록 웹 서버와 소켓으로 통신한다.
서블릿 컨테이너의 역할을 알아보자
1️⃣ 웹 서버와 통신 지원
서블릿 컨테이너는 서블릿과 웹 서버가 손쉽게 통신할 수 있도록 한다.
소켓을 만들고 listen, accept 등의 작동을 API로 제공하여 개발자가 서블릿에 구현해야 할 비즈니스 로직만 구현할 수 있게 해준다.
2️⃣ 서블릿 생명주기 관리
서블릿 컨테이너는 서블릿의 탄생과 죽음을 관리한다.
서블릿의 생명주기는 크게 3단계로 나눌 수 있다.
- 서블릿 생성 및 초기화
- 서블릿 컨테이너가 애플리케이션이 처음 실행되거나 서블릿이 처음 요청될 땨 서블릿 객체를 최초 한 번만 생성한다.
- 서블릿 객체가 생성되면 컨테이너가 init() 메소드를 호출해서 서블릿 객체를 초기화한다.
- init() 메소드는 서블릿이 로드될 때 딱 한 번만 호출된다.
- 서블릿 요청 처리
- 클라이언트의 HTTP 요청을 받을 때마다 service() 메소드를 호출한다.
- service() 메소드는 클라이언트의 요청 유형에 따라 doGet(), doPost() 메소드를 호출한다.
- 요청마다 새로운 스레드가 생성되어 처리한다.
- 즉, 서블릿 객체는 싱글톤으로 관리되지만 요청 / 응답 데이터는 각 요청마다 독립적으로 처리된다.
- 서블릿 종료
- 서블릿 컨테이너가 애플리케이션을 종료하거나 서블릿을 제거할 때 서블릿 객체를 메모리에서 해제한다.
- destroy() 메소드를 호출한다. init() 메소드와 마찬가지로 한 번만 실행된다.
- 컨테이너가 정상 종료될 때 destroy() 메소드가 호출된다.
@Override
public void init() throws ServletException {
// 초기화 작업
System.out.println("Servlet Initialized!");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// GET 요청 처리
response.getWriter().println("Handled GET request!");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// POST 요청 처리
response.getWriter().println("Handled POST request!");
}
@Override
public void destroy() {
// 종료 작업
System.out.println("Servlet Destroyed!");
}
3️⃣ 멀티 스레드 지원 및 관리
서블릿 컨테이너는 요청이 올 때 마다 새로운 자바 스레드를 생성하고 관리한다.
위에서 설명했듯 요청이 올 때 마다 각각 스레드 독립적으로 처리된다. 서버가 멀티 스레드를 생성 및 운영해주기 때문에 스레드 안정성도 보장된다.
4️⃣ 선언적 보안 관리
서블릿 컨테이너는 개발자가 보안에 관한 내용을 서블릿이나 자바 클래스에 구현하지 않아도 된다.
결국 서블릿은 클라이언트 요청을 처리하고 결과를 반환하는 자바 웹 프로그래밍 기술로 동적 웹페이지 생성 시 사용된다.
그리고 서블릿을 관리해주는 것이 서블릿 컨테이너이다.
참고 자료
서블릿(Servlet)이 뭔지 궁금해?
자바 웹기술 역사는 서블릿 → JSP → (서블릿 + JSP) MVC 패턴 → 스트럿츠, 웹워크 -> 스프링 MVC 요런식으로 발전해왔어요. 요즘은 Spring WebFlux라는 서블릿 기반이 아닌 Web Reactive 기반을 이용하기도
jh2021.tistory.com
https://mangkyu.tistory.com/14
[JSP] 서블릿(Servlet)이란?
1. Servlet(서블릿) 서블릿을 한 줄로 정의하자면 아래와 같습니다. 클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술 간단히 말해서,
mangkyu.tistory.com
'spring' 카테고리의 다른 글
@Component만 사용하면 안되나요? (0) | 2024.12.12 |
---|---|
@Value 어노테이션 주의점 (0) | 2024.11.14 |
싱글톤 패턴 (0) | 2022.11.11 |
- Total
- Today
- Yesterday
- Spring
- 생성자
- 오블완
- lowerBound
- ddl-auto
- 동등성
- 유효성 검사
- Optional
- @NoArgsConstructor
- @Spring
- Thymeleaf
- 티스토리챌린지
- 메인메소드
- N+1문제
- null
- @Value
- checkedException
- upperBound
- JPA
- Java
- @ConfigurationProperties
- uncheckedException
- NPE
- 이진탐색
- StreamAPI
- 일급컬렉션
- springboot
- 자바
- id생성전략
- 백준
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |