Spring

[Spring] MVC 15편 - HTTP 메시지 컨버터와 요청 처리 구조

dev-nadan 2025. 8. 14. 15:43

 

이번 편에서는 스프링 MVC가 요청과 응답을 변환하는 핵심 엔진HttpMessageConverter와,

컨트롤러 실행까지 이어지는 핸들러 어댑터 구조를 살펴본다.

이 과정을 이해하면, 커스텀 메시지 변환기나 특수한 요청 처리 로직을 구현할 때 막히는 일이 거의 없다.


1. HTTP 메시지 컨버터(HttpMessageConverter)란?

역할

  • HTTP 요청 바디 → 자바 객체 변환 (@RequestBody)
  • 자바 객체 → HTTP 응답 바디 변환 (@ResponseBody)

동작 시점

  • 요청: 컨트롤러 호출 전, 바디 내용을 읽어 객체로 변환
  • 응답: 컨트롤러 반환 후, 객체를 바디에 맞게 변환

2. 스프링 부트 기본 등록 컨버터

컨버터 클래스 지원 타입 설명
StringHttpMessageConverter String 텍스트 변환
MappingJackson2HttpMessageConverter 객체 ↔ JSON Jackson 기반 JSON 변환
MappingJackson2XmlHttpMessageConverter 객체 ↔ XML XML 변환 (선택)
ByteArrayHttpMessageConverter byte[] 바이너리 데이터 처리

3. 동작 과정 예시

요청 시 (@RequestBody)

  1. 클라이언트 → Content-Type: application/json
  2. DispatcherServlet → HandlerAdapter
  3. HttpMessageConverter 목록 확인
  4. canRead(HelloData.class, application/json) 가능한 컨버터 선택
  5. JSON → HelloData 객체 변환
  6. 컨트롤러 메서드 실행

응답 시 (@ResponseBody)

  1. 컨트롤러 → HelloData 객체 반환
  2. HandlerAdapter → HttpMessageConverter 목록 확인
  3. canWrite(HelloData.class, application/json) 가능한 컨버터 선택
  4. HelloData → JSON 변환
  5. HTTP 응답 전송

4. 요청 매핑 핸들러 어댑터 구조

처리 흐름

[DispatcherServlet]
   ↓
HandlerMapping → 어떤 컨트롤러 메서드 실행할지 찾음
   ↓
HandlerAdapter → 해당 컨트롤러 실행할 수 있는 어댑터 호출
   ↓
ArgumentResolver → 컨트롤러 파라미터 생성 (@RequestParam, @ModelAttribute 등)
   ↓
HttpMessageConverter → @RequestBody/@ResponseBody 변환
   ↓
컨트롤러 실행
   ↓
ReturnValueHandler → 반환값 처리

HandlerAdapter란?

  • 컨트롤러의 형태에 맞춰 실행해주는 어댑터
  • @Controller 기반, HttpRequestHandler, Servlet 등 다양한 핸들러 지원

5. 커스터마이징 포인트

  • HttpMessageConverter 확장
    • 예: CSV 변환기 추가
    • WebMvcConfigurerextendMessageConverters() 오버라이드
  • ArgumentResolver 추가
    • 예: 인증된 사용자 객체 주입
    • HandlerMethodArgumentResolver 구현

회고

이번 장에서는 평소 잘 쓰던 @RequestBody / @ResponseBody 뒤에서 실제로 어떤 변환기가 동작하는지, 그리고 그 변환기를 누가 호출하는지까지 구조를 살펴봤다.

예전에는 메시지 변환이 “자동으로 된다” 정도로만 알고 있었는데, 이제는 DispatcherServlet → HandlerMapping → HandlerAdapter → ArgumentResolver → HttpMessageConverter로 이어지는 전체 흐름이 머릿속에 그려진다.

이 덕분에 앞으로 JSON 외의 특수한 포맷을 처리하거나, 요청 파라미터를 커스텀하게 바인딩할 때 자신 있게 구현할 수 있을 것 같다.