Lined Notebook

[스프링 MVC - 백엔드 웹 개발 기술] 16. HTTP 메시지 컨버터(Message Converter)

by ymkim

01. HTTP 메시지 컨버터

  • 템플릿으로 HTML(mustache, thymeleaf)을 생성해서 응답하는 것이 아니라 HTTP API처럼 JSON 데이터HTTP 메시지 바디에서 읽거나 쓰는 경우 HTTP 메시지 컨버터 사용한다
  • HTTP 메시지 컨버터 설명 전 이전에 설명한 부분을 다시 복기 해보자

01-1. @ResponseBody 원리

  • @ResponseBody 어노테이션 사용
    • HTTP BODY에 문자 내용 직접 반환
    • viewResolver 대신 HttpMessageConvert 동작
    • 기본 문자 반환 처리시 : StringHttpMessageConverter
    • 기본 객체 반환 처리시 : MappingJackson2HttpMessageConverter
    • byte 처리 등등 기타 여러 HttpMessageConverter가 기본 등록 되어 있음
  • 응답의 경우 클라이언트의 HTTP Accept 헤더컨트롤러 반환 타입 정보 조합에 의해 HttpMessageConverter가 결정이 됨

01-2. 스프링 MVC는 다음 경우 HTTP 메시지 컨버터를 적용 한다

  • HTTP 요청
    • @RequestBody 사용하는 경우 메시지 컨버터를 통해 변환
    • HttpEntity(RequestEntity) 사용하는 경우 변환
  • HTTP 응답
    • @ResponseBody 사용하는 경우 메시지 컨버터를 통해 변환
    • HttpEntity(ResponseEntity) 사용하는 경우 변환

01-3. HTTP 메시지 컨버터 인터페이스

org.springframework.http.converter.HttpMessageConverter

package org.springframework.http.converter;

public interface HttpMessageConverter<T> {
		
		boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
		boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);

		T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
			throws IOException, HttpMessageNotReadableException;

		void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
			throws IOException, HttpMessageNotWritableException;
}

HTTP 메시지 컨버터는 사용자의 요청, 응답 시 데이터를 가공하여 사용자, 혹은 서버에 제공하는 역할을 한다. @RequestBody, @ResponseBody, HttpEntity(RequestEntity, ResponseEntity)를 사용하는 경우 값을 컨버팅 해주는 역할을 주로 담당한다.

  • HTTP 메시지 컨버터는 인터페이스 로 구현이 되어있다
    • 왜? 인터페이스 인가? (아래와 같이 요청, 응답 시에 변환해야 하는 데이터 타입이 다양하기 때문이다)
      • 문자열 처리 반환 시 : StringHttpMessageConverter
      • 객체 처리 반환 시 : MappingJackson2HttpMessageConverter
  • canRead(), canWrite()
    • 메시지 컨버터가 해당 클래스, 미디어타입 지원하는지 체크
  • read(), write()
    • 메시지 컨버터를 통해 메시지를 읽고 쓰는 기능

01-4. 스프링부트 기본 메시지 컨버터

아래 컨버터는 양방향 제공

- 0번 = ByteArrayHttpMessageConverter (Byte로 변환)
- 1번 = StringHttpMessageConverter (String로 변환)
- 2번 = MappingJackson2HttpMessageConverter (Json → Objec로 변환)
  • 스프링 부트는 대상 클래스 타입과, 미디어 타입 둘을 체크하여 사용여부 결정
  • 만약 만족하지 않으면 0번 - 2번… 순으로 넘어간다

01-5. 몇가지 주요한 메시지 컨버터를 알아보자

  • ByteArrayHttpMessageConverter
    • byte
    • 클래스 타입: byte[], 미디어타입: */*
    • 요청 예) @RequestBody byte[] data
    • 응답 예) @ResponseBody return byte[], 쓰기 미디어 타입 application/octet-stream
  • StringHttpMessageConverter
    • String 문자로 데이터 처리
    • 클래스 타입: String, 미디어 타입: */*
    • 요청 예) @RequestBody String data
    • 응답 예) @ResponseBody return “ok”, 쓰기 미디어 타입 text/plain
  • MappingJackson2HttpMessageConverter
    • application/json
    • 클래스타입: 객체 또는 HashMap, 미디어 타입: application/json 관련
    • 요청 예) @RequestBody HelloData data
    • 응답 예) @ResponseBody return helloData, 쓰기 미디어타입 application/json 관련

01-6. HTTP 요청 데이터 읽기(요청)

  • HTTP 요청 → 컨트롤러 → @RequestBody, HttpEntity가 있는 경우 → 컨버터 동작
  • 메시지 컨버터가 메시지 읽을 수 있는지 확인 → canRead() 호출됨
    • 클래스 타입 지원 하는가?
      • 예) @RequestBody의 대상 클래스 (byte[], String, HelloData)
    • HTTP 요청의 Content-Type 미디어 타입 지원 하는가?
      • 예) text/plan, application/json, */*
  • canRead() True → read() 호출 → 객체 생성 및 반환

01-7. HTTP 응답 데이터 생성(응답)

consume: 들어오는 데이터 제어, produces: 나가는 데이터 제어

  • 컨트롤러 → @RequestBody, HttpEntity가 있는 경우 → 컨버터 동작
  • 메시지 컨버터가 메시지를 쓸 수 있는지 확인 → canWrite() 함수 호출됨
    • 대상 클래스 타입 지원?
      • 예) return 대상 클래스 (byte[], String, HelloData)
    • HTTP 요청의 Accept 미디어 타입 지원? (더 정확히는 @RequestMapping의 produces)
      • 예) text/plan, application/json, */*
  • canWrite() True → write() 호출 → HTTP 응답 바디 데이터 생성

블로그의 정보

기록하고, 복기하고

ymkim

활동하기