
Servlet은 클라이언트의 요청(Request)을 처리하고 응답(Response)으로 전송하기 위해 Java를 사용해 웹 페이지를 동적으로 생성하는 서버 측 프로그램 혹은 그 API 규격이다.
Servlet 덕분에 개발자는 비즈니스 로직에 집중할 수 있게 됐다.
문제
서블릿이 요청을 처리하는 과정에서 각 서블릿 핸들러가 공통 로직을 반복하게 된다. 요청 개수에 따라 servlet 개수가 계속 늘어나는 구조다.
해결: "전문 reception desk를 만들자"

공통 로직을 처리하는 단일 servlet인 DispatcherServlet을 만들어 문제를 해결한다. 다만 이렇게 하면 DispatcherServlet의 일이 너무 많아진다는 새로운 문제가 생긴다.
→ 그래서 Spring MVC 구조를 취한다.
Spring MVC에서의 역할 매핑:
| MVC | Spring MVC 구성 요소 |
|---|---|
| Model | 핸들러들 |
| View | ViewResolver |
| Controller | DispatcherServlet |
HandlerMapping은 요청을 전달할 controller를 DispatcherServlet에게 알려주는 역할을 한다.
MVC는 SW를 만들 때 Design(화면), 데이터(비즈니스 로직), 통신 제어(Controller) 3개의 영역으로 나눠서 개발하는 디자인 아키텍처로, 코드의 책임을 분리하는 '패턴'이다.
각 구성 요소의 역할
| 구성 요소 | 역할 |
|---|---|
| Model | 데이터/비즈니스 로직 |
| View | 사용자 화면(요즘은 거의 JSON). 응답을 전달하는 객체. client 요청마다 결과물 형태가 다르기 때문에 ViewResolver를 활용 |
| Controller | 요청 처리, 모델과 뷰 연결. 사용자 요청을 URL 단위로 받음 |
웹 요청을 처리하는 과정을 역할별로 분리해서 처리하기 위해 사용한다.
처리 흐름 코드 예시
1. Controller로 요청이 들어온다
@GetMapping("/users/{id}")
public UserResponse getUser(@PathVariable Long id) {
return userService.findUser(id); // 실제 처리는 userService로 위임
}
@GetMapping → URL + HTTP 메서드 기준으로 요청을 매핑@PathVariable → URL 경로의 값을 파라미터로 받음2. Model에서 비즈니스 처리를 한다
@Service
public class UserService {
public UserResponse findUser(Long id) {
return new UserResponse(id, "홍길동");
}
}
Model은 어떤 요청인지 알 필요 없고, 로직 설계에만 집중한다.
3. Controller가 결과를 View로 반환한다
// 템플릿 기반 MVC
@GetMapping("/users/{id}")
public String getUser(@PathVariable Long id, Model model) {
model.addAttribute("user", userService.findUser(id));
return "user-detail";
}
// REST API
@GetMapping("/users/{id}")
public UserResponse getUser(@PathVariable Long id) {
return userService.findUser(id);
}
"user-detail"이 View 이름이고, Model에 담긴 데이터가 템플릿 엔진을 통해 HTML로 렌더링된다. REST API에서는 JSON 직렬화 과정 자체가 View 역할을 한다.
Spring Boot에서 Service = Model인가?
No. Model = Service + 도메인 객체 + Repository를 통한 데이터 접근. 다 포함하는 구조적 개념이다.
Spring MVC 구성 요소 상세

DispatcherServlet: Spring MVC의 진입점이자 전체 흐름을 조정하는 중심 컴포넌트. 요청을 직접 처리하지 않고 어떤 controller로 보낼지 결정하는 중앙 router다. 비즈니스 로직과는 철저히 분리되어 있다.
HandlerMapping: 요청 URL과 HTTP 메서드를 보고 어느 Controller 메서드가 처리해야 하는지 찾아주는 주소록 역할. @GetMapping, @RequestMapping 같은 매핑 정보가 이 단계에서 해석된다. mapping이 없으면 예외처리 흐름으로 넘어간다.
Controller: 요청 파라미터를 해석하고, 비즈니스 처리는 Service에 위임하고, 결과를 반환하는 중간 조정자. 비즈니스 로직 구현 X. 비대해지면 안 된다.
ViewResolver: Controller가 문자열로 반환한 View 이름("user-detail" 같은 것)을 실제 템플릿 파일로 변환해주는 역할.
View: Model 데이터를 받아 최종 화면(HTML)이나 응답 형태로 변환. 실제 응답 본문이 여기서 생성된다.
Spring MVC 내부 흐름

request
→ DispatcherServlet
→ HandlerMapping
→ HandlerAdapter
→ ArgumentResolver
→ Controller
→ Model
→ MessageConverter / View
일반 HTTP는 단순 단방향 정보 전달 목적일 때 주로 사용한다. 하지만 현대 웹사이트는 인증서, 결제, 송금 같은 보안 요소가 중요해졌고, 이를 해결하기 위해 HTTP + Secure = HTTPS가 등장했다.
키(Key)의 종류
| 종류 | 역할 | 특징 |
|---|---|---|
| 공개키 | 비대칭 암호화에서 암호화에 사용 | 누구에게나 공개 가능. 개인키 없이 복호화 불가 |
| 비공개키(개인키) | 비대칭 암호화에서 복호화에 사용 | 오직 소유자만 보관. 서버 밖으로 절대 나가지 않음 |
| 대칭키 | 암호화·복호화에 같은 키 사용 | XOR 연산. 빠르지만 키 전달이 어려움 |
| 비대칭키 | 공개키와 개인키 두 개를 사용 | 키 교환 안전. 대칭키보다 처리 느림 |
대칭키
비대칭키
HTTPS의 통신 방식: 비대칭키로 대칭키를 안전하게 전달하고, 실제 통신은 대칭키로 한다.
통신하는 상대방이 누군지 신원을 확인하는 과정이다.

목적은 처음 만나는 서버와 도청 없이 대칭키를 공유하는 것이다. 인터넷은 기본적으로 도청 가능한 공간이므로 이 복잡한 과정을 거친다. 4~5 과정에서 TLS Handshake가 발생한다.
1. CA 공개키는 이미 브라우저에 내장되어 있다
CA가 개인키로 암호화한 것을 클라이언트는 브라우저 내의 공개키로 복호화해서 검증할 수 있다. 인증서 안에는 서버 공개키 + CA 전자서명이 들어있다.
2. 클라이언트가 인증서를 검증한다
브라우저의 CA 공개키로 복호화해서 내용이 맞으면 서버 공개키까지 신뢰할 수 있다. 공격자가 서버 공개키를 끼워 넣으려 해도, CA 서명은 위조 불가하므로 검증 단계에서 걸린다.
CA 위조가 불가한 이유
애초에 개인키를 모르면 서명을 만들 수 없다. 위조하려면 개인키가 필요한데, 공개키에서 개인키를 역산하는 것이 수학적으로 현실 불가능하다.