F-LAB JAVA · 6주차 · Phase 2 · 웹 인프라 기초
이 Unit을 끝내면 다음을 답할 수 있어야 한다.
서블릿은 자바 코드로 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.
1. 서블릿이란
2. JSP란
3. JSP → 서블릿 변환
4. 역할 분담의 진화
5. MVC 패턴
6. 현대 Spring에서 JSP
7. Thymeleaf
8. DispatcherServlet
9. 면접 + 자기 점검
서블릿 (Servlet):
자바 코드로 HTTP 요청 처리:
- HttpServletRequest 받음
- HttpServletResponse 응답
- WAS 위에서 실행
// 서블릿 기본 구조
@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\"}");
}
}
HTTP 메서드 처리:
doGet(): GET
doPost(): POST
doPut(): PUT
doDelete(): DELETE
→ 메서드별 오버라이드
WAS 위에서 실행:
서블릿:
- WAS(Tomcat) 가 관리
- 요청 → 서블릿 매핑
- 생명주기 관리
// 서블릿 (저수준, 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 {}
서블릿(Servlet)이란?
답:
1. 서블릿:
구조:
메서드:
실행:
JSP (Java Server Pages):
HTML 안에 자바 코드:
- HTML 템플릿
- <% 자바 %> 삽입
- 동적 HTML 생성
<%-- JSP 예시 --%>
<html>
<body>
<h1>배송 목록</h1>
<% for (Shipment s : shipments) { %>
<p><%= s.getBlNo() %></p>
<% } %>
</body>
</html>
JSP 요소:
<% 코드 %>: 스크립틀릿
<%= 값 %>: 표현식 (출력)
<%@ %>: 지시자
${ }: EL (표현 언어)
JSP vs 서블릿:
서블릿:
- 자바에 HTML (out.println)
- HTML 안 보임
JSP:
- HTML 에 자바
- HTML 잘 보임 (View 적합)
<%-- 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 안 씀) --%>
JSP(Java Server Pages)란?
답:
1. JSP:
구조:
요소:
vs 서블릿:
JSP → 서블릿 변환:
JSP 파일:
- 컴파일 시 서블릿으로 변환
- .java → .class
→ 본질은 서블릿
변환 과정:
1. JSP 작성 (.jsp)
2. 첫 요청 시 변환 (.java)
3. 컴파일 (.class)
4. 서블릿으로 실행
5. 이후 재사용 (컴파일된)
변환의 의미:
JSP 도 결국 서블릿:
- HTML 출력하는 서블릿
- 편하게 작성 (HTML)
- 실행은 서블릿
→ 추상화
첫 요청 지연:
첫 JSP 요청:
- 변환 + 컴파일
- 약간 느림
이후:
- 컴파일된 것 재사용
- 빠름
JSP → 서블릿 변환 (개념):
shipments.jsp
↓ (첫 요청 시)
shipments_jsp.java (자동 생성)
↓ 컴파일
shipments_jsp.class (서블릿)
↓ 실행
HTML 응답
의미:
- JSP 는 작성 편의
- 실행은 서블릿
- "HTML 에 자바" 가 "자바로 HTML 출력" 으로
ILIC: Vue 빌드 → 정적 파일 (JSP 변환과 무관, CSR)
JSP가 서블릿으로 변환된다는 의미는?
답:
1. 변환:
과정:
의미:
첫 요청:
역할 분담 진화:
1. 서블릿만 (HTML 다 출력)
- 가독성 최악
2. JSP만 (모든 로직)
- 유지보수 지옥
3. MVC (JSP=View, 서블릿=로직)
- 분리
// 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 이 자바 문자열 (가독성 최악)
}
<%-- 2단계: JSP에 모든 로직 --%>
<%
// 비즈니스 로직까지 JSP 안에
Connection conn = DriverManager.getConnection(...);
// DB 조회, 계산 등 (유지보수 지옥)
%>
<html>...</html>
3단계 — MVC:
Controller (서블릿):
- 요청 처리
- 비즈니스 로직 호출
- 데이터 준비
View (JSP):
- 화면만
- 데이터 표시
// 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 {}
역할 분담의 진화는?
답:
1. 진화:
서블릿만:
JSP만:
MVC:
MVC 패턴:
Model: 데이터
View: 화면
Controller: 제어
→ 관심사 분리 (5주차)
각 역할:
Model:
- 데이터/비즈니스
- 도메인 객체
View:
- 화면 (JSP/Thymeleaf)
- 표시만
Controller:
- 요청 처리
- Model/View 연결
MVC 흐름:
요청 → Controller
→ Model (데이터)
→ View (화면)
→ 응답
관심사 분리 (5주차 연결):
MVC:
- 데이터/화면/제어 분리
- 각자 책임 (SRP)
→ 5주차 관심사 분리 정신
// 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 {}
MVC 패턴에서 JSP/서블릿의 역할은?
답:
1. MVC:
JSP:
서블릿/Controller:
관심사 분리:
JSP 쇠퇴:
현대 Spring:
- JSP 거의 안 씀
- Thymeleaf (SSR)
- SPA (React/Vue)
→ JSP 레거시
JSP 단점:
- Spring Boot 내장 톰캣 비권장
- 컴파일 필요
- JAR 패키징 어려움
- 스크립틀릿 남용 위험
대안:
SSR:
- Thymeleaf (Spring 권장)
CSR:
- React, Vue (SPA)
- REST API + JSON
여전히 쓰는 곳:
- 레거시 시스템
- JSP 기반 기존 프로젝트
- 외장 WAS + WAR
→ 신규는 거의 X
ILIC 의 선택:
ILIC = Vue 3 + REST API:
- View: Vue 3 (CSR)
- 백엔드: Spring Boot REST API (JSON)
- JSP 안 씀
이유:
- SPA (반응성)
- 프론트/백 분리
- i18n (Vue i18n)
- 모던 UX
→ JSP 는 레거시, ILIC 는 현대 구조
현대 Spring에서 JSP는 여전히 쓰이나?
답:
1. 쇠퇴:
단점:
대안:
여전히:
Thymeleaf:
Spring 권장 템플릿 엔진:
- 자연 템플릿 (natural)
- HTML 유효
- SSR
<!-- Thymeleaf (HTML 유효) -->
<table>
<tr th:each="shipment : ${shipments}">
<td th:text="${shipment.blNo}">BL001</td>
</tr>
</table>
<!-- 브라우저에서 그냥 열어도 HTML (자연) -->
JSP vs Thymeleaf:
JSP:
- 스크립틀릿 (<% %>)
- 컴파일
- HTML 깨짐 (브라우저)
Thymeleaf:
- 속성 (th:)
- HTML 유효
- 디자이너 친화
SSR 선택지:
Thymeleaf:
- 서버 렌더링
- SEO 좋음
- 전통 웹
vs SPA (CSR):
- 클라이언트 렌더링
- Vue/React
<!-- 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 -->
Thymeleaf와의 관계는?
답:
1. Thymeleaf:
자연 템플릿:
vs JSP:
SSR:
DispatcherServlet:
Spring MVC 의 핵심 서블릿:
- 모든 요청 받음 (Front Controller)
- Controller 에 분배
→ 서블릿 추상화
Front Controller 패턴:
단일 진입점:
- 모든 요청 한 곳
- DispatcherServlet
- 적절한 Controller 라우팅
DispatcherServlet 흐름:
요청
→ DispatcherServlet
→ HandlerMapping (Controller 찾기)
→ Controller 실행
→ ViewResolver (View 찾기)
→ 응답
서블릿 추상화:
개발자:
- 서블릿 직접 X
- @Controller, @GetMapping
Spring:
- DispatcherServlet 이 서블릿
- 추상화 제공
→ 서블릿 몰라도 됨
// 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 {}
DispatcherServlet은?
답:
1. DispatcherServlet:
Front Controller:
흐름:
추상화:
| Q | 핵심 답변 |
|---|---|
| 서블릿? | 자바 HTTP 처리 클래스 |
| JSP? | HTML + 자바 템플릿 |
| JSP 변환? | 컴파일 시 서블릿 |
| 역할 진화? | 서블릿→JSP→MVC |
| MVC? | Model/View/Controller |
| 현대 JSP? | 거의 안 씀 |
| Thymeleaf? | Spring 권장, HTML 유효 |
| DispatcherServlet? | Front Controller |
| 서블릿 생명주기? | init/service/destroy |
| 대안? | Thymeleaf, SPA |
답:
답:
답:
답:
답:
1. 서블릿과 JSP
2. 역할 진화
3. 현대
이번 Unit에서 서블릿/JSP 를 봤다면, 다음은 SSR vs CSR.
🌐 Phase 2 — 웹 인프라 기초
✅ Unit 2.1 웹서버 vs WAS
✅ Unit 2.2 서블릿과 JSP ← 여기
⏭ Unit 2.3 SSR vs CSR
⏭ Unit 2.4 JAR vs WAR
🧪 Part A — 학습 도구와 환경
✅ Phase 1 — JUnit 테스트 (5 Unit)
🌐 Phase 2 — 웹 인프라 기초 (2/4 진행)
총: 7/28 Unit
F-LAB JAVA · 6주차 · Phase 2 · Unit 2.2 · 끝