6주차 Unit 2.2 — 서블릿(Servlet)과 JSP

Psj·2026년 5월 28일

F-lab

목록 보기
188/240

Unit 2.2 — 서블릿(Servlet)과 JSP

F-LAB JAVA · 6주차 · Phase 2 · 웹 인프라 기초


📌 학습 목표

이 Unit을 끝내면 다음을 답할 수 있어야 한다.

  • 서블릿(Servlet) 이란?
  • JSP(Java Server Pages) 란?
  • JSP 가 서블릿으로 변환 된다는 의미는?
  • 역할 분담의 진화 (서블릿만 → JSP만 → MVC) 는?
  • MVC 패턴 에서 JSP/서블릿의 역할은?
  • 현대 Spring 에서 JSP 는 여전히 쓰이나?
  • Thymeleaf 와의 관계는?
  • DispatcherServlet 은?
  • 서블릿 생명주기 는?

🎯 핵심 한 문장

서블릿은 자바 코드로 HTTP 요청을 처리하는 클래스이고, JSP 는 HTML 안에 자바 코드를 섞는 템플릿으로 컴파일 시 서블릿으로 변환되며, 초기엔 서블릿/JSP 만으로 다 하다가 현재는 JSP(또는 Thymeleaf)는 View, 서블릿은 비즈니스 로직을 맡는 MVC 패턴으로 진화했다.
서블릿 은 자바 코드로 HTTP 요청을 처리하는 클래스로 WAS 위에서 실행된다.
JSP 는 HTML 안에 자바 코드를 섞을 수 있는 템플릿으로, 결국 컴파일 시 서블릿으로 변환 되어 실행되므로 본질은 서블릿이다.
역할 분담은 (1) 초기: 서블릿으로 HTML 까지 다 출력 (가독성 최악) → (2) 한때: JSP 로만 모든 로직 (유지보수 지옥) → (3) 현재: JSP 는 View, 서블릿은 비즈니스 로직 (MVC 패턴) 으로 진화했다.
현대 Spring 환경에서 JSP 는 거의 쓰이지 않고 Thymeleaf 같은 템플릿 엔진이나 React·Vue 같은 SPA 가 View 를 맡으며, ILIC 도 Vue 3 + REST API 구조를 쓴다.

비유 — 편지 작성 방식의 진화

서블릿/JSP = 편지 작성 방식:

서블릿 (코드로 편지):
  - 자바 코드로 HTML 출력
  - out.println("<html>...")
  - HTML 안 보임 (가독성 최악)

JSP (HTML에 코드):
  - HTML 에 자바 삽입
  - <% 자바 %>
  - 컴파일 → 서블릿 변환

진화 (역할 분담):
  초기: 서블릿이 다 (코드로 HTML)
    → 읽기 힘듦
  한때: JSP 가 다 (HTML에 로직)
    → 유지보수 지옥
  현재: MVC
    - JSP/Thymeleaf = View (화면)
    - 서블릿/Controller = 로직

JSP → 서블릿 변환:
  - JSP 도 결국 서블릿
  - 컴파일 시 변환
  - 첫 요청 시 컴파일

현대 (ILIC):
  - Vue 3 = View (CSR)
  - REST API = 로직
  → JSP 안 씀

→ 서블릿(자바 HTTP 처리) + JSP(HTML+자바, 서블릿 변환), MVC 진화, 현대는 SPA+API.


🧭 9개 섹션 로드맵

1. 서블릿이란
2. JSP란
3. JSP → 서블릿 변환
4. 역할 분담의 진화
5. MVC 패턴
6. 현대 Spring에서 JSP
7. Thymeleaf
8. DispatcherServlet
9. 면접 + 자기 점검

1️⃣ 서블릿이란

1.1 서블릿

서블릿 (Servlet):

  자바 코드로 HTTP 요청 처리:
    - HttpServletRequest 받음
    - HttpServletResponse 응답
    - WAS 위에서 실행

1.2 기본 구조

// 서블릿 기본 구조
@WebServlet("/shipments")
public class ShipmentServlet extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, 
                         HttpServletResponse resp) 
            throws ServletException, IOException {
        // HTTP GET 처리
        resp.setContentType("application/json");
        resp.getWriter().write("{\"status\":\"ok\"}");
    }
}

1.3 HTTP 메서드 처리

HTTP 메서드 처리:

  doGet(): GET
  doPost(): POST
  doPut(): PUT
  doDelete(): DELETE

→ 메서드별 오버라이드

1.4 WAS 위에서

WAS 위에서 실행:

  서블릿:
    - WAS(Tomcat) 가 관리
    - 요청 → 서블릿 매핑
    - 생명주기 관리

1.5 ILIC 의 맥락

// 서블릿 (저수준, ILIC 는 Spring 사용)
@WebServlet("/api/shipments")
public class ShipmentServlet extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, 
                         HttpServletResponse resp) 
            throws IOException {
        // 저수준 처리 (직접)
        String id = req.getParameter("id");
        // 비즈니스 로직
        resp.setContentType("application/json");
        resp.getWriter().write("{\"id\":" + id + "}");
    }
}

// 실제 ILIC 는 Spring (서블릿 추상화)
@RestController
public class ShipmentController {
    @GetMapping("/api/shipments/{id}")
    public Shipment get(@PathVariable Long id) {
        // Spring 이 서블릿 추상화 (DispatcherServlet)
        return null;
    }
}
class Shipment {}

1.6 자기 점검 답변

서블릿(Servlet)이란?

:
1. 서블릿:

  • 자바 HTTP 처리 클래스
  1. 구조:

    • HttpServlet 상속
  2. 메서드:

    • doGet/doPost
  3. 실행:

    • WAS 위

2️⃣ JSP란

2.1 JSP

JSP (Java Server Pages):

  HTML 안에 자바 코드:
    - HTML 템플릿
    - <% 자바 %> 삽입
    - 동적 HTML 생성

2.2 기본 구조

<%-- JSP 예시 --%>
<html>
<body>
  <h1>배송 목록</h1>
  <% for (Shipment s : shipments) { %>
    <p><%= s.getBlNo() %></p>
  <% } %>
</body>
</html>

2.3 스크립틀릿

JSP 요소:

  <% 코드 %>: 스크립틀릿
  <%= 값 %>: 표현식 (출력)
  <%@ %>: 지시자
  ${ }: EL (표현 언어)

2.4 서블릿 대비

JSP vs 서블릿:

서블릿:
  - 자바에 HTML (out.println)
  - HTML 안 보임

JSP:
  - HTML 에 자바
  - HTML 잘 보임 (View 적합)

2.5 ILIC 의 맥락

<%-- JSP (레거시, ILIC 는 Vue 사용) --%>
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<body>
  <h1>배송 현황</h1>
  <table>
    <c:forEach var="shipment" items="${shipments}">
      <tr>
        <td>${shipment.blNo}</td>
        <td>${shipment.status}</td>
      </tr>
    </c:forEach>
  </table>
</body>
</html>

<%-- ILIC 는 Vue 3 SPA + REST API (JSP 안 씀) --%>

2.6 자기 점검 답변

JSP(Java Server Pages)란?

:
1. JSP:

  • HTML + 자바 템플릿
  1. 구조:

    • HTML 에 <% %>
  2. 요소:

    • 스크립틀릿/EL
  3. vs 서블릿:

    • HTML 에 자바 (View)

3️⃣ JSP → 서블릿 변환

3.1 변환

JSP → 서블릿 변환:

  JSP 파일:
    - 컴파일 시 서블릿으로 변환
    - .java → .class

  → 본질은 서블릿

3.2 변환 과정

변환 과정:

  1. JSP 작성 (.jsp)
  2. 첫 요청 시 변환 (.java)
  3. 컴파일 (.class)
  4. 서블릿으로 실행
  5. 이후 재사용 (컴파일된)

3.3 의미

변환의 의미:

  JSP 도 결국 서블릿:
    - HTML 출력하는 서블릿
    - 편하게 작성 (HTML)
    - 실행은 서블릿

→ 추상화

3.4 첫 요청 지연

첫 요청 지연:

  첫 JSP 요청:
    - 변환 + 컴파일
    - 약간 느림

  이후:
    - 컴파일된 것 재사용
    - 빠름

3.5 ILIC 의 맥락

JSP → 서블릿 변환 (개념):

  shipments.jsp
    ↓ (첫 요청 시)
  shipments_jsp.java (자동 생성)
    ↓ 컴파일
  shipments_jsp.class (서블릿)
    ↓ 실행
  HTML 응답

  의미:
    - JSP 는 작성 편의
    - 실행은 서블릿
    - "HTML 에 자바" 가 "자바로 HTML 출력" 으로

  ILIC: Vue 빌드 → 정적 파일 (JSP 변환과 무관, CSR)

3.6 자기 점검 답변

JSP가 서블릿으로 변환된다는 의미는?

:
1. 변환:

  • 컴파일 시 서블릿
  1. 과정:

    • JSP → .java → .class
  2. 의미:

    • JSP 도 서블릿
  3. 첫 요청:

    • 변환 지연

4️⃣ 역할 분담의 진화

4.1 진화 단계

역할 분담 진화:

1. 서블릿만 (HTML 다 출력)
   - 가독성 최악

2. JSP만 (모든 로직)
   - 유지보수 지옥

3. MVC (JSP=View, 서블릿=로직)
   - 분리

4.2 1단계 — 서블릿만

// 1단계: 서블릿만 (HTML 출력)
protected void doGet(...) throws IOException {
    PrintWriter out = resp.getWriter();
    out.println("<html><body>");
    out.println("<h1>배송 목록</h1>");
    for (Shipment s : shipments) {
        out.println("<p>" + s.getBlNo() + "</p>");
    }
    out.println("</body></html>");
    // HTML 이 자바 문자열 (가독성 최악)
}

4.3 2단계 — JSP만

<%-- 2단계: JSP에 모든 로직 --%>
<%
    // 비즈니스 로직까지 JSP 안에
    Connection conn = DriverManager.getConnection(...);
    // DB 조회, 계산 등 (유지보수 지옥)
%>
<html>...</html>

4.4 3단계 — MVC

3단계 — MVC:

  Controller (서블릿):
    - 요청 처리
    - 비즈니스 로직 호출
    - 데이터 준비

  View (JSP):
    - 화면만
    - 데이터 표시

4.5 ILIC 의 맥락

// 3단계 MVC (Spring)

// Controller (로직)
@Controller
public class ShipmentController {
    @GetMapping("/shipments")
    public String list(Model model) {
        // 비즈니스 로직
        List<Shipment> shipments = shipmentService.findAll();
        model.addAttribute("shipments", shipments);   // 데이터 준비
        return "shipments";   // View 이름
    }
}

// View (shipments.jsp 또는 Thymeleaf — 화면만)
// <c:forEach items="${shipments}">...</c:forEach>

// ILIC 는 더 진화: REST API + Vue
@RestController
public class ShipmentApiController {
    @GetMapping("/api/shipments")
    public List<Shipment> list() {
        return shipmentService.findAll();   // JSON (View 는 Vue)
    }
}
class Shipment {}

4.6 자기 점검 답변

역할 분담의 진화는?

:
1. 진화:

  • 서블릿만 → JSP만 → MVC
  1. 서블릿만:

    • HTML 출력 (최악)
  2. JSP만:

    • 모든 로직 (지옥)
  3. MVC:

    • View/로직 분리

5️⃣ MVC 패턴

5.1 MVC

MVC 패턴:

  Model: 데이터
  View: 화면
  Controller: 제어

→ 관심사 분리 (5주차)

5.2 각 역할

각 역할:

Model:
  - 데이터/비즈니스
  - 도메인 객체

View:
  - 화면 (JSP/Thymeleaf)
  - 표시만

Controller:
  - 요청 처리
  - Model/View 연결

5.3 흐름

MVC 흐름:

  요청 → Controller
    → Model (데이터)
    → View (화면)
    → 응답

5.4 관심사 분리

관심사 분리 (5주차 연결):

  MVC:
    - 데이터/화면/제어 분리
    - 각자 책임 (SRP)

→ 5주차 관심사 분리 정신

5.5 ILIC 의 맥락

// MVC (ILIC)

// Model (도메인 + 서비스)
@Service
public class ShipmentService {
    public List<Shipment> findAll() { return null; }
}

// Controller (제어)
@RestController
public class ShipmentController {
    private final ShipmentService service;
    public ShipmentController(ShipmentService service) {
        this.service = service;
    }
    @GetMapping("/api/shipments")
    public List<Shipment> list() {
        return service.findAll();   // Model 조회 → 응답
    }
}

// View (Vue 3 — 프론트엔드)
// ILIC: 백엔드는 REST API (JSON)
// 화면(View)은 Vue 3 가 담당 (CSR)
// → MVC 의 View 가 SPA 로 분리
class Shipment {}

5.6 자기 점검 답변

MVC 패턴에서 JSP/서블릿의 역할은?

:
1. MVC:

  • Model/View/Controller
  1. JSP:

    • View (화면)
  2. 서블릿/Controller:

    • 제어/로직
  3. 관심사 분리:

    • 5주차 정신

6️⃣ 현대 Spring에서 JSP

6.1 JSP 의 쇠퇴

JSP 쇠퇴:

  현대 Spring:
    - JSP 거의 안 씀
    - Thymeleaf (SSR)
    - SPA (React/Vue)

→ JSP 레거시

6.2 JSP 단점

JSP 단점:

  - Spring Boot 내장 톰캣 비권장
  - 컴파일 필요
  - JAR 패키징 어려움
  - 스크립틀릿 남용 위험

6.3 대안

대안:

  SSR:
    - Thymeleaf (Spring 권장)

  CSR:
    - React, Vue (SPA)
    - REST API + JSON

6.4 여전히 쓰는 곳

여전히 쓰는 곳:

  - 레거시 시스템
  - JSP 기반 기존 프로젝트
  - 외장 WAS + WAR

→ 신규는 거의 X

6.5 ILIC 의 맥락

ILIC 의 선택:

  ILIC = Vue 3 + REST API:
    - View: Vue 3 (CSR)
    - 백엔드: Spring Boot REST API (JSON)
    - JSP 안 씀

  이유:
    - SPA (반응성)
    - 프론트/백 분리
    - i18n (Vue i18n)
    - 모던 UX

  → JSP 는 레거시, ILIC 는 현대 구조

6.6 자기 점검 답변

현대 Spring에서 JSP는 여전히 쓰이나?

:
1. 쇠퇴:

  • 거의 안 씀
  1. 단점:

    • 내장 톰캣 비권장
  2. 대안:

    • Thymeleaf, SPA
  3. 여전히:

    • 레거시만

7️⃣ Thymeleaf

7.1 Thymeleaf

Thymeleaf:

  Spring 권장 템플릿 엔진:
    - 자연 템플릿 (natural)
    - HTML 유효
    - SSR

7.2 자연 템플릿

<!-- Thymeleaf (HTML 유효) -->
<table>
  <tr th:each="shipment : ${shipments}">
    <td th:text="${shipment.blNo}">BL001</td>
  </tr>
</table>
<!-- 브라우저에서 그냥 열어도 HTML (자연) -->

7.3 JSP vs Thymeleaf

JSP vs Thymeleaf:

JSP:
  - 스크립틀릿 (<% %>)
  - 컴파일
  - HTML 깨짐 (브라우저)

Thymeleaf:
  - 속성 (th:)
  - HTML 유효
  - 디자이너 친화

7.4 SSR 선택지

SSR 선택지:

  Thymeleaf:
    - 서버 렌더링
    - SEO 좋음
    - 전통 웹

  vs SPA (CSR):
    - 클라이언트 렌더링
    - Vue/React

7.5 ILIC 의 맥락

<!-- Thymeleaf 예시 (ILIC 는 Vue 사용하지만) -->
<table>
  <tr th:each="shipment : ${shipments}">
    <td th:text="${shipment.blNo}">샘플</td>
    <td th:text="${shipment.status}">상태</td>
  </tr>
</table>

<!-- ILIC 선택: Vue 3 (CSR) -->
<!-- 
<template>
  <tr v-for="shipment in shipments" :key="shipment.id">
    <td>{{ shipment.blNo }}</td>
  </tr>
</template>
-->
<!-- Thymeleaf(SSR) 대신 Vue(CSR) → 다음 Unit SSR vs CSR -->

7.6 자기 점검 답변

Thymeleaf와의 관계는?

:
1. Thymeleaf:

  • Spring 권장 템플릿
  1. 자연 템플릿:

    • HTML 유효
  2. vs JSP:

    • th: 속성, 안 깨짐
  3. SSR:

    • 서버 렌더링

8️⃣ DispatcherServlet

8.1 DispatcherServlet

DispatcherServlet:

  Spring MVC 의 핵심 서블릿:
    - 모든 요청 받음 (Front Controller)
    - Controller 에 분배

→ 서블릿 추상화

8.2 Front Controller

Front Controller 패턴:

  단일 진입점:
    - 모든 요청 한 곳
    - DispatcherServlet
    - 적절한 Controller 라우팅

8.3 흐름

DispatcherServlet 흐름:

  요청
    → DispatcherServlet
    → HandlerMapping (Controller 찾기)
    → Controller 실행
    → ViewResolver (View 찾기)
    → 응답

8.4 서블릿 추상화

서블릿 추상화:

  개발자:
    - 서블릿 직접 X
    - @Controller, @GetMapping

  Spring:
    - DispatcherServlet 이 서블릿
    - 추상화 제공

→ 서블릿 몰라도 됨

8.5 ILIC 의 맥락

// DispatcherServlet 이 뒤에서 (ILIC)
@RestController
public class ShipmentController {
    @GetMapping("/api/shipments/{id}")
    public Shipment get(@PathVariable Long id) {
        return null;
    }
}

// 흐름:
// 1. GET /api/shipments/1
// 2. DispatcherServlet 받음 (Front Controller)
// 3. HandlerMapping → ShipmentController.get 찾음
// 4. get(1L) 실행
// 5. 반환 객체 → JSON 변환 (HttpMessageConverter)
// 6. 응답

// 개발자는 서블릿 직접 안 다룸
// DispatcherServlet (서블릿) 이 추상화
class Shipment {}

8.6 자기 점검 답변

DispatcherServlet은?

:
1. DispatcherServlet:

  • Spring MVC 핵심 서블릿
  1. Front Controller:

    • 단일 진입점
  2. 흐름:

    • 받음 → 라우팅 → 응답
  3. 추상화:

    • 서블릿 몰라도 됨

9️⃣ 면접 + 자기 점검

9.1 면접 단골 질문 매핑

Q핵심 답변
서블릿?자바 HTTP 처리 클래스
JSP?HTML + 자바 템플릿
JSP 변환?컴파일 시 서블릿
역할 진화?서블릿→JSP→MVC
MVC?Model/View/Controller
현대 JSP?거의 안 씀
Thymeleaf?Spring 권장, HTML 유효
DispatcherServlet?Front Controller
서블릿 생명주기?init/service/destroy
대안?Thymeleaf, SPA

9.2 자기 점검 체크리스트

서블릿

  • 정의

JSP

  • 정의

변환

  • 서블릿

진화

  • MVC

MVC

  • 역할

현대 JSP

  • 쇠퇴

Thymeleaf

  • 권장

DispatcherServlet

  • Front Controller

9.3 추가 심화 질문

Q1: 서블릿 생명주기?

답:

  • init() (1회)
  • service() (요청마다)
  • destroy() (종료)
  • WAS 가 관리

Q2: 서블릿 싱글톤?

답:

  • 서블릿 1개 인스턴스
  • 멀티스레드 공유
  • stateless 필요 (5주차 연결)
  • 인스턴스 변수 주의

Q3: JSP EL?

답:

  • Expression Language
  • ${ } 표현
  • 스크립틀릿 대체
  • 가독성

Q4: HttpMessageConverter?

답:

  • 객체 ↔ JSON/XML
  • @ResponseBody
  • Jackson (JSON)
  • REST API

Q5: 필터 vs 인터셉터?

답:

  • 필터: 서블릿 전후 (WAS)
  • 인터셉터: Controller 전후 (Spring)
  • 필터 먼저
  • 용도 다름

🎯 핵심 요약 — 3줄 정리

1. 서블릿과 JSP

  • 서블릿: 자바 코드로 HTTP 처리 (WAS 위)
  • JSP: HTML + 자바, 컴파일 시 서블릿으로 변환

2. 역할 진화

  • 서블릿만 (HTML 출력) → JSP만 (모든 로직) → MVC (JSP=View, 서블릿=로직)
  • 관심사 분리 (5주차 정신)

3. 현대

  • JSP 거의 안 씀 (Thymeleaf SSR 또는 SPA CSR)
  • ILIC = Vue 3 + REST API, DispatcherServlet 이 서블릿 추상화

📚 다음으로...

Unit 2.3 — SSR vs CSR

이번 Unit에서 서블릿/JSP 를 봤다면, 다음은 SSR vs CSR.

  • 서버 렌더링 vs 클라이언트 렌더링
  • SEO/초기 로딩/서버 부하
  • JSP/Thymeleaf vs React/Vue SPA

Phase 2 진행 상황

🌐 Phase 2 — 웹 인프라 기초
  ✅ Unit 2.1 웹서버 vs WAS
  ✅ Unit 2.2 서블릿과 JSP ← 여기
  ⏭ Unit 2.3 SSR vs CSR
  ⏭ Unit 2.4 JAR vs WAR

6주차 누적 진행

🧪 Part A — 학습 도구와 환경
  ✅ Phase 1 — JUnit 테스트 (5 Unit)
  🌐 Phase 2 — 웹 인프라 기초 (2/4 진행)

총: 7/28 Unit

F-LAB JAVA · 6주차 · Phase 2 · Unit 2.2 · 끝

profile
Software Developer

0개의 댓글