03. 서블릿 이해하기

03. 서블릿 이해하기

1. 서블릿이란?

서버에서 실행되며 클라이언트 요청에 동적으로 응답하는 자바 클래스

서블릿의 동작 흐름

클라이언트 (브라우저)
      │
      │ HTTP 요청
      ▼
┌──────────────┐
│   웹 서버     │
│  (Apache)    │
└──────┬───────┘
       │ 위임
       ▼
┌──────────────┐
│     WAS      │
│   (Tomcat)   │
│  ┌────────┐  │
│  │ Servlet │  │
│  └────────┘  │
└──────┬───────┘
       │ 응답
       ▼
클라이언트 (브라우저)

서블릿의 특징

특징설명
서버 측 실행WAS에서 동작
동적 처리요청마다 다른 결과
자바 기반객체지향, 플랫폼 독립
스레드 방식요청마다 스레드 생성
컨테이너 필요Tomcat 등에서 실행

일반 자바 vs 서블릿

구분일반 자바서블릿
실행독자 실행 가능컨테이너 필요
진입점main()service()
용도다양함웹 요청 처리

2. 서블릿 API 구조

계층 구조

<<interface>>
   Servlet
      │
      ├── init()
      ├── service()
      ├── destroy()
      └── getServletConfig()
         │
         ▼
<<interface>>
 ServletConfig
      │
      ├── getInitParameter()
      └── getServletContext()
         │
         ▼
<<abstract>>
 GenericServlet
      │
      │  (일반 프로토콜용)
      │
      ▼
  HttpServlet
      │
      │  (HTTP 프로토콜용)
      │
      ├── doGet()
      ├── doPost()
      ├── doPut()
      └── doDelete()

주요 인터페이스/클래스

Servlet 인터페이스

  • 패키지: javax.servlet
  • 모든 서블릿의 최상위
  • 생명주기 메서드 정의

ServletConfig 인터페이스

  • 패키지: javax.servlet
  • 서블릿 설정 정보 제공

GenericServlet 클래스

  • 패키지: javax.servlet
  • 프로토콜 독립적 서블릿
  • 추상 클래스

HttpServlet 클래스

  • 패키지: javax.servlet.http
  • HTTP 전용 서블릿
  • 실제 개발에서 주로 상속

3. HttpServlet 메서드

HTTP 메서드별 처리

메서드HTTP용도
doGet()GET조회
doPost()POST등록
doPut()PUT수정
doDelete()DELETE삭제
doHead()HEAD헤더만 조회

메서드 시그니처

protected void doGet(
    HttpServletRequest req,
    HttpServletResponse resp
) throws ServletException, IOException

service() 메서드 흐름

클라이언트 요청
      │
      ▼
public service()
      │
      ▼
protected service()
      │
      ├── GET  → doGet()
      ├── POST → doPost()
      ├── PUT  → doPut()
      └── DELETE → doDelete()

4. 서블릿 생명주기

생명주기 단계

[최초 요청]
     │
     ▼
┌─────────┐
│  init() │ ← 한 번만 실행
└────┬────┘
     │
     ▼
┌──────────────┐
│   service()  │
│  ┌────────┐  │
│  │doGet() │  │ ← 요청마다 실행
│  │doPost()│  │
│  └────────┘  │
└──────┬───────┘
       │
       ▼ (서버 종료/재배포)
┌───────────┐
│ destroy() │ ← 한 번만 실행
└───────────┘

생명주기 메서드 정리

메서드호출 시점횟수
init()최초 요청1번
doGet/doPost매 요청N번
destroy()서블릿 종료1번

각 메서드의 역할

init()

@Override
public void init() {
    // DB 연결 초기화
    // 설정 파일 로드
    // 리소스 준비
}

doGet() / doPost()

@Override
protected void doGet(
    HttpServletRequest req,
    HttpServletResponse resp) {
    // 요청 파라미터 처리
    // 비즈니스 로직 실행
    // 응답 생성
}

destroy()

@Override
public void destroy() {
    // DB 연결 해제
    // 리소스 정리
    // 로그 기록
}

5. 서블릿 동작 과정

최초 요청 시

1. 클라이언트 요청
       │
       ▼
2. 톰캣: 서블릿 메모리 확인
       │
       │ (없음)
       ▼
3. 서블릿 클래스 로드
       │
       ▼
4. init() 호출
       │
       ▼
5. 인스턴스 생성 (메모리 로드)
       │
       ▼
6. doGet()/doPost() 호출
       │
       ▼
7. 응답 전송

이후 요청 시

1. 클라이언트 요청
       │
       ▼
2. 톰캣: 서블릿 메모리 확인
       │
       │ (있음!)
       ▼
3. doGet()/doPost() 호출
       │
       ▼
4. 응답 전송

효율성

  • 최초 1회만 인스턴스 생성
  • 이후 요청은 재사용
  • 싱글톤 패턴과 유사

6. 서블릿 매핑

web.xml 방식 (전통적)

<!-- 서블릿 등록 -->
<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>
        com.example.HelloServlet
    </servlet-class>
</servlet>

<!-- URL 매핑 -->
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

애너테이션 방식 (권장)

@WebServlet("/hello")
public class HelloServlet
    extends HttpServlet {

    @Override
    protected void doGet(
        HttpServletRequest req,
        HttpServletResponse resp) {
        // 처리 로직
    }
}

@WebServlet 속성

속성설명
valueURL 패턴
urlPatterns여러 URL 패턴
name서블릿 이름
loadOnStartup시작 시 로드 순서

URL 패턴 예시

// 단일 경로
@WebServlet("/hello")

// 여러 경로
@WebServlet(urlPatterns = {
    "/hello",
    "/hi"
})

// 와일드카드
@WebServlet("/api/*")

// 확장자 매핑
@WebServlet("*.do")

7. 서블릿 예제

기본 구조

package com.example;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

@WebServlet("/hello")
public class HelloServlet
    extends HttpServlet {

    @Override
    public void init() {
        System.out.println("서블릿 초기화");
    }

    @Override
    protected void doGet(
        HttpServletRequest req,
        HttpServletResponse resp)
        throws IOException {

        resp.setContentType(
            "text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();
        out.println("<html>");
        out.println("<body>");
        out.println("<h1>Hello Servlet!</h1>");
        out.println("</body>");
        out.println("</html>");
    }

    @Override
    public void destroy() {
        System.out.println("서블릿 종료");
    }
}

파라미터 처리

@WebServlet("/login")
public class LoginServlet
    extends HttpServlet {

    @Override
    protected void doPost(
        HttpServletRequest req,
        HttpServletResponse resp)
        throws IOException {

        // 한글 처리
        req.setCharacterEncoding("UTF-8");

        // 파라미터 받기
        String id = req.getParameter("id");
        String pw = req.getParameter("pw");

        // 응답
        resp.setContentType(
            "text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("ID: " + id);
    }
}

8. Request & Response

HttpServletRequest 주요 메서드

메서드반환설명
getParameter()String단일 값
getParameterValues()String[]다중 값
getAttribute()Object속성 값
getSession()HttpSession세션
getMethod()StringHTTP 메서드
getRequestURI()String요청 URI

HttpServletResponse 주요 메서드

메서드설명
setContentType()MIME 타입 설정
getWriter()문자 출력 스트림
getOutputStream()바이트 출력 스트림
sendRedirect()리다이렉트
setStatus()상태 코드 설정

요약

서블릿 핵심

항목내용
정의동적 웹 처리 자바 클래스
상속HttpServlet
실행WAS (Tomcat 등)
매핑@WebServlet

생명주기

init()     → 초기화 (1회)
     ↓
doXxx()    → 요청 처리 (매번)
     ↓
destroy()  → 종료 (1회)

필수 코드 패턴

@WebServlet("/path")
public class MyServlet
    extends HttpServlet {

    @Override
    protected void doGet(
        HttpServletRequest req,
        HttpServletResponse resp)
        throws IOException {

        // 응답 타입 설정
        resp.setContentType(
            "text/html;charset=UTF-8");

        // 출력
        PrintWriter out = resp.getWriter();
        out.println("응답 내용");
    }
}