[Spring] HTTP 요청/응답 처리 흐름 분석(Tomcat, DispatcherServlet)

이지연·2026년 1월 27일

클라이언트에서 요청 → Spring Boot → 응답까지 전체 과정을 단계별로 자연스럽게 정리한다.


1. Spring Boot의 내장 Tomcat 역할

Spring Boot는 Tomcat을 내장하여 별도 WAS 설치 없이 웹서버 + 애플리케이션 서버 역할을 동시에 수행한다.

클라이언트 요청 (GET /author/1)
    ↓
Spring Boot 내장 Tomcat 수신
    ↓  
스레드 할당 + HttpServletRequest/Response 객체 생성
    ↓
DispatcherServlet으로 요청 전달

Web Server vs WAS 처리 구분

구분처리 콘텐츠예시Spring Boot
Web Server정적 (이미지/CSS/JS)Nginx, S3Tomcat으로 처리
WAS동적 (JSON API)Tomcat내장 Tomcat으로 처리

Spring Boot: 모든 요청을 Tomcat에서 처리 (정적 + 동적)


2. 요청 처리 1단계: Tomcat (서블릿 컨테이너)

Tomcat은 HTTP 요청을 Java 객체로 변환하는 역할을 한다.

1. 스레드 할당
   - 동시 요청 100개 → 100개 스레드 병렬 처리
   
2. 서블릿 객체 생성 (매 요청마다)
   - HttpServletRequest: 요청 데이터 (헤더, 바디, 파라미터)
   - HttpServletResponse: 응답 데이터 (JSON, 상태코드)

왜 매번 새로 생성하나?

@GetMapping("/author/{id}")
public ResponseEntity<AuthorDto> getAuthor(@PathVariable Long id, 
                                          @RequestBody AuthorRequest request) {
    // @PathVariable, @RequestBody ← HttpServletRequest에서 추출
}
  • 스레드 안전성 (동시 요청 충돌 방지)
  • 메모리 관리 (요청 끝나면 즉시 GC)
  • Spring 편의성 (@PathVariable 자동 바인딩)

결과: 개발자는 HttpServletRequest 직접 다룰 필요 없이@GetMapping만 쓰면 자동으로 요청 데이터 받음


3. 요청 처리 2단계: DispatcherServlet (중앙 컨트롤러)

Tomcat이 생성한 요청을 Spring MVC의 DispatcherServlet이 받아서 적절한 컨트롤러로 라우팅한다.

DispatcherServlet 특징
✅ 싱글톤 (서버당 1개만 생성 → 재사용)
✅ 모든 HTTP 요청 중앙 처리
✅ URL + 메서드 분석 → 컨트롤러 매칭

실제 매칭 과정

요청: GET /author/1
↓
@GetMapping("/author/{id}") ← 매칭!
↓
AuthorController.getAuthor(1) 실행

4. 전체 요청 워크플로우

1. 클라이언트 → GET /author/1
2. Tomcat → 스레드 할당 + HttpServletRequest 생성  
3. DispatcherServlet → @GetMapping("/author/{id}") 매칭
4. AuthorController.getAuthor(id=1) 실행
5. Service → Repository → DB 조회
6. JSON 직렬화 → HttpServletResponse
7. Tomcat → HTTP 응답 전송

이 때 chain.doFilter()를 호출해야 다음 필터 → DispatcherServlet으로 진행

즉, 필터 체인 완료 후 DispatcherServlet 으로 전달됨


5. 현대 웹 아키텍처에서의 위치

SPA(React) + API Server 패턴

브라우저 (React)
    ↓ fetch('/api/author/1')
[CORS 검증]
Spring Boot (Tomcat + Spring MVC)
    ↓ DB 연동
JSON 응답 → React 렌더링

정적 컨텐츠 분리 (권장)

S3/Nginx
├── 정적: HTML/CSS/JS (빌드 후)
    ↓
Spring Boot API
├── 동적: /api/author/** (JSON)

Spring Boot 단일 JAR로: 정적 + 동적 모두 처리 가능 (개발 편의성 ↑)


6. 순수 Spring vs Spring Boot 차이점

순수 Spring
├── 외부 Tomcat 설치 필요
├── WAR 파일 배포
└── 복잡한 web.xml 설정

Spring Boot ✅
├── Tomcat 내장 (java -jar 한방)
├── 자동 설정
├── 개발자 생산성 극대화

7. 실제 코드로 확인

@RestController
public class AuthorController {
    
    @GetMapping("/author/{id}")
    public ResponseEntity<AuthorResponse> getAuthor(@PathVariable Long id) {
        // 1. DispatcherServlet이 이 메서드로 요청 전달
        // 2. @PathVariable ← HttpServletRequest에서 id 추출
        Author author = authorService.findById(id);
        return ResponseEntity.ok(AuthorResponse.from(author));
    }
}

요청 시 내부 흐름

GET /author/1
→ Tomcat: HttpServletRequest 생성 (path="/author/1")
→ DispatcherServlet: @GetMapping 매칭
→ 컨트롤러: id=1 바인딩 → JSON 응답

핵심 정리

요청 흐름
클라이언트 → [Tomcat 내장: 스레드+서블릿] → [DispatcherServlet: 라우팅] → 컨트롤러 → JSON

주요 역할
- Tomcat: HTTP → Java 객체 변환 (내장)
- DispatcherServlet: 요청 → 컨트롤러 연결 (싱글톤)

현대 구조
S3(정적파일) + Spring Boot(API) + React(동적렌더링)

Spring Boot = "Tomcat 내장 + DispatcherServlet 자동 설정"의 편리함. 이제 요청 흐름 완벽 파악 완료.

profile
Eazy하게

0개의 댓글